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 "GrEffect.h" 12 #include "SkMatrix.h" 13 #include "GrTexture.h" 14 #include "GrTypes.h" 15 16 /** 17 * Coordinates available to GrEffect subclasses for requesting transformations. Transformed 18 * coordinates are made available in the the portion of fragment shader emitted by the effect. 19 */ 20 enum GrCoordSet { 21 /** 22 * The user-space coordinates that map to the fragment being rendered. These coords account for 23 * any change of coordinate system done on the CPU by GrContext before rendering, and also are 24 * correct for draws that take explicit local coords rather than inferring them from the 25 * primitive's positions (e.g. drawVertices). These are usually the coords a GrEffect wants. 26 */ 27 kLocal_GrCoordSet, 28 29 /** 30 * The actual vertex position. Note that GrContext may not draw using the original view matrix 31 * specified by the caller, as it may have transformed vertices into another space. These are 32 * usually not the coordinates a GrEffect wants. 33 */ 34 kPosition_GrCoordSet 35 }; 36 37 /** 38 * A class representing a linear transformation from one of the built-in coordinate sets (local or 39 * position). GrEffects just define these transformations, and the framework does the rest of the 40 * work to make the transformed coordinates available in their fragment shader. 41 */ 42 class GrCoordTransform : public SkNoncopyable { 43 public: 44 GrCoordTransform() { SkDEBUGCODE(fInEffect = false); } 45 46 /** 47 * Create a transformation that maps [0, 1] to a texture's boundaries. 48 */ 49 GrCoordTransform(GrCoordSet sourceCoords, const GrTexture* texture) { 50 SkDEBUGCODE(fInEffect = false); 51 this->reset(sourceCoords, texture); 52 } 53 54 /** 55 * Create a transformation from a matrix. The optional texture parameter is used to infer if the 56 * framework should internally do a y reversal to account for it being upside down by Skia's 57 * coord convention. 58 */ 59 GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) { 60 SkDEBUGCODE(fInEffect = false); 61 this->reset(sourceCoords, m, texture); 62 } 63 64 void reset(GrCoordSet sourceCoords, const GrTexture* texture) { 65 SkASSERT(!fInEffect); 66 SkASSERT(NULL != texture); 67 this->reset(sourceCoords, GrEffect::MakeDivByTextureWHMatrix(texture), texture); 68 } 69 70 void reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) { 71 SkASSERT(!fInEffect); 72 fSourceCoords = sourceCoords; 73 fMatrix = m; 74 fReverseY = NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin(); 75 } 76 77 GrCoordTransform& operator= (const GrCoordTransform& other) { 78 SkASSERT(!fInEffect); 79 fSourceCoords = other.fSourceCoords; 80 fMatrix = other.fMatrix; 81 fReverseY = other.fReverseY; 82 return *this; 83 } 84 85 /** 86 * Access the matrix for editing. Note, this must be done before adding the transform to an 87 * effect, since effects are immutable. 88 */ 89 SkMatrix* accessMatrix() { 90 SkASSERT(!fInEffect); 91 return &fMatrix; 92 } 93 94 bool operator== (const GrCoordTransform& other) const { 95 return fSourceCoords == other.fSourceCoords && 96 fMatrix.cheapEqualTo(other.fMatrix) && 97 fReverseY == other.fReverseY; 98 } 99 100 GrCoordSet sourceCoords() const { return fSourceCoords; } 101 const SkMatrix& getMatrix() const { return fMatrix; } 102 bool reverseY() const { return fReverseY; } 103 104 private: 105 GrCoordSet fSourceCoords; 106 SkMatrix fMatrix; 107 bool fReverseY; 108 109 typedef SkNoncopyable INHERITED; 110 111 #ifdef SK_DEBUG 112 public: 113 void setInEffect() const { fInEffect = true; } 114 private: 115 mutable bool fInEffect; 116 #endif 117 }; 118 119 #endif 120