Out-line GrRRectBlurEffect find_or_create_rrect_blur_mask_fp
I'm going to make this function even more complex (with a thread-safe shared uniquely-keyed proxy cache) so remove it from the header. Change-Id: I810ed095729ac30862a8713624e6440380b1128d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/312862 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
6e727832b5
commit
a1c4f1ad51
@ -14,6 +14,26 @@ layout(ctype=SkRect) uniform float4 proxyRect;
|
||||
uniform half blurRadius;
|
||||
|
||||
@header {
|
||||
#include "include/core/SkRect.h"
|
||||
class GrRecordingContext;
|
||||
class SkRRect;
|
||||
}
|
||||
|
||||
@optimizationFlags {
|
||||
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
|
||||
kCompatibleWithCoverageAsAlpha_OptimizationFlag
|
||||
}
|
||||
|
||||
@make {
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
GrRecordingContext* context,
|
||||
float sigma,
|
||||
float xformedSigma,
|
||||
const SkRRect& srcRRect,
|
||||
const SkRRect& devRRect);
|
||||
}
|
||||
|
||||
@cpp {
|
||||
#include "include/gpu/GrRecordingContext.h"
|
||||
#include "src/core/SkBlurPriv.h"
|
||||
#include "src/core/SkGpuBlurUtils.h"
|
||||
@ -25,9 +45,7 @@ uniform half blurRadius;
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrStyle.h"
|
||||
#include "src/gpu/effects/GrTextureEffect.h"
|
||||
}
|
||||
|
||||
@class {
|
||||
static std::unique_ptr<GrFragmentProcessor> find_or_create_rrect_blur_mask_fp(
|
||||
GrRecordingContext* context,
|
||||
const SkRRect& rrectToDraw,
|
||||
@ -105,23 +123,7 @@ uniform half blurRadius;
|
||||
proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy());
|
||||
return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m);
|
||||
}
|
||||
}
|
||||
|
||||
@optimizationFlags {
|
||||
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
|
||||
kCompatibleWithCoverageAsAlpha_OptimizationFlag
|
||||
}
|
||||
|
||||
@make {
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
GrRecordingContext* context,
|
||||
float sigma,
|
||||
float xformedSigma,
|
||||
const SkRRect& srcRRect,
|
||||
const SkRRect& devRRect);
|
||||
}
|
||||
|
||||
@cpp {
|
||||
std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(
|
||||
std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
GrRecordingContext* context,
|
||||
|
@ -10,6 +10,95 @@
|
||||
**************************************************************************************************/
|
||||
#include "GrRRectBlurEffect.h"
|
||||
|
||||
#include "include/gpu/GrRecordingContext.h"
|
||||
#include "src/core/SkBlurPriv.h"
|
||||
#include "src/core/SkGpuBlurUtils.h"
|
||||
#include "src/core/SkRRectPriv.h"
|
||||
#include "src/gpu/GrCaps.h"
|
||||
#include "src/gpu/GrPaint.h"
|
||||
#include "src/gpu/GrProxyProvider.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrStyle.h"
|
||||
#include "src/gpu/effects/GrTextureEffect.h"
|
||||
|
||||
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");
|
||||
builder[0] = SkScalarCeilToInt(xformedSigma - 1 / 6.0f);
|
||||
|
||||
int index = 1;
|
||||
for (auto c : {SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner,
|
||||
SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner}) {
|
||||
SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) && SkScalarIsInt(rrectToDraw.radii(c).fY));
|
||||
builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX);
|
||||
builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY);
|
||||
}
|
||||
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 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 nullptr;
|
||||
}
|
||||
|
||||
GrPaint paint;
|
||||
|
||||
rtc->clear(SK_PMColor4fTRANSPARENT);
|
||||
rtc->drawRRect(nullptr, std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
|
||||
GrStyle::SimpleFill());
|
||||
|
||||
GrSurfaceProxyView srcView = rtc->readSurfaceView();
|
||||
if (!srcView) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(srcView.asTextureProxy());
|
||||
auto rtc2 = SkGpuBlurUtils::GaussianBlur(context,
|
||||
std::move(srcView),
|
||||
rtc->colorInfo().colorType(),
|
||||
rtc->colorInfo().alphaType(),
|
||||
nullptr,
|
||||
SkIRect::MakeSize(dimensions),
|
||||
SkIRect::MakeSize(dimensions),
|
||||
xformedSigma,
|
||||
xformedSigma,
|
||||
SkTileMode::kClamp,
|
||||
SkBackingFit::kExact);
|
||||
if (!rtc2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView mask = rtc2->readSurfaceView();
|
||||
if (!mask) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(mask.asTextureProxy());
|
||||
SkASSERT(mask.origin() == kMaskOrigin);
|
||||
proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy());
|
||||
return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m);
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(
|
||||
std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
GrRecordingContext* context,
|
||||
@ -95,18 +184,18 @@ half2 texCoord = translatedFragPos / proxyDims;)SkSL",
|
||||
args.fUniformHandler->getUniformCStr(proxyRectVar),
|
||||
args.fUniformHandler->getUniformCStr(blurRadiusVar),
|
||||
args.fUniformHandler->getUniformCStr(cornerRadiusVar));
|
||||
SkString _sample9554 = this->invokeChild(0, args);
|
||||
SkString _sample9630 = this->invokeChild(0, args);
|
||||
fragBuilder->codeAppendf(
|
||||
R"SkSL(
|
||||
half4 inputColor = %s;)SkSL",
|
||||
_sample9554.c_str());
|
||||
SkString _coords9602("float2(texCoord)");
|
||||
SkString _sample9602 = this->invokeChild(1, args, _coords9602.c_str());
|
||||
_sample9630.c_str());
|
||||
SkString _coords9678("float2(texCoord)");
|
||||
SkString _sample9678 = this->invokeChild(1, args, _coords9678.c_str());
|
||||
fragBuilder->codeAppendf(
|
||||
R"SkSL(
|
||||
%s = inputColor * %s;
|
||||
)SkSL",
|
||||
args.fOutputColor, _sample9602.c_str());
|
||||
args.fOutputColor, _sample9678.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -14,100 +14,14 @@
|
||||
#include "include/core/SkM44.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include "include/gpu/GrRecordingContext.h"
|
||||
#include "src/core/SkBlurPriv.h"
|
||||
#include "src/core/SkGpuBlurUtils.h"
|
||||
#include "src/core/SkRRectPriv.h"
|
||||
#include "src/gpu/GrCaps.h"
|
||||
#include "src/gpu/GrPaint.h"
|
||||
#include "src/gpu/GrProxyProvider.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/gpu/GrRenderTargetContext.h"
|
||||
#include "src/gpu/GrStyle.h"
|
||||
#include "src/gpu/effects/GrTextureEffect.h"
|
||||
#include "include/core/SkRect.h"
|
||||
class GrRecordingContext;
|
||||
class SkRRect;
|
||||
|
||||
#include "src/gpu/GrFragmentProcessor.h"
|
||||
|
||||
class GrRRectBlurEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
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");
|
||||
builder[0] = SkScalarCeilToInt(xformedSigma - 1 / 6.0f);
|
||||
|
||||
int index = 1;
|
||||
for (auto c : {SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner,
|
||||
SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner}) {
|
||||
SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) &&
|
||||
SkScalarIsInt(rrectToDraw.radii(c).fY));
|
||||
builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX);
|
||||
builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY);
|
||||
}
|
||||
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 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 nullptr;
|
||||
}
|
||||
|
||||
GrPaint paint;
|
||||
|
||||
rtc->clear(SK_PMColor4fTRANSPARENT);
|
||||
rtc->drawRRect(nullptr, std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
|
||||
GrStyle::SimpleFill());
|
||||
|
||||
GrSurfaceProxyView srcView = rtc->readSurfaceView();
|
||||
if (!srcView) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(srcView.asTextureProxy());
|
||||
auto rtc2 = SkGpuBlurUtils::GaussianBlur(context,
|
||||
std::move(srcView),
|
||||
rtc->colorInfo().colorType(),
|
||||
rtc->colorInfo().alphaType(),
|
||||
nullptr,
|
||||
SkIRect::MakeSize(dimensions),
|
||||
SkIRect::MakeSize(dimensions),
|
||||
xformedSigma,
|
||||
xformedSigma,
|
||||
SkTileMode::kClamp,
|
||||
SkBackingFit::kExact);
|
||||
if (!rtc2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView mask = rtc2->readSurfaceView();
|
||||
if (!mask) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(mask.asTextureProxy());
|
||||
SkASSERT(mask.origin() == kMaskOrigin);
|
||||
proxyProvider->assignUniqueKeyToProxy(key, mask.asTextureProxy());
|
||||
return GrTextureEffect::Make(std::move(mask), kPremul_SkAlphaType, m);
|
||||
}
|
||||
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||
GrRecordingContext* context,
|
||||
float sigma,
|
||||
|
Loading…
Reference in New Issue
Block a user