• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
GrSamplerState()87     GrSamplerState() {
88         this->setClampNoFilter();
89     }
90 
GrSamplerState(Filter filter)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 
GrSamplerState(WrapMode wx,WrapMode wy,Filter filter)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 
GrSamplerState(WrapMode wx,WrapMode wy,const GrMatrix & matrix,Filter filter)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 
GrSamplerState(WrapMode wx,WrapMode wy,SampleMode sample,const GrMatrix & matrix,Filter filter)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 
getWrapX()129     WrapMode getWrapX() const { return fWrapX; }
getWrapY()130     WrapMode getWrapY() const { return fWrapY; }
getSampleMode()131     SampleMode getSampleMode() const { return fSampleMode; }
getMatrix()132     const GrMatrix& getMatrix() const { return fMatrix; }
getTextureDomain()133     const GrRect& getTextureDomain() const { return fTextureDomain; }
hasTextureDomain()134     bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
getFilter()135     Filter getFilter() const { return fFilter; }
136 
isGradient()137     bool isGradient() const {
138         return  kRadial_SampleMode == fSampleMode ||
139                 kRadial2_SampleMode == fSampleMode ||
140                 kSweep_SampleMode == fSampleMode;
141     }
142 
setWrapX(WrapMode mode)143     void setWrapX(WrapMode mode) { fWrapX = mode; }
setWrapY(WrapMode mode)144     void setWrapY(WrapMode mode) { fWrapY = mode; }
setSampleMode(SampleMode 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      */
setMatrix(const GrMatrix & matrix)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      */
setTextureDomain(const GrRect & textureDomain)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      */
preConcatMatrix(const GrMatrix & matrix)171     void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
172 
173     /**
174      * Sets filtering type.
175      * @param filter    type of filtering to apply
176      */
setFilter(Filter filter)177     void setFilter(Filter filter) { fFilter = filter; }
178 
setClampNoFilter()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 
getRadial2CenterX1()188     GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
getRadial2Radius0()189     GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
isRadial2PosRoot()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      */
setRadial2Params(GrScalar centerX1,GrScalar radius0,bool posRoot)199     void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) {
200         fRadial2CenterX1 = centerX1;
201         fRadial2Radius0 = radius0;
202         fRadial2PosRoot = posRoot;
203     }
204 
ClampNoFilter()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