Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: src/gpu/effects/GrMatrixConvolutionEffect.cpp

Issue 418223009: 2D kernel initial wiring for Guassian (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrMatrixConvolutionEffect.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 kFloat_GrSLType, "Bias"); 77 kFloat_GrSLType, "Bias");
78 78
79 const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni); 79 const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni);
80 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); 80 const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
81 const char* kernel = builder->getUniformCStr(fKernelUni); 81 const char* kernel = builder->getUniformCStr(fKernelUni);
82 const char* gain = builder->getUniformCStr(fGainUni); 82 const char* gain = builder->getUniformCStr(fGainUni);
83 const char* bias = builder->getUniformCStr(fBiasUni); 83 const char* bias = builder->getUniformCStr(fBiasUni);
84 int kWidth = fKernelSize.width(); 84 int kWidth = fKernelSize.width();
85 int kHeight = fKernelSize.height(); 85 int kHeight = fKernelSize.height();
86 86
87 builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n"); 87 builder->fsCodeAppend("vec4 sum = vec4(0, 0, 0, 0);");
88 builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, 88 builder->fsCodeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), kerne lOffset,
89 imgInc); 89 imgInc);
90 builder->fsCodeAppend("\t\tvec4 c;\n"); 90 builder->fsCodeAppend("vec4 c;");
91 91
92 for (int y = 0; y < kHeight; y++) { 92 for (int y = 0; y < kHeight; y++) {
93 for (int x = 0; x < kWidth; x++) { 93 for (int x = 0; x < kWidth; x++) {
94 GrGLShaderBuilder::FSBlock block(builder); 94 GrGLShaderBuilder::FSBlock block(builder);
95 builder->fsCodeAppendf("\t\tfloat k = %s[%d * %d + %d];\n", kernel, y, kWidth, x); 95 builder->fsCodeAppendf("float k = %s[%d * %d + %d];", kernel, y, kWi dth, x);
96 SkString coord; 96 SkString coord;
97 coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc); 97 coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc);
98 fDomain.sampleTexture(builder, domain, "c", coord, samplers[0]); 98 fDomain.sampleTexture(builder, domain, "c", coord, samplers[0]);
99 if (!fConvolveAlpha) { 99 if (!fConvolveAlpha) {
100 builder->fsCodeAppend("\t\tc.rgb /= c.a;\n"); 100 builder->fsCodeAppend("c.rgb /= c.a;");
101 } 101 }
102 builder->fsCodeAppend("\t\tsum += c * k;\n"); 102 builder->fsCodeAppend("sum += c * k;");
103 } 103 }
104 } 104 }
105 if (fConvolveAlpha) { 105 if (fConvolveAlpha) {
106 builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, b ias); 106 builder->fsCodeAppendf("%s = sum * %s + %s;", outputColor, gain, bias);
107 builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n", 107 builder->fsCodeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
108 outputColor, outputColor, outputColor); 108 outputColor, outputColor, outputColor);
109 } else { 109 } else {
110 fDomain.sampleTexture(builder, domain, "c", coords2D, samplers[0]); 110 fDomain.sampleTexture(builder, domain, "c", coords2D, samplers[0]);
111 builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor); 111 builder->fsCodeAppendf("%s.a = c.a;", outputColor);
112 builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias); 112 builder->fsCodeAppendf("%s.rgb = sum.rgb * %s + %s;", outputColor, gain, bias);
113 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor ); 113 builder->fsCodeAppendf("%s.rgb *= %s.a;", outputColor, outputColor);
114 } 114 }
115
116 SkString modulate;
117 GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor);
118 builder->fsCodeAppend(modulate.c_str());
115 } 119 }
116 120
117 void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect, 121 void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
118 const GrGLCaps&, GrEffectKeyBuilder* b) { 122 const GrGLCaps&, GrEffectKeyBuilder* b) {
119 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti onEffect>(); 123 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti onEffect>();
120 SkASSERT(m.kernelSize().width() <= 0x7FFF && m.kernelSize().height() <= 0xFF FF); 124 SkASSERT(m.kernelSize().width() <= 0x7FFF && m.kernelSize().height() <= 0xFF FF);
121 uint32_t key = m.kernelSize().width() << 16 | m.kernelSize().height(); 125 uint32_t key = m.kernelSize().width() << 16 | m.kernelSize().height();
122 key |= m.convolveAlpha() ? 1 << 31 : 0; 126 key |= m.convolveAlpha() ? 1 << 31 : 0;
123 b->add32(key); 127 b->add32(key);
124 b->add32(GrTextureDomain::GLDomain::DomainKey(m.domain())); 128 b->add32(GrTextureDomain::GLDomain::DomainKey(m.domain()));
(...skipping 25 matching lines...) Expand all
150 SkScalar bias, 154 SkScalar bias,
151 const SkIPoint& kernelOffse t, 155 const SkIPoint& kernelOffse t,
152 GrTextureDomain::Mode tileM ode, 156 GrTextureDomain::Mode tileM ode,
153 bool convolveAlpha) 157 bool convolveAlpha)
154 : INHERITED(texture, MakeDivByTextureWHMatrix(texture)), 158 : INHERITED(texture, MakeDivByTextureWHMatrix(texture)),
155 fKernelSize(kernelSize), 159 fKernelSize(kernelSize),
156 fGain(SkScalarToFloat(gain)), 160 fGain(SkScalarToFloat(gain)),
157 fBias(SkScalarToFloat(bias) / 255.0f), 161 fBias(SkScalarToFloat(bias) / 255.0f),
158 fConvolveAlpha(convolveAlpha), 162 fConvolveAlpha(convolveAlpha),
159 fDomain(GrTextureDomain::MakeTexelDomain(texture, bounds), tileMode) { 163 fDomain(GrTextureDomain::MakeTexelDomain(texture, bounds), tileMode) {
160 fKernel = new float[kernelSize.width() * kernelSize.height()];
161 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { 164 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
162 fKernel[i] = SkScalarToFloat(kernel[i]); 165 fKernel[i] = SkScalarToFloat(kernel[i]);
163 } 166 }
164 fKernelOffset[0] = static_cast<float>(kernelOffset.x()); 167 fKernelOffset[0] = static_cast<float>(kernelOffset.x());
165 fKernelOffset[1] = static_cast<float>(kernelOffset.y()); 168 fKernelOffset[1] = static_cast<float>(kernelOffset.y());
166 this->setWillNotUseInputColor();
167 } 169 }
168 170
169 GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() { 171 GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() {
170 delete[] fKernel;
171 } 172 }
172 173
173 const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const { 174 const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const {
174 return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance(); 175 return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance();
175 } 176 }
176 177
177 bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const { 178 bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
178 const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(s Base); 179 const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(s Base);
179 return this->texture(0) == s.texture(0) && 180 return this->texture(0) == s.texture(0) &&
180 fKernelSize == s.kernelSize() && 181 fKernelSize == s.kernelSize() &&
181 !memcmp(fKernel, s.kernel(), 182 !memcmp(fKernel, s.kernel(),
182 fKernelSize.width() * fKernelSize.height() * sizeof(float)) & & 183 fKernelSize.width() * fKernelSize.height() * sizeof(float)) & &
183 fGain == s.gain() && 184 fGain == s.gain() &&
184 fBias == s.bias() && 185 fBias == s.bias() &&
185 fKernelOffset == s.kernelOffset() && 186 fKernelOffset == s.kernelOffset() &&
186 fConvolveAlpha == s.convolveAlpha() && 187 fConvolveAlpha == s.convolveAlpha() &&
187 fDomain == s.domain(); 188 fDomain == s.domain();
188 } 189 }
189 190
191 // Static function to create a 2D convolution
192 GrEffect* GrMatrixConvolutionEffect::CreateGaussian(GrTexture* texture,
193 const SkIRect& bounds,
194 const SkISize& kernelSize,
195 SkScalar gain,
196 SkScalar bias,
197 const SkIPoint& kernelOffset ,
198 GrTextureDomain::Mode tileMo de,
199 bool convolveAlpha,
200 SkScalar sigmaX,
201 SkScalar sigmaY) {
202 float kernel[MAX_KERNEL_SIZE];
203 int width = kernelSize.width();
204 int height = kernelSize.height();
205 SkASSERT(width * height <= MAX_KERNEL_SIZE);
206 float sum = 0.0f;
207 float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX)));
208 float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY)));
209 int xRadius = width / 2;
210 int yRadius = height / 2;
211 for (int x = 0; x < width; x++) {
212 float xTerm = static_cast<float>(x - xRadius);
213 xTerm = xTerm * xTerm * sigmaXDenom;
214 for (int y = 0; y < height; y++) {
215 float yTerm = static_cast<float>(y - yRadius);
216 float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom));
217 // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
218 // is dropped here, since we renormalize the kernel below.
219 kernel[y * width + x] = xyTerm;
220 sum += xyTerm;
221 }
222 }
223 // Normalize the kernel
224 float scale = 1.0f / sum;
225 for (int i = 0; i < width * height; ++i) {
226 kernel[i] *= scale;
227 }
228 return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
229 bounds,
230 kernelSize,
231 kernel,
232 gain,
233 bias,
234 kernelOffset,
235 tileMode,
236 convolveAlpha));
237 }
238
190 GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect); 239 GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect);
191 240
192 GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random, 241 GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
193 GrContext* context, 242 GrContext* context,
194 const GrDrawTargetCaps&, 243 const GrDrawTargetCaps&,
195 GrTexture* textures[]) { 244 GrTexture* textures[]) {
196 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 245 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
197 GrEffectUnitTest::kAlphaTextureIdx; 246 GrEffectUnitTest::kAlphaTextureIdx;
198 int width = random->nextRangeU(1, MAX_KERNEL_SIZE); 247 int width = random->nextRangeU(1, MAX_KERNEL_SIZE);
199 int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width); 248 int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width);
(...skipping 15 matching lines...) Expand all
215 return GrMatrixConvolutionEffect::Create(textures[texIdx], 264 return GrMatrixConvolutionEffect::Create(textures[texIdx],
216 bounds, 265 bounds,
217 kernelSize, 266 kernelSize,
218 kernel.get(), 267 kernel.get(),
219 gain, 268 gain,
220 bias, 269 bias,
221 kernelOffset, 270 kernelOffset,
222 tileMode, 271 tileMode,
223 convolveAlpha); 272 convolveAlpha);
224 } 273 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrMatrixConvolutionEffect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698