| 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 |