GrRRectBlurEffect uses child for nine patch
Bug: skia:10139 Change-Id: Ic306775bb8d1f5d8b29cc38c116d0f8c3e0d55a2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297193 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
8c662a7d6e
commit
71f6cfd654
@ -9,7 +9,7 @@ in fragmentProcessor? inputFP;
|
||||
in float sigma;
|
||||
layout(ctype=SkRect) in float4 rect;
|
||||
in uniform half cornerRadius;
|
||||
in uniform sampler2D ninePatchSampler;
|
||||
in fragmentProcessor ninePatchFP;
|
||||
layout(ctype=SkRect) uniform float4 proxyRect;
|
||||
uniform half blurRadius;
|
||||
|
||||
@ -25,13 +25,15 @@ uniform half blurRadius;
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrStyle.h"
|
||||
#include "src/gpu/effects/GrTextureEffect.h"
|
||||
}
|
||||
|
||||
@class {
|
||||
static GrSurfaceProxyView find_or_create_rrect_blur_mask(GrRecordingContext* context,
|
||||
const SkRRect& rrectToDraw,
|
||||
const SkISize& dimensions,
|
||||
float xformedSigma) {
|
||||
static std::unique_ptr<GrFragmentProcessor> find_or_create_rrect_blur_mask_fp(
|
||||
GrRecordingContext* context,
|
||||
const SkRRect& rrectToDraw,
|
||||
const SkISize& dimensions,
|
||||
float xformedSigma) {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey key;
|
||||
GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask");
|
||||
@ -47,19 +49,26 @@ uniform half blurRadius;
|
||||
}
|
||||
builder.finish();
|
||||
|
||||
// It seems like we could omit this matrix and modify the shader code to not normalize
|
||||
// the coords used to sample the texture effect. However, the "proxyDims" value in the
|
||||
// shader is not always the actual the proxy dimensions. This is because 'dimensions' here
|
||||
// was computed using integer corner radii as determined in
|
||||
// SkComputeBlurredRRectParams whereas the shader code uses the float radius to compute
|
||||
// 'proxyDims'. Why it draws correctly with these unequal values is a mystery for the ages.
|
||||
auto m = SkMatrix::Scale(dimensions.width(), dimensions.height());
|
||||
static constexpr auto kMaskOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
|
||||
|
||||
if (auto view = proxyProvider->findCachedProxyWithColorTypeFallback(
|
||||
key, kMaskOrigin, GrColorType::kAlpha_8, 1)) {
|
||||
return view;
|
||||
return GrTextureEffect::Make(std::move(view), kPremul_SkAlphaType, m);
|
||||
}
|
||||
|
||||
auto rtc = GrRenderTargetContext::MakeWithFallback(
|
||||
context, GrColorType::kAlpha_8, nullptr, SkBackingFit::kExact, dimensions, 1,
|
||||
GrMipMapped::kNo, GrProtected::kNo, kMaskOrigin);
|
||||
if (!rtc) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrPaint paint;
|
||||
@ -70,7 +79,7 @@ uniform half blurRadius;
|
||||
|
||||
GrSurfaceProxyView srcView = rtc->readSurfaceView();
|
||||
if (!srcView) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(srcView.asTextureProxy());
|
||||
auto rtc2 = SkGpuBlurUtils::GaussianBlur(context,
|
||||
@ -85,18 +94,17 @@ uniform half blurRadius;
|
||||
SkTileMode::kClamp,
|
||||
SkBackingFit::kExact);
|
||||
if (!rtc2) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView mask = rtc2->readSurfaceView();
|
||||
if (!mask) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(mask.asTextureProxy());
|
||||
SkASSERT(mask.origin() == kMaskOrigin);
|
||||
proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy());
|
||||
|
||||
return mask;
|
||||
return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m);
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,15 +158,15 @@ uniform half blurRadius;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView mask = find_or_create_rrect_blur_mask(context, rrectToDraw, dimensions,
|
||||
xformedSigma);
|
||||
if (!mask) {
|
||||
std::unique_ptr<GrFragmentProcessor> maskFP = find_or_create_rrect_blur_mask_fp(
|
||||
context, rrectToDraw, dimensions, xformedSigma);
|
||||
if (!maskFP) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::unique_ptr<GrFragmentProcessor>(
|
||||
new GrRRectBlurEffect(std::move(inputFP), xformedSigma, devRRect.getBounds(),
|
||||
SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(mask)));
|
||||
SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(maskFP)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,7 +216,7 @@ void main() {
|
||||
half2 texCoord = translatedFragPos / proxyDims;
|
||||
|
||||
half4 inputColor = sample(inputFP, sk_InColor);
|
||||
sk_OutColor = inputColor * sample(ninePatchSampler, texCoord);
|
||||
sk_OutColor = inputColor * sample(ninePatchFP, texCoord);
|
||||
}
|
||||
|
||||
@setData(pdman) {
|
||||
|
@ -41,15 +41,15 @@ std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView mask =
|
||||
find_or_create_rrect_blur_mask(context, rrectToDraw, dimensions, xformedSigma);
|
||||
if (!mask) {
|
||||
std::unique_ptr<GrFragmentProcessor> maskFP =
|
||||
find_or_create_rrect_blur_mask_fp(context, rrectToDraw, dimensions, xformedSigma);
|
||||
if (!maskFP) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::unique_ptr<GrFragmentProcessor>(
|
||||
new GrRRectBlurEffect(std::move(inputFP), xformedSigma, devRRect.getBounds(),
|
||||
SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(mask)));
|
||||
SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(maskFP)));
|
||||
}
|
||||
#include "src/gpu/GrTexture.h"
|
||||
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
|
||||
@ -91,21 +91,19 @@ public:
|
||||
args.fUniformHandler->getUniformCStr(blurRadiusVar),
|
||||
args.fUniformHandler->getUniformCStr(cornerRadiusVar));
|
||||
fragBuilder->codeAppendf("nslatedFragPos / proxyDims;");
|
||||
SkString _input8931 = SkStringPrintf("%s", args.fInputColor);
|
||||
SkString _sample8931;
|
||||
SkString _input9604 = SkStringPrintf("%s", args.fInputColor);
|
||||
SkString _sample9604;
|
||||
if (_outer.inputFP_index >= 0) {
|
||||
_sample8931 = this->invokeChild(_outer.inputFP_index, _input8931.c_str(), args);
|
||||
_sample9604 = this->invokeChild(_outer.inputFP_index, _input9604.c_str(), args);
|
||||
} else {
|
||||
_sample8931 = _input8931;
|
||||
_sample9604 = _input9604;
|
||||
}
|
||||
fragBuilder->codeAppendf(
|
||||
"\nhalf4 inputColor = %s;\n%s = inputColor * sample(%s, float2(texCoord)).%s;\n",
|
||||
_sample8931.c_str(), args.fOutputColor,
|
||||
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
|
||||
fragBuilder->getProgramBuilder()
|
||||
->samplerSwizzle(args.fTexSamplers[0])
|
||||
.asString()
|
||||
.c_str());
|
||||
fragBuilder->codeAppendf("\nhalf4 inputColor = %s;", _sample9604.c_str());
|
||||
SkString _sample9664;
|
||||
SkString _coords9664("float2(texCoord)");
|
||||
_sample9664 = this->invokeChild(_outer.ninePatchFP_index, args, _coords9664.c_str());
|
||||
fragBuilder->codeAppendf("\n%s = inputColor * %s;\n", args.fOutputColor,
|
||||
_sample9664.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
@ -119,9 +117,6 @@ private:
|
||||
(void)rect;
|
||||
UniformHandle& cornerRadius = cornerRadiusVar;
|
||||
(void)cornerRadius;
|
||||
const GrSurfaceProxyView& ninePatchSamplerView = _outer.textureSampler(0).view();
|
||||
GrTexture& ninePatchSampler = *ninePatchSamplerView.proxy()->peekTexture();
|
||||
(void)ninePatchSampler;
|
||||
UniformHandle& proxyRect = proxyRectVar;
|
||||
(void)proxyRect;
|
||||
UniformHandle& blurRadius = blurRadiusVar;
|
||||
@ -149,26 +144,24 @@ bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
||||
if (sigma != that.sigma) return false;
|
||||
if (rect != that.rect) return false;
|
||||
if (cornerRadius != that.cornerRadius) return false;
|
||||
if (ninePatchSampler != that.ninePatchSampler) return false;
|
||||
return true;
|
||||
}
|
||||
GrRRectBlurEffect::GrRRectBlurEffect(const GrRRectBlurEffect& src)
|
||||
: INHERITED(kGrRRectBlurEffect_ClassID, src.optimizationFlags())
|
||||
, sigma(src.sigma)
|
||||
, rect(src.rect)
|
||||
, cornerRadius(src.cornerRadius)
|
||||
, ninePatchSampler(src.ninePatchSampler) {
|
||||
, cornerRadius(src.cornerRadius) {
|
||||
if (src.inputFP_index >= 0) {
|
||||
inputFP_index = this->cloneAndRegisterChildProcessor(src.childProcessor(src.inputFP_index));
|
||||
}
|
||||
this->setTextureSamplerCnt(1);
|
||||
{
|
||||
ninePatchFP_index =
|
||||
this->cloneAndRegisterChildProcessor(src.childProcessor(src.ninePatchFP_index));
|
||||
}
|
||||
}
|
||||
std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::clone() const {
|
||||
return std::unique_ptr<GrFragmentProcessor>(new GrRRectBlurEffect(*this));
|
||||
}
|
||||
const GrFragmentProcessor::TextureSampler& GrRRectBlurEffect::onTextureSampler(int index) const {
|
||||
return IthTextureSampler(index, ninePatchSampler);
|
||||
}
|
||||
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect);
|
||||
#if GR_TEST_UTILS
|
||||
std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d) {
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "src/gpu/GrProxyProvider.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/effects/GrTextureEffect.h"
|
||||
#include "src/gpu/GrStyle.h"
|
||||
|
||||
#include "src/gpu/GrCoordTransform.h"
|
||||
@ -31,10 +32,11 @@
|
||||
|
||||
class GrRRectBlurEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
static GrSurfaceProxyView find_or_create_rrect_blur_mask(GrRecordingContext* context,
|
||||
const SkRRect& rrectToDraw,
|
||||
const SkISize& dimensions,
|
||||
float xformedSigma) {
|
||||
static std::unique_ptr<GrFragmentProcessor> find_or_create_rrect_blur_mask_fp(
|
||||
GrRecordingContext* context,
|
||||
const SkRRect& rrectToDraw,
|
||||
const SkISize& dimensions,
|
||||
float xformedSigma) {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey key;
|
||||
GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask");
|
||||
@ -50,19 +52,26 @@ public:
|
||||
}
|
||||
builder.finish();
|
||||
|
||||
// It seems like we could omit this matrix and modify the shader code to not normalize
|
||||
// the coords used to sample the texture effect. However, the "proxyDims" value in the
|
||||
// shader is not always the actual the proxy dimensions. This is because 'dimensions' here
|
||||
// was computed using integer corner radii as determined in
|
||||
// SkComputeBlurredRRectParams whereas the shader code uses the float radius to compute
|
||||
// 'proxyDims'. Why it draws correctly with these unequal values is a mystery for the ages.
|
||||
auto m = SkMatrix::Scale(dimensions.width(), dimensions.height());
|
||||
static constexpr auto kMaskOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
|
||||
|
||||
if (auto view = proxyProvider->findCachedProxyWithColorTypeFallback(
|
||||
key, kMaskOrigin, GrColorType::kAlpha_8, 1)) {
|
||||
return view;
|
||||
return GrTextureEffect::Make(std::move(view), kPremul_SkAlphaType, m);
|
||||
}
|
||||
|
||||
auto rtc = GrRenderTargetContext::MakeWithFallback(
|
||||
context, GrColorType::kAlpha_8, nullptr, SkBackingFit::kExact, dimensions, 1,
|
||||
GrMipMapped::kNo, GrProtected::kNo, kMaskOrigin);
|
||||
if (!rtc) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrPaint paint;
|
||||
@ -73,7 +82,7 @@ public:
|
||||
|
||||
GrSurfaceProxyView srcView = rtc->readSurfaceView();
|
||||
if (!srcView) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(srcView.asTextureProxy());
|
||||
auto rtc2 = SkGpuBlurUtils::GaussianBlur(context,
|
||||
@ -88,18 +97,17 @@ public:
|
||||
SkTileMode::kClamp,
|
||||
SkBackingFit::kExact);
|
||||
if (!rtc2) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView mask = rtc2->readSurfaceView();
|
||||
if (!mask) {
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(mask.asTextureProxy());
|
||||
SkASSERT(mask.origin() == kMaskOrigin);
|
||||
proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy());
|
||||
|
||||
return mask;
|
||||
return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m);
|
||||
}
|
||||
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
@ -115,31 +123,31 @@ public:
|
||||
float sigma;
|
||||
SkRect rect;
|
||||
float cornerRadius;
|
||||
TextureSampler ninePatchSampler;
|
||||
int ninePatchFP_index = -1;
|
||||
|
||||
private:
|
||||
GrRRectBlurEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
float sigma,
|
||||
SkRect rect,
|
||||
float cornerRadius,
|
||||
GrSurfaceProxyView ninePatchSampler)
|
||||
std::unique_ptr<GrFragmentProcessor> ninePatchFP)
|
||||
: INHERITED(kGrRRectBlurEffect_ClassID,
|
||||
(OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
|
||||
: kAll_OptimizationFlags) &
|
||||
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
|
||||
, sigma(sigma)
|
||||
, rect(rect)
|
||||
, cornerRadius(cornerRadius)
|
||||
, ninePatchSampler(std::move(ninePatchSampler)) {
|
||||
, cornerRadius(cornerRadius) {
|
||||
if (inputFP) {
|
||||
inputFP_index = this->registerChildProcessor(std::move(inputFP));
|
||||
}
|
||||
this->setTextureSamplerCnt(1);
|
||||
SkASSERT(ninePatchFP);
|
||||
ninePatchFP->setSampledWithExplicitCoords();
|
||||
ninePatchFP_index = this->registerChildProcessor(std::move(ninePatchFP));
|
||||
}
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
|
||||
bool onIsEqual(const GrFragmentProcessor&) const override;
|
||||
const TextureSampler& onTextureSampler(int) const override;
|
||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user