blob: fb59111d14612d5863851d483aa4dede49a792b2 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#ifndef GrSamplerState_DEFINED
12#define GrSamplerState_DEFINED
13
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000014#include "GrCustomStage.h"
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000015#include "GrMatrix.h"
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000016#include "GrTypes.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000017
18class GrSamplerState {
19public:
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +000020 enum Filter {
21 /**
22 * Read the closest src texel to the sample position
23 */
24 kNearest_Filter,
25 /**
26 * Blend between closest 4 src texels to sample position (tent filter)
27 */
28 kBilinear_Filter,
29 /**
30 * Average of 4 bilinear filterings spaced +/- 1 texel from sample
31 * position in x and y. Intended for averaging 16 texels in a downsample
32 * pass. (rasterizing such that texture samples fall exactly halfway
bsalomon@google.com1f221a72011-08-23 20:54:07 +000033 * between texels in x and y spaced 4 texels apart.) Only supported
34 * on shader backends.
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +000035 */
36 k4x4Downsample_Filter,
bsalomon@google.comaa814fe2011-12-12 18:45:07 +000037
38 kDefault_Filter = kNearest_Filter
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +000039 };
40
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000041 /**
reed@google.comac10a2d2010-12-22 21:39:39 +000042 * Describes how a texture is sampled when coordinates are outside the
43 * texture border
44 */
45 enum WrapMode {
46 kClamp_WrapMode,
47 kRepeat_WrapMode,
bsalomon@google.comaa814fe2011-12-12 18:45:07 +000048 kMirror_WrapMode,
49
50 kDefault_WrapMode = kClamp_WrapMode
reed@google.comac10a2d2010-12-22 21:39:39 +000051 };
52
53 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000054 * Default sampler state is set to clamp, use normal sampling mode, be
55 * unfiltered, and use identity matrix.
reed@google.comac10a2d2010-12-22 21:39:39 +000056 */
bsalomon@google.com6aab8e32011-06-21 20:32:12 +000057 GrSamplerState()
tomhudson@google.com898e7b52012-06-01 20:42:15 +000058 : fCustomStage (NULL) {
tomhudson@google.com194de082012-05-31 20:35:27 +000059 memset(this, 0, sizeof(GrSamplerState));
bsalomon@google.com97912912011-12-06 16:30:36 +000060 this->reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000061 }
62
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000063 ~GrSamplerState() {
64 GrSafeUnref(fCustomStage);
65 }
66
tomhudson@google.com02b1ea22012-04-30 20:19:07 +000067 bool operator ==(const GrSamplerState& s) const {
tomhudson@google.comb88bbd22012-05-01 12:48:07 +000068 /* We must be bit-identical as far as the CustomStage;
69 there may be multiple CustomStages that will produce
70 the same shader code and so are equivalent.
71 Can't take the address of fWrapX because it's :8 */
72 int bitwiseRegion = (intptr_t) &fCustomStage - (intptr_t) this;
73 GrAssert(sizeof(GrSamplerState) ==
74 bitwiseRegion + sizeof(fCustomStage));
75 return !memcmp(this, &s, bitwiseRegion) &&
76 ((fCustomStage == s.fCustomStage) ||
77 (fCustomStage && s.fCustomStage &&
tomhudson@google.comd8f856c2012-05-10 12:13:36 +000078 (fCustomStage->getFactory() ==
79 s.fCustomStage->getFactory()) &&
bsalomon@google.comb505a122012-05-31 18:40:36 +000080 fCustomStage->isEqual(*s.fCustomStage)));
tomhudson@google.com02b1ea22012-04-30 20:19:07 +000081 }
82 bool operator !=(const GrSamplerState& s) const { return !(*this == s); }
83
tomhudson@google.com0bdbed32012-06-01 19:50:02 +000084 GrSamplerState& operator =(const GrSamplerState& s) {
tomhudson@google.com11175592012-05-31 14:23:28 +000085 // memcpy() breaks refcounting
86 fWrapX = s.fWrapX;
87 fWrapY = s.fWrapY;
tomhudson@google.com11175592012-05-31 14:23:28 +000088 fFilter = s.fFilter;
89 fMatrix = s.fMatrix;
90 fSwapRAndB = s.fSwapRAndB;
91 fTextureDomain = s.fTextureDomain;
92
tomhudson@google.com11175592012-05-31 14:23:28 +000093 fCustomStage = s.fCustomStage;
94 SkSafeRef(fCustomStage);
95
tomhudson@google.com02b1ea22012-04-30 20:19:07 +000096 return *this;
97 }
98
reed@google.comac10a2d2010-12-22 21:39:39 +000099 WrapMode getWrapX() const { return fWrapX; }
100 WrapMode getWrapY() const { return fWrapY; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000101 const GrMatrix& getMatrix() const { return fMatrix; }
junov@google.com6acc9b32011-05-16 18:32:07 +0000102 const GrRect& getTextureDomain() const { return fTextureDomain; }
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000103 bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000104 Filter getFilter() const { return fFilter; }
bsalomon@google.com0a97be22011-11-08 19:20:57 +0000105 bool swapsRAndB() const { return fSwapRAndB; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000106
107 void setWrapX(WrapMode mode) { fWrapX = mode; }
108 void setWrapY(WrapMode mode) { fWrapY = mode; }
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000109
110 /**
bsalomon@google.comaa814fe2011-12-12 18:45:07 +0000111 * Access the sampler's matrix. See SampleMode for explanation of
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000112 * relationship between the matrix and sample mode.
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000113 */
bsalomon@google.comaa814fe2011-12-12 18:45:07 +0000114 GrMatrix* matrix() { return &fMatrix; }
115
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000116 /**
junov@google.com6acc9b32011-05-16 18:32:07 +0000117 * Sets the sampler's texture coordinate domain to a
118 * custom rectangle, rather than the default (0,1).
119 * This option is currently only supported with kClamp_WrapMode
120 */
121 void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; }
122
123 /**
bsalomon@google.com0a97be22011-11-08 19:20:57 +0000124 * Swaps the R and B components when reading from the texture. Has no effect
125 * if the texture is alpha only.
126 */
127 void setRAndBSwap(bool swap) { fSwapRAndB = swap; }
128
129 /**
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000130 * Multiplies the current sampler matrix a matrix
131 *
132 * After this call M' = M*m where M is the old matrix, m is the parameter
133 * to this function, and M' is the new matrix. (We consider points to
134 * be column vectors so tex cood vector t is transformed by matrix X as
135 * t' = X*t.)
136 *
137 * @param matrix the matrix used to modify the matrix.
138 */
139 void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
140
141 /**
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000142 * Sets filtering type.
143 * @param filter type of filtering to apply
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000144 */
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000145 void setFilter(Filter filter) { fFilter = filter; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000146
bsalomon@google.com97912912011-12-06 16:30:36 +0000147 void reset(WrapMode wrapXAndY,
148 Filter filter,
149 const GrMatrix& matrix) {
150 fWrapX = wrapXAndY;
151 fWrapY = wrapXAndY;
bsalomon@google.com97912912011-12-06 16:30:36 +0000152 fFilter = filter;
153 fMatrix = matrix;
154 fTextureDomain.setEmpty();
155 fSwapRAndB = false;
tomhudson@google.com07eecdc2012-04-20 18:35:38 +0000156 GrSafeSetNull(fCustomStage);
bsalomon@google.com97912912011-12-06 16:30:36 +0000157 }
bsalomon@google.comb505a122012-05-31 18:40:36 +0000158 void reset(WrapMode wrapXAndY, Filter filter) {
159 this->reset(wrapXAndY, filter, GrMatrix::I());
bsalomon@google.comaa814fe2011-12-12 18:45:07 +0000160 }
bsalomon@google.com1e266f82011-12-12 16:11:33 +0000161 void reset(const GrMatrix& matrix) {
bsalomon@google.comb505a122012-05-31 18:40:36 +0000162 this->reset(kDefault_WrapMode, kDefault_Filter, matrix);
bsalomon@google.comaa814fe2011-12-12 18:45:07 +0000163 }
164 void reset() {
bsalomon@google.comb505a122012-05-31 18:40:36 +0000165 this->reset(kDefault_WrapMode, kDefault_Filter, GrMatrix::I());
bsalomon@google.com1e266f82011-12-12 16:11:33 +0000166 }
bsalomon@google.com97912912011-12-06 16:30:36 +0000167
tomhudson@google.com07eecdc2012-04-20 18:35:38 +0000168 void setCustomStage(GrCustomStage* stage) {
169 GrSafeAssign(fCustomStage, stage);
170 }
171 GrCustomStage* getCustomStage() const { return fCustomStage; }
172
reed@google.comac10a2d2010-12-22 21:39:39 +0000173private:
senorblanco@chromium.org05054f12012-03-02 21:05:45 +0000174 WrapMode fWrapX : 8;
175 WrapMode fWrapY : 8;
senorblanco@chromium.org05054f12012-03-02 21:05:45 +0000176 Filter fFilter : 8;
senorblanco@chromium.org05054f12012-03-02 21:05:45 +0000177 bool fSwapRAndB;
tomhudson@google.com898e7b52012-06-01 20:42:15 +0000178 GrMatrix fMatrix;
senorblanco@chromium.org05054f12012-03-02 21:05:45 +0000179 GrRect fTextureDomain;
reed@google.comac10a2d2010-12-22 21:39:39 +0000180
tomhudson@google.com02b1ea22012-04-30 20:19:07 +0000181 GrCustomStage* fCustomStage;
reed@google.comac10a2d2010-12-22 21:39:39 +0000182};
183
184#endif
185