blob: 51d3d35f95bd7ad2b7f58bb699f56842a47a9b79 [file] [log] [blame]
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**************************************************************************************************
*** This file was autogenerated from GrRRectBlurEffect.fp; do not modify.
**************************************************************************************************/
#ifndef GrRRectBlurEffect_DEFINED
#define GrRRectBlurEffect_DEFINED
#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 "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,
float xformedSigma,
const SkRRect& srcRRect,
const SkRRect& devRRect);
GrRRectBlurEffect(const GrRRectBlurEffect& src);
#ifdef SK_DEBUG
SkString dumpInfo() const override;
#endif
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "RRectBlurEffect"; }
float sigma;
SkRect rect;
float cornerRadius;
private:
GrRRectBlurEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
float sigma,
SkRect rect,
float cornerRadius,
std::unique_ptr<GrFragmentProcessor> ninePatchFP)
: INHERITED(kGrRRectBlurEffect_ClassID,
(OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
: kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, sigma(sigma)
, rect(rect)
, cornerRadius(cornerRadius) {
this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
SkASSERT(ninePatchFP);
this->registerChild(std::move(ninePatchFP), SkSL::SampleUsage::Explicit());
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
typedef GrFragmentProcessor INHERITED;
};
#endif