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 "glsl/GrGLSLFragmentProcessor.h" | 8 #include "glsl/GrGLSLFragmentProcessor.h" |
9 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 9 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
10 #include "glsl/GrGLSLProgramDataManager.h" | 10 #include "glsl/GrGLSLProgramDataManager.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 !memcmp(fKernel, s.kernel(), | 184 !memcmp(fKernel, s.kernel(), |
185 fKernelSize.width() * fKernelSize.height() * sizeof(float)) &
& | 185 fKernelSize.width() * fKernelSize.height() * sizeof(float)) &
& |
186 fGain == s.gain() && | 186 fGain == s.gain() && |
187 fBias == s.bias() && | 187 fBias == s.bias() && |
188 fKernelOffset == s.kernelOffset() && | 188 fKernelOffset == s.kernelOffset() && |
189 fConvolveAlpha == s.convolveAlpha() && | 189 fConvolveAlpha == s.convolveAlpha() && |
190 fDomain == s.domain(); | 190 fDomain == s.domain(); |
191 } | 191 } |
192 | 192 |
193 // Static function to create a 2D convolution | 193 // Static function to create a 2D convolution |
194 GrFragmentProcessor* | 194 sk_sp<GrFragmentProcessor> |
195 GrMatrixConvolutionEffect::CreateGaussian(GrTexture* texture, | 195 GrMatrixConvolutionEffect::MakeGaussian(GrTexture* texture, |
196 const SkIRect& bounds, | 196 const SkIRect& bounds, |
197 const SkISize& kernelSize, | 197 const SkISize& kernelSize, |
198 SkScalar gain, | 198 SkScalar gain, |
199 SkScalar bias, | 199 SkScalar bias, |
200 const SkIPoint& kernelOffset, | 200 const SkIPoint& kernelOffset, |
201 GrTextureDomain::Mode tileMode, | 201 GrTextureDomain::Mode tileMode, |
202 bool convolveAlpha, | 202 bool convolveAlpha, |
203 SkScalar sigmaX, | 203 SkScalar sigmaX, |
204 SkScalar sigmaY) { | 204 SkScalar sigmaY) { |
205 float kernel[MAX_KERNEL_SIZE]; | 205 float kernel[MAX_KERNEL_SIZE]; |
206 int width = kernelSize.width(); | 206 int width = kernelSize.width(); |
207 int height = kernelSize.height(); | 207 int height = kernelSize.height(); |
208 SkASSERT(width * height <= MAX_KERNEL_SIZE); | 208 SkASSERT(width * height <= MAX_KERNEL_SIZE); |
209 float sum = 0.0f; | 209 float sum = 0.0f; |
210 float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX))); | 210 float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX))); |
211 float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY))); | 211 float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY))); |
212 int xRadius = width / 2; | 212 int xRadius = width / 2; |
213 int yRadius = height / 2; | 213 int yRadius = height / 2; |
214 for (int x = 0; x < width; x++) { | 214 for (int x = 0; x < width; x++) { |
215 float xTerm = static_cast<float>(x - xRadius); | 215 float xTerm = static_cast<float>(x - xRadius); |
216 xTerm = xTerm * xTerm * sigmaXDenom; | 216 xTerm = xTerm * xTerm * sigmaXDenom; |
217 for (int y = 0; y < height; y++) { | 217 for (int y = 0; y < height; y++) { |
218 float yTerm = static_cast<float>(y - yRadius); | 218 float yTerm = static_cast<float>(y - yRadius); |
219 float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom)); | 219 float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom)); |
220 // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian | 220 // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian |
221 // is dropped here, since we renormalize the kernel below. | 221 // is dropped here, since we renormalize the kernel below. |
222 kernel[y * width + x] = xyTerm; | 222 kernel[y * width + x] = xyTerm; |
223 sum += xyTerm; | 223 sum += xyTerm; |
224 } | 224 } |
225 } | 225 } |
226 // Normalize the kernel | 226 // Normalize the kernel |
227 float scale = 1.0f / sum; | 227 float scale = 1.0f / sum; |
228 for (int i = 0; i < width * height; ++i) { | 228 for (int i = 0; i < width * height; ++i) { |
229 kernel[i] *= scale; | 229 kernel[i] *= scale; |
230 } | 230 } |
231 return new GrMatrixConvolutionEffect(texture, bounds, kernelSize, kernel, ga
in, bias, | 231 return sk_sp<GrFragmentProcessor>( |
232 kernelOffset, tileMode, convolveAlpha); | 232 new GrMatrixConvolutionEffect(texture, bounds, kernelSize, kernel, gain,
bias, |
| 233 kernelOffset, tileMode, convolveAlpha)); |
233 } | 234 } |
234 | 235 |
235 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMatrixConvolutionEffect); | 236 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMatrixConvolutionEffect); |
236 | 237 |
237 const GrFragmentProcessor* GrMatrixConvolutionEffect::TestCreate(GrProcessorTest
Data* d) { | 238 sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::TestCreate(GrProcessorTest
Data* d) { |
238 int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
: | 239 int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
: |
239 GrProcessorUnitTest::kAlphaTextureIdx; | 240 GrProcessorUnitTest::kAlphaTextureIdx; |
240 int width = d->fRandom->nextRangeU(1, MAX_KERNEL_SIZE); | 241 int width = d->fRandom->nextRangeU(1, MAX_KERNEL_SIZE); |
241 int height = d->fRandom->nextRangeU(1, MAX_KERNEL_SIZE / width); | 242 int height = d->fRandom->nextRangeU(1, MAX_KERNEL_SIZE / width); |
242 SkISize kernelSize = SkISize::Make(width, height); | 243 SkISize kernelSize = SkISize::Make(width, height); |
243 SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]); | 244 SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]); |
244 for (int i = 0; i < width * height; i++) { | 245 for (int i = 0; i < width * height; i++) { |
245 kernel.get()[i] = d->fRandom->nextSScalar1(); | 246 kernel.get()[i] = d->fRandom->nextSScalar1(); |
246 } | 247 } |
247 SkScalar gain = d->fRandom->nextSScalar1(); | 248 SkScalar gain = d->fRandom->nextSScalar1(); |
248 SkScalar bias = d->fRandom->nextSScalar1(); | 249 SkScalar bias = d->fRandom->nextSScalar1(); |
249 SkIPoint kernelOffset = SkIPoint::Make(d->fRandom->nextRangeU(0, kernelSize.
width()), | 250 SkIPoint kernelOffset = SkIPoint::Make(d->fRandom->nextRangeU(0, kernelSize.
width()), |
250 d->fRandom->nextRangeU(0, kernelSize.
height())); | 251 d->fRandom->nextRangeU(0, kernelSize.
height())); |
251 SkIRect bounds = SkIRect::MakeXYWH(d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->width()), | 252 SkIRect bounds = SkIRect::MakeXYWH(d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->width()), |
252 d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->height()), | 253 d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->height()), |
253 d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->width()), | 254 d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->width()), |
254 d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->height())); | 255 d->fRandom->nextRangeU(0, d->fTextures[te
xIdx]->height())); |
255 GrTextureDomain::Mode tileMode = | 256 GrTextureDomain::Mode tileMode = |
256 static_cast<GrTextureDomain::Mode>(d->fRandom->nextRangeU(0, 2)); | 257 static_cast<GrTextureDomain::Mode>(d->fRandom->nextRangeU(0, 2)); |
257 bool convolveAlpha = d->fRandom->nextBool(); | 258 bool convolveAlpha = d->fRandom->nextBool(); |
258 return GrMatrixConvolutionEffect::Create(d->fTextures[texIdx], | 259 return GrMatrixConvolutionEffect::Make(d->fTextures[texIdx], |
259 bounds, | 260 bounds, |
260 kernelSize, | 261 kernelSize, |
261 kernel.get(), | 262 kernel.get(), |
262 gain, | 263 gain, |
263 bias, | 264 bias, |
264 kernelOffset, | 265 kernelOffset, |
265 tileMode, | 266 tileMode, |
266 convolveAlpha); | 267 convolveAlpha); |
267 } | 268 } |
OLD | NEW |