blob: 373ea94cb39b2fcd5f1fd7c495e6b5d613549e82 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
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"
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000022#include "GrMatrix.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000023
24class GrSamplerState {
25public:
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +000026 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
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000044 /**
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 */
reed@google.comac10a2d2010-12-22 21:39:39 +000066 enum SampleMode {
67 kNormal_SampleMode, //!< sample color directly
reed@google.comac10a2d2010-12-22 21:39:39 +000068 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 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000084 * Default sampler state is set to clamp, use normal sampling mode, be
85 * unfiltered, and use identity matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +000086 */
87 GrSamplerState() {
88 this->setClampNoFilter();
89 }
90
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +000091 explicit GrSamplerState(Filter filter) {
reed@google.comac10a2d2010-12-22 21:39:39 +000092 fWrapX = kClamp_WrapMode;
93 fWrapY = kClamp_WrapMode;
94 fSampleMode = kNormal_SampleMode;
95 fFilter = filter;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000096 fMatrix.setIdentity();
junov@google.com6acc9b32011-05-16 18:32:07 +000097 fTextureDomain.setEmpty();
reed@google.comac10a2d2010-12-22 21:39:39 +000098 }
bsalomon@google.com5782d712011-01-21 21:03:59 +000099
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000100 GrSamplerState(WrapMode wx, WrapMode wy, Filter filter) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000101 fWrapX = wx;
102 fWrapY = wy;
103 fSampleMode = kNormal_SampleMode;
104 fFilter = filter;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000105 fMatrix.setIdentity();
junov@google.com6acc9b32011-05-16 18:32:07 +0000106 fTextureDomain.setEmpty();
reed@google.comac10a2d2010-12-22 21:39:39 +0000107 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000108
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000109 GrSamplerState(WrapMode wx, WrapMode wy,
110 const GrMatrix& matrix, Filter filter) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000111 fWrapX = wx;
112 fWrapY = wy;
113 fSampleMode = kNormal_SampleMode;
114 fFilter = filter;
115 fMatrix = matrix;
junov@google.com6acc9b32011-05-16 18:32:07 +0000116 fTextureDomain.setEmpty();
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000117 }
118
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000119 GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample,
120 const GrMatrix& matrix, Filter filter) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000121 fWrapX = wx;
122 fWrapY = wy;
123 fSampleMode = sample;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000124 fMatrix = matrix;
reed@google.comac10a2d2010-12-22 21:39:39 +0000125 fFilter = filter;
junov@google.com6acc9b32011-05-16 18:32:07 +0000126 fTextureDomain.setEmpty();
reed@google.comac10a2d2010-12-22 21:39:39 +0000127 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000128
reed@google.comac10a2d2010-12-22 21:39:39 +0000129 WrapMode getWrapX() const { return fWrapX; }
130 WrapMode getWrapY() const { return fWrapY; }
131 SampleMode getSampleMode() const { return fSampleMode; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000132 const GrMatrix& getMatrix() const { return fMatrix; }
junov@google.com6acc9b32011-05-16 18:32:07 +0000133 const GrRect& getTextureDomain() const { return fTextureDomain; }
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000134 bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000135 Filter getFilter() const { return fFilter; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000136
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; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000146
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 /**
junov@google.com6acc9b32011-05-16 18:32:07 +0000155 * 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 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000162 * 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 /**
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000174 * Sets filtering type.
175 * @param filter type of filtering to apply
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000176 */
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000177 void setFilter(Filter filter) { fFilter = filter; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000178
179 void setClampNoFilter() {
180 fWrapX = kClamp_WrapMode;
181 fWrapY = kClamp_WrapMode;
182 fSampleMode = kNormal_SampleMode;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000183 fFilter = kNearest_Filter;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000184 fMatrix.setIdentity();
junov@google.com6acc9b32011-05-16 18:32:07 +0000185 fTextureDomain.setEmpty();
reed@google.comac10a2d2010-12-22 21:39:39 +0000186 }
187
188 GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
189 GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
190 bool isRadial2PosRoot() const { return fRadial2PosRoot; }
191
192 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000193 * 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
reed@google.comac10a2d2010-12-22 21:39:39 +0000195 * 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
209private:
210 WrapMode fWrapX;
211 WrapMode fWrapY;
212 SampleMode fSampleMode;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000213 Filter fFilter;
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000214 GrMatrix fMatrix;
junov@google.com6acc9b32011-05-16 18:32:07 +0000215 GrRect fTextureDomain;
reed@google.comac10a2d2010-12-22 21:39:39 +0000216
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