GrMatrixConvolutionEffect uses child for sampled kernel
Bug: skia:10139
Change-Id: Ic1380cf47c9293a54bf104ccbb3ca3222e704276
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/296127
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Adlai Holler <adlai@google.com>
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index ed96861..1ad920e 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -42,9 +42,12 @@
typedef GrGLSLFragmentProcessor INHERITED;
};
-GrMatrixConvolutionEffect::KernelWrapper GrMatrixConvolutionEffect::KernelWrapper::Make(
- GrRecordingContext* context, SkISize size, const GrCaps& caps, const SkScalar* values) {
- if (nullptr == context || nullptr == values || size.isEmpty()) {
+GrMatrixConvolutionEffect::KernelWrapper::MakeResult
+GrMatrixConvolutionEffect::KernelWrapper::Make(GrRecordingContext* context,
+ SkISize size,
+ const GrCaps& caps,
+ const SkScalar* values) {
+ if (!context || !values || size.isEmpty()) {
return {};
}
const int length = size.area();
@@ -54,10 +57,10 @@
for (int i = 0; i < length; i++) {
result.fArray[i] = SkScalarToFloat(values[i]);
}
- return result;
+ return {result, nullptr};
}
- ScalableSampler& scalableSampler = result.fScalableSampler;
+ BiasAndGain& scalableSampler = result.fBiasAndGain;
bool useA16 =
context->defaultBackendFormat(kA16_float_SkColorType, GrRenderable::kNo).isValid();
SkScalar min = values[0];
@@ -108,8 +111,7 @@
view = {std::move(cachedKernel), kTopLeft_GrSurfaceOrigin, swizzle};
} else {
SkBitmap bm;
- auto info = SkImageInfo::Make({(int)GrNextPow2(length), 1}, colorType,
- kPremul_SkAlphaType, nullptr);
+ auto info = SkImageInfo::Make({length, 1}, colorType, kPremul_SkAlphaType, nullptr);
if (!bm.tryAllocPixels(info)) {
return {};
}
@@ -131,23 +133,23 @@
proxyProvider->assignUniqueKeyToProxy(key, view.asTextureProxy());
}
}
- scalableSampler.fSampler = { std::move(view) };
- return result;
+ auto kernelFP = GrTextureEffect::Make(std::move(view), kUnknown_SkAlphaType);
+ return {result, std::move(kernelFP)};
}
bool GrMatrixConvolutionEffect::KernelWrapper::operator==(const KernelWrapper& k) const {
if (fSize != k.fSize) {
return false;
} else if (this->isSampled()) {
- return fScalableSampler == k.fScalableSampler;
+ return fBiasAndGain == k.fBiasAndGain;
} else {
return std::equal(fArray.begin(), fArray.begin() + fSize.area(), k.fArray.begin());
}
}
-bool GrMatrixConvolutionEffect::KernelWrapper::ScalableSampler::operator==(
- const ScalableSampler& k) const {
- return fSampler == k.fSampler && fGain == k.fGain && fBias == k.fBias;
+bool GrMatrixConvolutionEffect::KernelWrapper::BiasAndGain::operator==(
+ const BiasAndGain& k) const {
+ return fGain == k.fGain && fBias == k.fBias;
}
// For sampled kernels, emit a for loop that does all the kernel accumulation.
@@ -162,7 +164,6 @@
int kernelArea = kernelWidth * kernelHeight;
if (mce.kernelIsSampled()) {
- fragBuilder->codeAppendf("half2 kernelCoord = half2(0, 0);");
fragBuilder->codeAppendf("for (int i = 0; i < %d; ++i)", (int)kernelArea);
}
@@ -172,13 +173,11 @@
fragBuilder->codeAppend("half2 sourceOffset;");
if (mce.kernelIsSampled()) {
const char* kernelBias = uniformHandler->getUniformCStr(fKernelBiasUni);
- fragBuilder->codeAppend("k = ");
- fragBuilder->appendTextureLookup(args.fTexSamplers[0], "kernelCoord");
- fragBuilder->codeAppendf(".w + %s;", kernelBias);
+ SkString kernelCoord = SkStringPrintf("float2(float(i) + 0.5, 0.5)");
+ SkString kernelSample = this->invokeChild(1, args, kernelCoord.c_str());
+ fragBuilder->codeAppendf("k = %s.w + %s;", kernelSample.c_str(), kernelBias);
fragBuilder->codeAppendf("sourceOffset.y = floor(i / %d);", kernelWidth);
fragBuilder->codeAppendf("sourceOffset.x = i - sourceOffset.y * %d;", kernelWidth);
- float kernelStride = 1.0f / (float)GrNextPow2(kernelArea);
- fragBuilder->codeAppendf("kernelCoord.x += %f;", kernelStride);
} else {
fragBuilder->codeAppendf("sourceOffset = half2(%d, %d);", loc.x(), loc.y());
int offset = loc.y() * kernelWidth + loc.x();
@@ -282,7 +281,8 @@
}
GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(std::unique_ptr<GrFragmentProcessor> child,
- KernelWrapper kernel,
+ const KernelWrapper& kernel,
+ std::unique_ptr<GrFragmentProcessor> kernelFP,
SkScalar gain,
SkScalar bias,
const SkIPoint& kernelOffset,
@@ -290,14 +290,15 @@
// To advertise either the modulation or opaqueness optimizations we'd have to examine the
// parameters.
: INHERITED(kGrMatrixConvolutionEffect_ClassID, kNone_OptimizationFlags)
- , fKernel(std::move(kernel))
+ , fKernel(kernel)
, fGain(SkScalarToFloat(gain))
, fBias(SkScalarToFloat(bias) / 255.0f)
, fConvolveAlpha(convolveAlpha) {
child->setSampledWithExplicitCoords();
this->registerChildProcessor(std::move(child));
- if (fKernel.isSampled()) {
- this->setTextureSamplerCnt(1);
+ if (kernelFP) {
+ kernelFP->setSampledWithExplicitCoords();
+ this->registerChildProcessor(std::move(kernelFP));
}
fKernelOffset = {static_cast<float>(kernelOffset.x()),
static_cast<float>(kernelOffset.y())};
@@ -315,7 +316,9 @@
child->setSampledWithExplicitCoords();
this->registerChildProcessor(std::move(child));
if (fKernel.isSampled()) {
- this->setTextureSamplerCnt(1);
+ child = that.childProcessor(1).clone();
+ child->setSampledWithExplicitCoords();
+ this->registerChildProcessor(std::move(child));
}
this->addCoordTransform(&fCoordTransform);
}
@@ -342,11 +345,6 @@
fConvolveAlpha == s.convolveAlpha();
}
-const GrFragmentProcessor::TextureSampler& GrMatrixConvolutionEffect::onTextureSampler(
- int index) const {
- return IthTextureSampler(index, fKernel.scalableSampler().fSampler);
-}
-
static void fill_in_1D_gaussian_kernel_with_stride(float* kernel, int size, int stride,
float twoSigmaSqrd) {
SkASSERT(!SkScalarNearlyZero(twoSigmaSqrd, SK_ScalarNearlyZero));
@@ -437,15 +435,16 @@
GrSamplerState::WrapMode wm,
bool convolveAlpha,
const GrCaps& caps) {
- auto kw = KernelWrapper::Make(context, kernelSize, caps, kernel);
- if (!kw.isValid()) {
+ auto [kernelWrapper, kernelFP] = KernelWrapper::Make(context, kernelSize, caps, kernel);
+ if (!kernelWrapper.isValid()) {
return nullptr;
}
GrSamplerState sampler(wm, GrSamplerState::Filter::kNearest);
auto child = GrTextureEffect::MakeSubset(std::move(srcView), kPremul_SkAlphaType, SkMatrix::I(),
sampler, SkRect::Make(srcBounds), caps);
- return std::unique_ptr<GrFragmentProcessor>(new GrMatrixConvolutionEffect(
- std::move(child), std::move(kw), gain, bias, kernelOffset, convolveAlpha));
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrMatrixConvolutionEffect(std::move(child), kernelWrapper, std::move(kernelFP),
+ gain, bias, kernelOffset, convolveAlpha));
}
std::unique_ptr<GrFragmentProcessor> GrMatrixConvolutionEffect::MakeGaussian(