Push GrTextureProxy down to more effects
Change-Id: Ie3f32a88f25af082c25bc6daf3fe24e303e80f9e
Reviewed-on: https://skia-review.googlesource.com/7616
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 9b670e1..86fd565 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -172,6 +172,32 @@
fKernelOffset[1] = static_cast<float>(kernelOffset.y());
}
+GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ const SkScalar* kernel,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha)
+ // To advertise either the modulation or opaqueness optimizations we'd have to examine the
+ // parameters.
+ : INHERITED(context, kNone_OptimizationFlags, proxy, nullptr, SkMatrix::I())
+ , fKernelSize(kernelSize)
+ , fGain(SkScalarToFloat(gain))
+ , fBias(SkScalarToFloat(bias) / 255.0f)
+ , fConvolveAlpha(convolveAlpha)
+ , fDomain(proxy.get(), GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) {
+ this->initClassID<GrMatrixConvolutionEffect>();
+ for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
+ fKernel[i] = SkScalarToFloat(kernel[i]);
+ }
+ fKernelOffset[0] = static_cast<float>(kernelOffset.x());
+ fKernelOffset[1] = static_cast<float>(kernelOffset.y());
+}
+
void GrMatrixConvolutionEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {
GrGLMatrixConvolutionEffect::GenKey(*this, caps, b);
@@ -193,49 +219,75 @@
fDomain == s.domain();
}
-// Static function to create a 2D convolution
-sk_sp<GrFragmentProcessor>
-GrMatrixConvolutionEffect::MakeGaussian(GrTexture* texture,
- const SkIRect& bounds,
- const SkISize& kernelSize,
- SkScalar gain,
- SkScalar bias,
- const SkIPoint& kernelOffset,
- GrTextureDomain::Mode tileMode,
- bool convolveAlpha,
- SkScalar sigmaX,
- SkScalar sigmaY) {
- float kernel[MAX_KERNEL_SIZE];
- int width = kernelSize.width();
- int height = kernelSize.height();
+static void fill_in_2D_gaussian_kernel(float* kernel, int width, int height,
+ SkScalar sigmaX, SkScalar sigmaY) {
SkASSERT(width * height <= MAX_KERNEL_SIZE);
+ const float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX)));
+ const float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY)));
+ const int xRadius = width / 2;
+ const int yRadius = height / 2;
+
float sum = 0.0f;
- float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX)));
- float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY)));
- int xRadius = width / 2;
- int yRadius = height / 2;
for (int x = 0; x < width; x++) {
- float xTerm = static_cast<float>(x - xRadius);
- xTerm = xTerm * xTerm * sigmaXDenom;
- for (int y = 0; y < height; y++) {
- float yTerm = static_cast<float>(y - yRadius);
- float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom));
- // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
- // is dropped here, since we renormalize the kernel below.
- kernel[y * width + x] = xyTerm;
- sum += xyTerm;
- }
+ float xTerm = static_cast<float>(x - xRadius);
+ xTerm = xTerm * xTerm * sigmaXDenom;
+ for (int y = 0; y < height; y++) {
+ float yTerm = static_cast<float>(y - yRadius);
+ float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom));
+ // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
+ // is dropped here, since we renormalize the kernel below.
+ kernel[y * width + x] = xyTerm;
+ sum += xyTerm;
+ }
}
// Normalize the kernel
float scale = 1.0f / sum;
for (int i = 0; i < width * height; ++i) {
kernel[i] *= scale;
}
+}
+
+
+// Static function to create a 2D convolution
+sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::MakeGaussian(GrTexture* texture,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha,
+ SkScalar sigmaX,
+ SkScalar sigmaY) {
+ float kernel[MAX_KERNEL_SIZE];
+
+ fill_in_2D_gaussian_kernel(kernel, kernelSize.width(), kernelSize.height(), sigmaX, sigmaY);
+
return sk_sp<GrFragmentProcessor>(
new GrMatrixConvolutionEffect(texture, bounds, kernelSize, kernel, gain, bias,
kernelOffset, tileMode, convolveAlpha));
}
+sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::MakeGaussian(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha,
+ SkScalar sigmaX,
+ SkScalar sigmaY) {
+ float kernel[MAX_KERNEL_SIZE];
+
+ fill_in_2D_gaussian_kernel(kernel, kernelSize.width(), kernelSize.height(), sigmaX, sigmaY);
+
+ return sk_sp<GrFragmentProcessor>(
+ new GrMatrixConvolutionEffect(context, std::move(proxy), bounds, kernelSize, kernel,
+ gain, bias, kernelOffset, tileMode, convolveAlpha));
+}
+
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMatrixConvolutionEffect);
sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::TestCreate(GrProcessorTestData* d) {
@@ -259,7 +311,8 @@
GrTextureDomain::Mode tileMode =
static_cast<GrTextureDomain::Mode>(d->fRandom->nextRangeU(0, 2));
bool convolveAlpha = d->fRandom->nextBool();
- return GrMatrixConvolutionEffect::Make(d->fTextures[texIdx],
+ return GrMatrixConvolutionEffect::Make(d->context(),
+ d->textureProxy(texIdx),
bounds,
kernelSize,
kernel.get(),