1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrCoordTransform_DEFINED
9#define GrCoordTransform_DEFINED
10
11#include "include/core/SkMatrix.h"
12#include "src/core/SkMatrixPriv.h"
13#include "src/gpu/GrSurfaceProxyPriv.h"
14#include "src/gpu/GrTextureProxy.h"
15
16class GrTexture;
17
18/**
19 * A class representing a linear transformation of local coordinates. GrFragnentProcessors
20 * these transformations, and the GrGeometryProcessor implements the transformation.
21 */
22class GrCoordTransform {
23public:
24 GrCoordTransform() = default;
25
26 GrCoordTransform(const GrCoordTransform&) = default;
27
28 /**
29 * Create a transformation that maps [0, proxy->width()] x [0, proxy->height()] to a proxy's
30 * extent.
31 */
32 GrCoordTransform(GrSurfaceProxy* proxy, GrSurfaceOrigin origin)
33 : fProxy(proxy), fOrigin(origin) {}
34
35 /**
36 * Create a transformation from a matrix. The origin implies whether a y-reversal should be
37 * performed.
38 */
39 GrCoordTransform(const SkMatrix& m, GrSurfaceProxy* proxy, GrSurfaceOrigin origin)
40 : fProxy(proxy), fOrigin(origin), fMatrix(m) {
41 SkASSERT(proxy);
42 }
43
44 /**
45 * Create a transformation that applies the matrix to a coord set.
46 */
47 GrCoordTransform(const SkMatrix& m) : fMatrix(m) {}
48
49 GrCoordTransform& operator=(const GrCoordTransform& that) = default;
50
51 // The textures' effect is to optionally normalize the final matrix, so a blind equality check
52 // could be misleading.
53 bool operator==(const GrCoordTransform& that) const = delete;
54 bool operator!=(const GrCoordTransform& that) const = delete;
55
56 bool hasSameEffectiveMatrix(const GrCoordTransform& that) const {
57 // This is slightly more conservative than computing each transforms effective matrix and
58 // then comparing them.
59 if (!SkMatrixPriv::CheapEqual(fMatrix, that.fMatrix)) {
60 return false;
61 }
62 if (SkToBool(fProxy) != SkToBool(that.fProxy)) {
63 return false;
64 }
65 if (this->normalize() != that.normalize() || this->reverseY() != that.reverseY()) {
66 return false;
67 }
68 if (this->normalize() &&
69 fProxy->backingStoreDimensions() != that.fProxy->backingStoreDimensions()) {
70 return false;
71 }
72 return true;
73 }
74
75 const SkMatrix& matrix() const { return fMatrix; }
76 const GrSurfaceProxy* proxy() const { return fProxy; }
77 bool normalize() const {
78 return fProxy && fProxy->backendFormat().textureType() != GrTextureType::kRectangle;
79 }
80 bool reverseY() const { return fProxy && fOrigin == kBottomLeft_GrSurfaceOrigin; }
81 bool isNoOp() const { return fMatrix.isIdentity() && !this->normalize() && !this->reverseY(); }
82
83 // This should only ever be called at flush time after the backing texture has been
84 // successfully instantiated
85 GrTexture* peekTexture() const { return fProxy->peekTexture(); }
86
87private:
88 const GrSurfaceProxy* fProxy = nullptr;
89 GrSurfaceOrigin fOrigin = kTopLeft_GrSurfaceOrigin;
90 SkMatrix fMatrix = SkMatrix::I();
91};
92
93#endif
94