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 "GrProcessor.h" 12 #include "SkMatrix.h" 13 #include "GrTexture.h" 14 #include "GrTypes.h" 15 #include "GrShaderVar.h" 16 17 class GrTextureProxy; 18 19 /** 20 * A class representing a linear transformation of local coordinates. GrFragnentProcessors 21 * these transformations, and the GrGeometryProcessor implements the transformation. 22 */ 23 class GrCoordTransform : SkNoncopyable { 24 public: 25 GrCoordTransform() 26 : fTexture(nullptr) 27 , fNormalize(false) 28 , fReverseY(false) 29 , fPrecision(kDefault_GrSLPrecision) { 30 SkDEBUGCODE(fInProcessor = false); 31 } 32 33 /** 34 * Create a transformation that maps [0, 1] to a texture's boundaries. The precision is inferred 35 * from the texture size and filter. The texture origin also implies whether a y-reversal should 36 * be performed. 37 */ 38 GrCoordTransform(const GrTexture* texture, GrSamplerParams::FilterMode filter) { 39 SkASSERT(texture); 40 SkDEBUGCODE(fInProcessor = false); 41 this->reset(SkMatrix::I(), texture, filter); 42 } 43 44 GrCoordTransform(GrResourceProvider* resourceProvider, GrTextureProxy* proxy, 45 GrSamplerParams::FilterMode filter) { 46 SkASSERT(proxy); 47 SkDEBUGCODE(fInProcessor = false); 48 this->reset(resourceProvider, SkMatrix::I(), proxy, filter); 49 } 50 51 /** 52 * Create a transformation from a matrix. The precision is inferred from the texture size and 53 * filter. The texture origin also implies whether a y-reversal should be performed. 54 */ 55 GrCoordTransform(const SkMatrix& m, const GrTexture* texture, 56 GrSamplerParams::FilterMode filter) { 57 SkASSERT(texture); 58 SkDEBUGCODE(fInProcessor = false); 59 this->reset(m, texture, filter); 60 } 61 62 GrCoordTransform(GrResourceProvider* resourceProvider, const SkMatrix& m, 63 GrTextureProxy* proxy, GrSamplerParams::FilterMode filter) { 64 SkASSERT(proxy); 65 SkDEBUGCODE(fInProcessor = false); 66 this->reset(resourceProvider, m, proxy, filter); 67 } 68 69 /** 70 * Create a transformation that applies the matrix to a coord set. 71 */ 72 GrCoordTransform(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) { 73 SkDEBUGCODE(fInProcessor = false); 74 this->reset(m, precision); 75 } 76 77 // MDB TODO: rm the GrTexture* flavor of reset 78 void reset(const SkMatrix&, const GrTexture*, GrSamplerParams::FilterMode filter, 79 bool normalize = true); 80 81 void reset(GrResourceProvider*, const SkMatrix&, GrTextureProxy*, 82 GrSamplerParams::FilterMode filter, bool normalize = true); 83 84 void reset(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) { 85 SkASSERT(!fInProcessor); 86 fMatrix = m; 87 fTexture = nullptr; 88 fNormalize = false; 89 fReverseY = false; 90 fPrecision = precision; 91 } 92 93 GrCoordTransform& operator= (const GrCoordTransform& that) { 94 SkASSERT(!fInProcessor); 95 fMatrix = that.fMatrix; 96 fTexture = that.fTexture; 97 fNormalize = that.fNormalize; 98 fReverseY = that.fReverseY; 99 fPrecision = that.fPrecision; 100 return *this; 101 } 102 103 /** 104 * Access the matrix for editing. Note, this must be done before adding the transform to an 105 * effect, since effects are immutable. 106 */ 107 SkMatrix* accessMatrix() { 108 SkASSERT(!fInProcessor); 109 return &fMatrix; 110 } 111 112 bool hasSameEffectAs(const GrCoordTransform& that) const { 113 if (fNormalize != that.fNormalize || 114 fReverseY != that.fReverseY || 115 fPrecision != that.fPrecision || 116 !fMatrix.cheapEqualTo(that.fMatrix)) { 117 return false; 118 } 119 120 if (fNormalize) { 121 SkASSERT(fTexture && that.fTexture); 122 return fTexture->width() == that.fTexture->width() && 123 fTexture->height() == that.fTexture->height(); 124 } 125 126 return true; 127 } 128 129 const SkMatrix& getMatrix() const { return fMatrix; } 130 const GrTexture* texture() const { return fTexture; } 131 bool normalize() const { return fNormalize; } 132 bool reverseY() const { return fReverseY; } 133 GrSLPrecision precision() const { return fPrecision; } 134 135 private: 136 // The textures' effect is to optionally normalize the final matrix, so a blind 137 // equality check could be misleading 138 bool operator==(const GrCoordTransform& that) const; 139 bool operator!=(const GrCoordTransform& that) const; 140 141 SkMatrix fMatrix; 142 const GrTexture* fTexture; 143 bool fNormalize; 144 bool fReverseY; 145 GrSLPrecision fPrecision; 146 typedef SkNoncopyable INHERITED; 147 148 #ifdef SK_DEBUG 149 public: 150 void setInProcessor() const { fInProcessor = true; } 151 private: 152 mutable bool fInProcessor; 153 #endif 154 }; 155 156 #endif 157