1 /* 2 Copyright 2010 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 18 #ifndef GrSamplerState_DEFINED 19 #define GrSamplerState_DEFINED 20 21 #include "GrTypes.h" 22 #include "GrMatrix.h" 23 24 class GrSamplerState { 25 public: 26 enum Filter { 27 /** 28 * Read the closest src texel to the sample position 29 */ 30 kNearest_Filter, 31 /** 32 * Blend between closest 4 src texels to sample position (tent filter) 33 */ 34 kBilinear_Filter, 35 /** 36 * Average of 4 bilinear filterings spaced +/- 1 texel from sample 37 * position in x and y. Intended for averaging 16 texels in a downsample 38 * pass. (rasterizing such that texture samples fall exactly halfway 39 * between texels in x and y spaced 4 texels apart.) 40 */ 41 k4x4Downsample_Filter, 42 }; 43 44 /** 45 * The intepretation of the texture matrix depends on the sample mode. The 46 * texture matrix is applied both when the texture coordinates are explicit 47 * and when vertex positions are used as texture coordinates. In the latter 48 * case the texture matrix is applied to the pre-view-matrix position 49 * values. 50 * 51 * kNormal_SampleMode 52 * The post-matrix texture coordinates are in normalize space with (0,0) at 53 * the top-left and (1,1) at the bottom right. 54 * kRadial_SampleMode 55 * The matrix specifies the radial gradient parameters. 56 * (0,0) in the post-matrix space is center of the radial gradient. 57 * kRadial2_SampleMode 58 * Matrix transforms to space where first circle is centered at the 59 * origin. The second circle will be centered (x, 0) where x may be 60 * 0 and is provided by setRadial2Params. The post-matrix space is 61 * normalized such that 1 is the second radius - first radius. 62 * kSweepSampleMode 63 * The angle from the origin of texture coordinates in post-matrix space 64 * determines the gradient value. 65 */ 66 enum SampleMode { 67 kNormal_SampleMode, //!< sample color directly 68 kRadial_SampleMode, //!< treat as radial gradient 69 kRadial2_SampleMode, //!< treat as 2-point radial gradient 70 kSweep_SampleMode, //!< treat as sweep gradient 71 }; 72 73 /** 74 * Describes how a texture is sampled when coordinates are outside the 75 * texture border 76 */ 77 enum WrapMode { 78 kClamp_WrapMode, 79 kRepeat_WrapMode, 80 kMirror_WrapMode 81 }; 82 83 /** 84 * Default sampler state is set to clamp, use normal sampling mode, be 85 * unfiltered, and use identity matrix. 86 */ 87 GrSamplerState() { 88 this->setClampNoFilter(); 89 } 90 91 explicit GrSamplerState(Filter filter) { 92 fWrapX = kClamp_WrapMode; 93 fWrapY = kClamp_WrapMode; 94 fSampleMode = kNormal_SampleMode; 95 fFilter = filter; 96 fMatrix.setIdentity(); 97 fTextureDomain.setEmpty(); 98 } 99 100 GrSamplerState(WrapMode wx, WrapMode wy, Filter filter) { 101 fWrapX = wx; 102 fWrapY = wy; 103 fSampleMode = kNormal_SampleMode; 104 fFilter = filter; 105 fMatrix.setIdentity(); 106 fTextureDomain.setEmpty(); 107 } 108 109 GrSamplerState(WrapMode wx, WrapMode wy, 110 const GrMatrix& matrix, Filter filter) { 111 fWrapX = wx; 112 fWrapY = wy; 113 fSampleMode = kNormal_SampleMode; 114 fFilter = filter; 115 fMatrix = matrix; 116 fTextureDomain.setEmpty(); 117 } 118 119 GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, 120 const GrMatrix& matrix, Filter filter) { 121 fWrapX = wx; 122 fWrapY = wy; 123 fSampleMode = sample; 124 fMatrix = matrix; 125 fFilter = filter; 126 fTextureDomain.setEmpty(); 127 } 128 129 WrapMode getWrapX() const { return fWrapX; } 130 WrapMode getWrapY() const { return fWrapY; } 131 SampleMode getSampleMode() const { return fSampleMode; } 132 const GrMatrix& getMatrix() const { return fMatrix; } 133 const GrRect& getTextureDomain() const { return fTextureDomain; } 134 bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();} 135 Filter getFilter() const { return fFilter; } 136 137 bool isGradient() const { 138 return kRadial_SampleMode == fSampleMode || 139 kRadial2_SampleMode == fSampleMode || 140 kSweep_SampleMode == fSampleMode; 141 } 142 143 void setWrapX(WrapMode mode) { fWrapX = mode; } 144 void setWrapY(WrapMode mode) { fWrapY = mode; } 145 void setSampleMode(SampleMode mode) { fSampleMode = mode; } 146 147 /** 148 * Sets the sampler's matrix. See SampleMode for explanation of 149 * relationship between the matrix and sample mode. 150 * @param matrix the matrix to set 151 */ 152 void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; } 153 154 /** 155 * Sets the sampler's texture coordinate domain to a 156 * custom rectangle, rather than the default (0,1). 157 * This option is currently only supported with kClamp_WrapMode 158 */ 159 void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; } 160 161 /** 162 * Multiplies the current sampler matrix a matrix 163 * 164 * After this call M' = M*m where M is the old matrix, m is the parameter 165 * to this function, and M' is the new matrix. (We consider points to 166 * be column vectors so tex cood vector t is transformed by matrix X as 167 * t' = X*t.) 168 * 169 * @param matrix the matrix used to modify the matrix. 170 */ 171 void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); } 172 173 /** 174 * Sets filtering type. 175 * @param filter type of filtering to apply 176 */ 177 void setFilter(Filter filter) { fFilter = filter; } 178 179 void setClampNoFilter() { 180 fWrapX = kClamp_WrapMode; 181 fWrapY = kClamp_WrapMode; 182 fSampleMode = kNormal_SampleMode; 183 fFilter = kNearest_Filter; 184 fMatrix.setIdentity(); 185 fTextureDomain.setEmpty(); 186 } 187 188 GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; } 189 GrScalar getRadial2Radius0() const { return fRadial2Radius0; } 190 bool isRadial2PosRoot() const { return fRadial2PosRoot; } 191 192 /** 193 * Sets the parameters for kRadial2_SampleMode. The texture 194 * matrix must be set so that the first point is at (0,0) and the second 195 * point lies on the x-axis. The second radius minus the first is 1 unit. 196 * The additional parameters to define the gradient are specified by this 197 * function. 198 */ 199 void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) { 200 fRadial2CenterX1 = centerX1; 201 fRadial2Radius0 = radius0; 202 fRadial2PosRoot = posRoot; 203 } 204 205 static const GrSamplerState& ClampNoFilter() { 206 return gClampNoFilter; 207 } 208 209 private: 210 WrapMode fWrapX; 211 WrapMode fWrapY; 212 SampleMode fSampleMode; 213 Filter fFilter; 214 GrMatrix fMatrix; 215 GrRect fTextureDomain; 216 217 // these are undefined unless fSampleMode == kRadial2_SampleMode 218 GrScalar fRadial2CenterX1; 219 GrScalar fRadial2Radius0; 220 bool fRadial2PosRoot; 221 222 static const GrSamplerState gClampNoFilter; 223 }; 224 225 #endif 226 227