• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2010 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 
11 #ifndef GrSamplerState_DEFINED
12 #define GrSamplerState_DEFINED
13 
14 #include "GrTypes.h"
15 #include "GrMatrix.h"
16 
17 #define MAX_KERNEL_WIDTH 25
18 
19 class GrSamplerState {
20 public:
21     enum Filter {
22         /**
23          * Read the closest src texel to the sample position
24          */
25         kNearest_Filter,
26         /**
27          * Blend between closest 4 src texels to sample position (tent filter)
28          */
29         kBilinear_Filter,
30         /**
31          * Average of 4 bilinear filterings spaced +/- 1 texel from sample
32          * position in x and y. Intended for averaging 16 texels in a downsample
33          * pass. (rasterizing such that texture samples fall exactly halfway
34          * between texels in x and y spaced 4 texels apart.) Only supported
35          * on shader backends.
36          */
37         k4x4Downsample_Filter,
38         /**
39          * Apply a separable convolution kernel.
40          */
41         kConvolution_Filter,
42         /**
43          * Apply a dilate filter (max over a 1D radius).
44          */
45         kDilate_Filter,
46         /**
47          * Apply an erode filter (min over a 1D radius).
48          */
49         kErode_Filter,
50 
51         kDefault_Filter = kNearest_Filter
52     };
53 
54     /**
55      * The intepretation of the texture matrix depends on the sample mode. The
56      * texture matrix is applied both when the texture coordinates are explicit
57      * and  when vertex positions are used as texture  coordinates. In the latter
58      * case the texture matrix is applied to the pre-view-matrix position
59      * values.
60      *
61      * kNormal_SampleMode
62      *  The post-matrix texture coordinates are in normalize space with (0,0) at
63      *  the top-left and (1,1) at the bottom right.
64      * kRadial_SampleMode
65      *  The matrix specifies the radial gradient parameters.
66      *  (0,0) in the post-matrix space is center of the radial gradient.
67      * kRadial2_SampleMode
68      *   Matrix transforms to space where first circle is centered at the
69      *   origin. The second circle will be centered (x, 0) where x may be
70      *   0 and is provided by setRadial2Params. The post-matrix space is
71      *   normalized such that 1 is the second radius - first radius.
72      * kSweepSampleMode
73      *  The angle from the origin of texture coordinates in post-matrix space
74      *  determines the gradient value.
75      */
76     enum SampleMode {
77         kNormal_SampleMode,     //!< sample color directly
78         kRadial_SampleMode,     //!< treat as radial gradient
79         kRadial2_SampleMode,    //!< treat as 2-point radial gradient
80         kSweep_SampleMode,      //!< treat as sweep gradient
81 
82         kDefault_SampleMode = kNormal_SampleMode
83     };
84 
85     /**
86      * Describes how a texture is sampled when coordinates are outside the
87      * texture border
88      */
89     enum WrapMode {
90         kClamp_WrapMode,
91         kRepeat_WrapMode,
92         kMirror_WrapMode,
93 
94         kDefault_WrapMode = kClamp_WrapMode
95     };
96 
97     /**
98      * For the filters which perform more than one texture sample (convolution,
99      * erode, dilate), this determines the direction in which the texture
100      * coordinates will be incremented.
101      */
102     enum FilterDirection {
103         kX_FilterDirection,
104         kY_FilterDirection,
105 
106         kDefault_FilterDirection = kX_FilterDirection,
107     };
108     /**
109      * Default sampler state is set to clamp, use normal sampling mode, be
110      * unfiltered, and use identity matrix.
111      */
GrSamplerState()112     GrSamplerState()
113     : fRadial2CenterX1()
114     , fRadial2Radius0()
115     , fRadial2PosRoot() {
116         this->reset();
117     }
118 
getWrapX()119     WrapMode getWrapX() const { return fWrapX; }
getWrapY()120     WrapMode getWrapY() const { return fWrapY; }
getFilterDirection()121     FilterDirection getFilterDirection() const { return fFilterDirection; }
getSampleMode()122     SampleMode getSampleMode() const { return fSampleMode; }
getMatrix()123     const GrMatrix& getMatrix() const { return fMatrix; }
getTextureDomain()124     const GrRect& getTextureDomain() const { return fTextureDomain; }
hasTextureDomain()125     bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
getFilter()126     Filter getFilter() const { return fFilter; }
getKernelWidth()127     int getKernelWidth() const { return fKernelWidth; }
getKernel()128     const float* getKernel() const { return fKernel; }
swapsRAndB()129     bool swapsRAndB() const { return fSwapRAndB; }
130 
isGradient()131     bool isGradient() const {
132         return  kRadial_SampleMode == fSampleMode ||
133                 kRadial2_SampleMode == fSampleMode ||
134                 kSweep_SampleMode == fSampleMode;
135     }
136 
setWrapX(WrapMode mode)137     void setWrapX(WrapMode mode) { fWrapX = mode; }
setWrapY(WrapMode mode)138     void setWrapY(WrapMode mode) { fWrapY = mode; }
setSampleMode(SampleMode mode)139     void setSampleMode(SampleMode mode) { fSampleMode = mode; }
setFilterDirection(FilterDirection mode)140     void setFilterDirection(FilterDirection mode) { fFilterDirection = mode; }
141 
142     /**
143      * Access the sampler's matrix. See SampleMode for explanation of
144      * relationship between the matrix and sample mode.
145      */
matrix()146     GrMatrix* matrix() { return &fMatrix; }
147 
148     /**
149      * Sets the sampler's texture coordinate domain to a
150      * custom rectangle, rather than the default (0,1).
151      * This option is currently only supported with kClamp_WrapMode
152      */
setTextureDomain(const GrRect & textureDomain)153     void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; }
154 
155     /**
156      * Swaps the R and B components when reading from the texture. Has no effect
157      * if the texture is alpha only.
158      */
setRAndBSwap(bool swap)159     void setRAndBSwap(bool swap) { fSwapRAndB = swap; }
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 
reset(WrapMode wrapXAndY,Filter filter,FilterDirection direction,const GrMatrix & matrix)179     void reset(WrapMode wrapXAndY,
180                Filter filter,
181                FilterDirection direction,
182                const GrMatrix& matrix) {
183         fWrapX = wrapXAndY;
184         fWrapY = wrapXAndY;
185         fSampleMode = kDefault_SampleMode;
186         fFilter = filter;
187         fFilterDirection = direction;
188         fMatrix = matrix;
189         fTextureDomain.setEmpty();
190         fSwapRAndB = false;
191     }
reset(WrapMode wrapXAndY,Filter filter,const GrMatrix & matrix)192     void reset(WrapMode wrapXAndY, Filter filter, const GrMatrix& matrix) {
193         this->reset(wrapXAndY, filter, kDefault_FilterDirection, matrix);
194     }
reset(WrapMode wrapXAndY,Filter filter)195     void reset(WrapMode wrapXAndY,
196                Filter filter) {
197         this->reset(wrapXAndY, filter, kDefault_FilterDirection, GrMatrix::I());
198     }
reset(const GrMatrix & matrix)199     void reset(const GrMatrix& matrix) {
200         this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, matrix);
201     }
reset()202     void reset() {
203         this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, GrMatrix::I());
204     }
205 
getRadial2CenterX1()206     GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
getRadial2Radius0()207     GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
isRadial2PosRoot()208     bool     isRadial2PosRoot() const { return SkToBool(fRadial2PosRoot); }
209     // do the radial gradient params lead to a linear (rather than quadratic)
210     // equation.
radial2IsDegenerate()211     bool radial2IsDegenerate() const { return GR_Scalar1 == fRadial2CenterX1; }
212 
213     /**
214      * Sets the parameters for kRadial2_SampleMode. The texture
215      * matrix must be set so that the first point is at (0,0) and the second
216      * point lies on the x-axis. The second radius minus the first is 1 unit.
217      * The additional parameters to define the gradient are specified by this
218      * function.
219      */
setRadial2Params(GrScalar centerX1,GrScalar radius0,bool posRoot)220     void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) {
221         fRadial2CenterX1 = centerX1;
222         fRadial2Radius0 = radius0;
223         fRadial2PosRoot = posRoot;
224     }
225 
setConvolutionParams(int kernelWidth,const float * kernel)226     void setConvolutionParams(int kernelWidth, const float* kernel) {
227         GrAssert(kernelWidth >= 0 && kernelWidth <= MAX_KERNEL_WIDTH);
228         fKernelWidth = kernelWidth;
229         if (NULL != kernel) {
230             memcpy(fKernel, kernel, kernelWidth * sizeof(float));
231         }
232     }
233 
setMorphologyRadius(int radius)234     void setMorphologyRadius(int radius) {
235         GrAssert(radius >= 0 && radius <= MAX_KERNEL_WIDTH);
236         fKernelWidth = radius;
237     }
238 
239 private:
240     WrapMode            fWrapX : 8;
241     WrapMode            fWrapY : 8;
242     FilterDirection     fFilterDirection : 8;
243     SampleMode          fSampleMode : 8;
244     Filter              fFilter : 8;
245     GrMatrix            fMatrix;
246     bool                fSwapRAndB;
247     GrRect              fTextureDomain;
248 
249     // these are undefined unless fSampleMode == kRadial2_SampleMode
250     GrScalar            fRadial2CenterX1;
251     GrScalar            fRadial2Radius0;
252     SkBool8             fRadial2PosRoot;
253 
254     // These are undefined unless fFilter == kConvolution_Filter
255     uint8_t             fKernelWidth;
256     float               fKernel[MAX_KERNEL_WIDTH];
257 };
258 
259 #endif
260 
261