OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include "GrMatrixConvolutionEffect.h" | 7 #include "GrMatrixConvolutionEffect.h" |
8 #include "gl/GrGLShaderBuilder.h" | 8 #include "gl/GrGLShaderBuilder.h" |
9 #include "gl/GrGLEffect.h" | 9 #include "gl/GrGLEffect.h" |
10 #include "gl/GrGLSL.h" | 10 #include "gl/GrGLSL.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB uilder*); | 26 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyB uilder*); |
27 | 27 |
28 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; | 28 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; |
29 | 29 |
30 private: | 30 private: |
31 typedef GrGLUniformManager::UniformHandle UniformHandle; | 31 typedef GrGLUniformManager::UniformHandle UniformHandle; |
32 typedef GrMatrixConvolutionEffect::TileMode TileMode; | 32 typedef GrMatrixConvolutionEffect::TileMode TileMode; |
33 SkISize fKernelSize; | 33 SkISize fKernelSize; |
34 TileMode fTileMode; | 34 TileMode fTileMode; |
35 bool fConvolveAlpha; | 35 bool fConvolveAlpha; |
36 bool fUseBounds; | |
36 | 37 |
37 UniformHandle fBoundsUni; | 38 UniformHandle fBoundsUni; |
38 UniformHandle fKernelUni; | 39 UniformHandle fKernelUni; |
39 UniformHandle fImageIncrementUni; | 40 UniformHandle fImageIncrementUni; |
40 UniformHandle fKernelOffsetUni; | 41 UniformHandle fKernelOffsetUni; |
41 UniformHandle fGainUni; | 42 UniformHandle fGainUni; |
42 UniformHandle fBiasUni; | 43 UniformHandle fBiasUni; |
43 | 44 |
44 typedef GrGLEffect INHERITED; | 45 typedef GrGLEffect INHERITED; |
45 }; | 46 }; |
46 | 47 |
47 GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa ctory& factory, | 48 GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa ctory& factory, |
48 const GrDrawEffect& dra wEffect) | 49 const GrDrawEffect& dra wEffect) |
49 : INHERITED(factory) { | 50 : INHERITED(factory) { |
50 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti onEffect>(); | 51 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti onEffect>(); |
51 fKernelSize = m.kernelSize(); | 52 fKernelSize = m.kernelSize(); |
52 fTileMode = m.tileMode(); | 53 fTileMode = m.tileMode(); |
53 fConvolveAlpha = m.convolveAlpha(); | 54 fConvolveAlpha = m.convolveAlpha(); |
55 fUseBounds = m.useBounds(); | |
54 } | 56 } |
55 | 57 |
56 static void appendTextureLookup(GrGLShaderBuilder* builder, | 58 static void appendTextureLookup(GrGLShaderBuilder* builder, |
57 const GrGLShaderBuilder::TextureSampler& sampler , | 59 const GrGLShaderBuilder::TextureSampler& sampler , |
58 const char* coord, | 60 const char* coord, |
59 const char* bounds, | 61 const char* bounds, |
60 GrMatrixConvolutionEffect::TileMode tileMode) { | 62 GrMatrixConvolutionEffect::TileMode tileMode) { |
61 SkString clampedCoord; | 63 SkString clampedCoord; |
62 switch (tileMode) { | 64 if (bounds != NULL) { |
63 case GrMatrixConvolutionEffect::kClamp_TileMode: | 65 switch (tileMode) { |
64 clampedCoord.printf("clamp(%s, %s.xy, %s.zw)", coord, bounds, bounds ); | 66 case GrMatrixConvolutionEffect::kClamp_TileMode: |
65 coord = clampedCoord.c_str(); | 67 clampedCoord.printf("clamp(%s, %s.xy, %s.zw)", coord, bounds, bo unds); |
66 break; | 68 coord = clampedCoord.c_str(); |
67 case GrMatrixConvolutionEffect::kRepeat_TileMode: | 69 break; |
68 clampedCoord.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", coord, bounds, bounds, bounds, bounds); | 70 case GrMatrixConvolutionEffect::kRepeat_TileMode: |
69 coord = clampedCoord.c_str(); | 71 clampedCoord.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", co ord, bounds, bounds, |
70 break; | 72 bounds, bounds); |
71 case GrMatrixConvolutionEffect::kClampToBlack_TileMode: | 73 coord = clampedCoord.c_str(); |
72 builder->fsCodeAppendf("clamp(%s, %s.xy, %s.zw) != %s ? vec4(0, 0, 0 , 0) : ", coord, bounds, bounds, coord); | 74 break; |
73 break; | 75 case GrMatrixConvolutionEffect::kClampToBlack_TileMode: |
76 builder->fsCodeAppendf("clamp(%s, %s.xy, %s.zw) != %s ? vec4(0, 0, 0, 0) : ", coord, | |
77 bounds, bounds, coord); | |
78 break; | |
79 } | |
74 } | 80 } |
75 builder->fsAppendTextureLookup(sampler, coord); | 81 builder->fsAppendTextureLookup(sampler, coord); |
76 } | 82 } |
77 | 83 |
78 void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder, | 84 void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder, |
79 const GrDrawEffect&, | 85 const GrDrawEffect&, |
80 const GrEffectKey& key, | 86 const GrEffectKey& key, |
81 const char* outputColor, | 87 const char* outputColor, |
82 const char* inputColor, | 88 const char* inputColor, |
83 const TransformedCoordsArray& coords, | 89 const TransformedCoordsArray& coords, |
84 const TextureSamplerArray& samplers) { | 90 const TextureSamplerArray& samplers) { |
85 sk_ignore_unused_variable(inputColor); | 91 sk_ignore_unused_variable(inputColor); |
86 SkString coords2D = builder->ensureFSCoords2D(coords, 0); | 92 SkString coords2D = builder->ensureFSCoords2D(coords, 0); |
87 fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 93 if (fUseBounds) { |
88 kVec4f_GrSLType, "Bounds"); | 94 fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility , |
95 kVec4f_GrSLType, "Bounds"); | |
96 } | |
89 fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi lity, | 97 fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi lity, |
90 kVec2f_GrSLType, "ImageIncrement"); | 98 kVec2f_GrSLType, "ImageIncrement"); |
91 fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibilit y, | 99 fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibilit y, |
92 kFloat_GrSLType, | 100 kFloat_GrSLType, |
93 "Kernel", | 101 "Kernel", |
94 fKernelSize.width() * fKernelSize.h eight()); | 102 fKernelSize.width() * fKernelSize.h eight()); |
95 fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili ty, | 103 fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili ty, |
96 kVec2f_GrSLType, "KernelOffset"); | 104 kVec2f_GrSLType, "KernelOffset"); |
97 fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 105 fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
98 kFloat_GrSLType, "Gain"); | 106 kFloat_GrSLType, "Gain"); |
99 fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 107 fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
100 kFloat_GrSLType, "Bias"); | 108 kFloat_GrSLType, "Bias"); |
101 | 109 |
102 const char* bounds = builder->getUniformCStr(fBoundsUni); | 110 const char* bounds = NULL; |
111 if (fUseBounds) { | |
112 bounds = builder->getUniformCStr(fBoundsUni); | |
113 } | |
103 const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni); | 114 const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni); |
104 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); | 115 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); |
105 const char* kernel = builder->getUniformCStr(fKernelUni); | 116 const char* kernel = builder->getUniformCStr(fKernelUni); |
106 const char* gain = builder->getUniformCStr(fGainUni); | 117 const char* gain = builder->getUniformCStr(fGainUni); |
107 const char* bias = builder->getUniformCStr(fBiasUni); | 118 const char* bias = builder->getUniformCStr(fBiasUni); |
108 int kWidth = fKernelSize.width(); | 119 int kWidth = fKernelSize.width(); |
109 int kHeight = fKernelSize.height(); | 120 int kHeight = fKernelSize.height(); |
110 | 121 |
111 builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n"); | 122 builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n"); |
112 builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, imgInc); | 123 builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, |
113 builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight); | 124 imgInc); |
114 builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth); | 125 builder->fsCodeAppend("\t\tfloat k;\n"); |
115 builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth ); | 126 builder->fsCodeAppend("\t\tvec2 coord2;\n"); |
116 builder->fsCodeAppendf("\t\t\t\tvec2 coord2 = coord + vec2(x, y) * %s;\n", i mgInc); | 127 builder->fsCodeAppend("\t\tvec4 c;\n"); |
117 builder->fsCodeAppend("\t\t\t\tvec4 c = "); | 128 |
118 appendTextureLookup(builder, samplers[0], "coord2", bounds, fTileMode); | 129 for (int y = 0; y < kHeight; y++) { |
119 builder->fsCodeAppend(";\n"); | 130 for (int x = 0; x < kWidth; x++) { |
120 if (!fConvolveAlpha) { | 131 builder->fsCodeAppendf("\t\tk = %s[%d * %d + %d];\n", kernel, y, kWi dth, x); |
121 builder->fsCodeAppend("\t\t\t\tc.rgb /= c.a;\n"); | 132 builder->fsCodeAppendf("\t\tcoord2 = coord + vec2(%d, %d) * %s;\n", x, y, imgInc); |
133 builder->fsCodeAppend("\t\tc = "); | |
134 appendTextureLookup(builder, samplers[0], "coord2", bounds, fTileMod e); | |
135 builder->fsCodeAppend(";\n"); | |
136 if (!fConvolveAlpha) { | |
137 builder->fsCodeAppend("\t\tc.rgb /= c.a;\n"); | |
138 } | |
139 builder->fsCodeAppend("\t\tsum += c * k;\n"); | |
140 } | |
122 } | 141 } |
123 builder->fsCodeAppend("\t\t\t\tsum += c * k;\n"); | |
124 builder->fsCodeAppend("\t\t\t}\n"); | |
125 builder->fsCodeAppend("\t\t}\n"); | |
126 if (fConvolveAlpha) { | 142 if (fConvolveAlpha) { |
127 builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, b ias); | 143 builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, b ias); |
128 builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n", | 144 builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n", |
129 outputColor, outputColor, outputColor); | 145 outputColor, outputColor, outputColor); |
130 } else { | 146 } else { |
131 builder->fsCodeAppend("\t\tvec4 c = "); | 147 builder->fsCodeAppend("\t\tc = "); |
132 appendTextureLookup(builder, samplers[0], coords2D.c_str(), bounds, fTil eMode); | 148 appendTextureLookup(builder, samplers[0], coords2D.c_str(), bounds, fTil eMode); |
133 builder->fsCodeAppend(";\n"); | 149 builder->fsCodeAppend(";\n"); |
134 builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor); | 150 builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor); |
135 builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias); | 151 builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias); |
136 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor ); | 152 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor ); |
137 } | 153 } |
138 } | 154 } |
139 | 155 |
140 namespace { | 156 namespace { |
141 | 157 |
142 int encodeXY(int x, int y) { | 158 int encodeXY(int x, int y) { |
143 SkASSERT(x >= 1 && y >= 1 && x * y <= 32); | 159 SkASSERT(x >= 1 && y >= 1 && x * y <= 32); |
144 if (y < x) | 160 if (y < x) |
145 return 0x40 | encodeXY(y, x); | 161 return 0x40 | encodeXY(y, x); |
146 else | 162 else |
147 return (0x40 >> x) | (y - x); | 163 return (0x40 >> x) | (y - x); |
148 } | 164 } |
149 | 165 |
150 }; | 166 }; |
151 | 167 |
152 void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect, | 168 void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect, |
153 const GrGLCaps&, GrEffectKeyBuilder* b) { | 169 const GrGLCaps&, GrEffectKeyBuilder* b) { |
154 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti onEffect>(); | 170 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti onEffect>(); |
155 uint32_t key = encodeXY(m.kernelSize().width(), m.kernelSize().height()); | 171 uint32_t key = encodeXY(m.kernelSize().width(), m.kernelSize().height()); |
156 key |= m.tileMode() << 7; | 172 key |= m.tileMode() << 7; |
157 key |= m.convolveAlpha() ? 1 << 9 : 0; | 173 key |= m.convolveAlpha() ? 1 << 9 : 0; |
174 key |= m.useBounds() ? 1 << 10 : 0; | |
158 b->add32(key); | 175 b->add32(key); |
159 } | 176 } |
160 | 177 |
161 void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman, | 178 void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman, |
162 const GrDrawEffect& drawEffect) { | 179 const GrDrawEffect& drawEffect) { |
163 const GrMatrixConvolutionEffect& conv = drawEffect.castEffect<GrMatrixConvol utionEffect>(); | 180 const GrMatrixConvolutionEffect& conv = drawEffect.castEffect<GrMatrixConvol utionEffect>(); |
164 GrTexture& texture = *conv.texture(0); | 181 GrTexture& texture = *conv.texture(0); |
165 // the code we generated was for a specific kernel size | 182 // the code we generated was for a specific kernel size |
166 SkASSERT(conv.kernelSize() == fKernelSize); | 183 SkASSERT(conv.kernelSize() == fKernelSize); |
167 SkASSERT(conv.tileMode() == fTileMode); | 184 SkASSERT(conv.tileMode() == fTileMode); |
168 float imageIncrement[2]; | 185 float imageIncrement[2]; |
169 float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f; | 186 float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f; |
170 imageIncrement[0] = 1.0f / texture.width(); | 187 imageIncrement[0] = 1.0f / texture.width(); |
171 imageIncrement[1] = ySign / texture.height(); | 188 imageIncrement[1] = ySign / texture.height(); |
172 uman.set2fv(fImageIncrementUni, 1, imageIncrement); | 189 uman.set2fv(fImageIncrementUni, 1, imageIncrement); |
173 uman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset()); | 190 uman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset()); |
174 uman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.ker nel()); | 191 uman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.ker nel()); |
175 uman.set1f(fGainUni, conv.gain()); | 192 uman.set1f(fGainUni, conv.gain()); |
176 uman.set1f(fBiasUni, conv.bias()); | 193 uman.set1f(fBiasUni, conv.bias()); |
177 const SkIRect& bounds = conv.bounds(); | 194 if (fUseBounds) { |
178 float left = (float) bounds.left() / texture.width(); | 195 const SkIRect& bounds = conv.bounds(); |
179 float top = (float) bounds.top() / texture.height(); | 196 float left = (float) bounds.left() / texture.width(); |
180 float right = (float) bounds.right() / texture.width(); | 197 float top = (float) bounds.top() / texture.height(); |
181 float bottom = (float) bounds.bottom() / texture.height(); | 198 float right = (float) bounds.right() / texture.width(); |
182 if (texture.origin() == kBottomLeft_GrSurfaceOrigin) { | 199 float bottom = (float) bounds.bottom() / texture.height(); |
183 uman.set4f(fBoundsUni, left, 1.0f - bottom, right, 1.0f - top); | 200 if (texture.origin() == kBottomLeft_GrSurfaceOrigin) { |
184 } else { | 201 uman.set4f(fBoundsUni, left, 1.0f - bottom, right, 1.0f - top); |
185 uman.set4f(fBoundsUni, left, top, right, bottom); | 202 } else { |
203 uman.set4f(fBoundsUni, left, top, right, bottom); | |
204 } | |
186 } | 205 } |
187 } | 206 } |
188 | 207 |
189 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, | 208 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, |
190 const SkIRect& bounds, | 209 const SkIRect& bounds, |
191 const SkISize& kernelSize, | 210 const SkISize& kernelSize, |
192 const SkScalar* kernel, | 211 const SkScalar* kernel, |
193 SkScalar gain, | 212 SkScalar gain, |
194 SkScalar bias, | 213 SkScalar bias, |
195 const SkIPoint& kernelOffse t, | 214 const SkIPoint& kernelOffse t, |
196 TileMode tileMode, | 215 TileMode tileMode, |
197 bool convolveAlpha) | 216 bool convolveAlpha, |
217 bool useBounds) | |
198 : INHERITED(texture, MakeDivByTextureWHMatrix(texture)), | 218 : INHERITED(texture, MakeDivByTextureWHMatrix(texture)), |
199 fBounds(bounds), | 219 fBounds(bounds), |
200 fKernelSize(kernelSize), | 220 fKernelSize(kernelSize), |
201 fGain(SkScalarToFloat(gain)), | 221 fGain(SkScalarToFloat(gain)), |
202 fBias(SkScalarToFloat(bias) / 255.0f), | 222 fBias(SkScalarToFloat(bias) / 255.0f), |
203 fTileMode(tileMode), | 223 fTileMode(tileMode), |
204 fConvolveAlpha(convolveAlpha) { | 224 fConvolveAlpha(convolveAlpha), |
205 fKernel = new float[kernelSize.width() * kernelSize.height()]; | 225 fUseBounds(useBounds) { |
206 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { | 226 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { |
207 fKernel[i] = SkScalarToFloat(kernel[i]); | 227 fKernel[i] = SkScalarToFloat(kernel[i]); |
208 } | 228 } |
209 fKernelOffset[0] = static_cast<float>(kernelOffset.x()); | 229 fKernelOffset[0] = static_cast<float>(kernelOffset.x()); |
210 fKernelOffset[1] = static_cast<float>(kernelOffset.y()); | 230 fKernelOffset[1] = static_cast<float>(kernelOffset.y()); |
211 this->setWillNotUseInputColor(); | 231 this->setWillNotUseInputColor(); |
212 } | 232 } |
213 | 233 |
234 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, | |
235 const SkIRect& bounds, | |
236 const SkISize& kernelSize, | |
237 SkScalar gain, | |
238 SkScalar bias, | |
239 const SkIPoint& kernelOffse t, | |
240 TileMode tileMode, | |
241 bool convolveAlpha, | |
242 bool useBounds, | |
243 SkScalar sigmaX, | |
244 SkScalar sigmaY) | |
245 : INHERITED(texture, MakeDivByTextureWHMatrix(texture)), | |
246 fBounds(bounds), | |
247 fKernelSize(kernelSize), | |
248 fGain(SkScalarToFloat(gain)), | |
249 fBias(SkScalarToFloat(bias) / 255.0f), | |
250 fTileMode(tileMode), | |
251 fConvolveAlpha(convolveAlpha), | |
252 fUseBounds(useBounds) { | |
253 int width = kernelSize.width(); | |
254 int height = kernelSize.height(); | |
255 SkASSERT(width * height <= MAX_KERNEL_SIZE); | |
256 float sum = 0.0f; | |
257 float sigmaXDenom = 1.0 / (2.0 * sigmaX * sigmaX); | |
258 float sigmaYDenom = 1.0 / (2.0 * sigmaY * sigmaY); | |
259 int xRadius = width / 2; | |
260 int yRadius = height / 2; | |
261 for (int x = 0; x < width; x++) { | |
262 float xTerm = static_cast<float>(x - xRadius); | |
263 xTerm = SkScalarSquare(xTerm) * sigmaXDenom; | |
264 for (int y = 0; y < height; y++) { | |
265 float yTerm = static_cast<float>(y - yRadius); | |
266 | |
267 float xyTerm = sk_float_exp(-(xTerm + SkScalarSquare(yTerm) * sigmaYDeno m)); | |
268 // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian | |
269 // is dropped here, since we renormalize the kernel below. | |
Stephen White
2014/07/25 20:43:18
I'm not fond of baking the Gaussian-specific stuff
| |
270 fKernel[y * width + x] = xyTerm; | |
271 sum += xyTerm; | |
272 } | |
273 } | |
274 // Normalize the kernel | |
275 float scale = 1.0f / sum; | |
276 for (int i = 0; i < width * height; ++i) { | |
277 fKernel[i] *= scale; | |
278 } | |
279 | |
280 fKernelOffset[0] = static_cast<float>(kernelOffset.x()); | |
281 fKernelOffset[1] = static_cast<float>(kernelOffset.y()); | |
282 this->setWillNotUseInputColor(); | |
283 } | |
284 | |
214 GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() { | 285 GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() { |
215 delete[] fKernel; | |
216 } | 286 } |
217 | 287 |
218 const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const { | 288 const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const { |
219 return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance(); | 289 return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance(); |
220 } | 290 } |
221 | 291 |
222 bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const { | 292 bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const { |
223 const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(s Base); | 293 const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(s Base); |
224 return this->texture(0) == s.texture(0) && | 294 return this->texture(0) == s.texture(0) && |
225 fKernelSize == s.kernelSize() && | 295 fKernelSize == s.kernelSize() && |
(...skipping 24 matching lines...) Expand all Loading... | |
250 SkScalar gain = random->nextSScalar1(); | 320 SkScalar gain = random->nextSScalar1(); |
251 SkScalar bias = random->nextSScalar1(); | 321 SkScalar bias = random->nextSScalar1(); |
252 SkIPoint kernelOffset = SkIPoint::Make(random->nextRangeU(0, kernelSize.widt h()), | 322 SkIPoint kernelOffset = SkIPoint::Make(random->nextRangeU(0, kernelSize.widt h()), |
253 random->nextRangeU(0, kernelSize.heig ht())); | 323 random->nextRangeU(0, kernelSize.heig ht())); |
254 SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->w idth()), | 324 SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->w idth()), |
255 random->nextRangeU(0, textures[texIdx]->h eight()), | 325 random->nextRangeU(0, textures[texIdx]->h eight()), |
256 random->nextRangeU(0, textures[texIdx]->w idth()), | 326 random->nextRangeU(0, textures[texIdx]->w idth()), |
257 random->nextRangeU(0, textures[texIdx]->h eight())); | 327 random->nextRangeU(0, textures[texIdx]->h eight())); |
258 TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2)); | 328 TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2)); |
259 bool convolveAlpha = random->nextBool(); | 329 bool convolveAlpha = random->nextBool(); |
330 bool useBounds = random->nextBool(); | |
260 return GrMatrixConvolutionEffect::Create(textures[texIdx], | 331 return GrMatrixConvolutionEffect::Create(textures[texIdx], |
261 bounds, | 332 bounds, |
262 kernelSize, | 333 kernelSize, |
263 kernel.get(), | 334 kernel.get(), |
264 gain, | 335 gain, |
265 bias, | 336 bias, |
266 kernelOffset, | 337 kernelOffset, |
267 tileMode, | 338 tileMode, |
268 convolveAlpha); | 339 convolveAlpha, |
340 useBounds); | |
269 } | 341 } |
OLD | NEW |