aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects
diff options
context:
space:
mode:
authorGravatar Ethan Nicholas <ethannicholas@google.com>2017-10-16 12:35:44 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-16 16:58:41 +0000
commit823994624aa5e805e16833ecd3d748fc769a164d (patch)
tree5066101c7fd3f697bf3d95b3166ad0168dc404d3 /src/effects
parentd982d0579e7681ec512c0ab612f9664b7a235e79 (diff)
converted GrRectBlurEffect to SkSL
Bug: skia: Change-Id: I3a8e16fd2792e6fb5711815d8aad46ae30c2872e Reviewed-on: https://skia-review.googlesource.com/59163 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.cpp6
-rw-r--r--src/effects/GrCircleBlurFragmentProcessor.cpp6
-rw-r--r--src/effects/SkBlurMaskFilter.cpp248
3 files changed, 13 insertions, 247 deletions
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
index e1badf7f21..5ef0221be7 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
@@ -34,6 +34,12 @@ public:
const GrAlphaThresholdFragmentProcessor& _outer =
args.fFp.cast<GrAlphaThresholdFragmentProcessor>();
(void)_outer;
+ auto colorXform = _outer.colorXform();
+ (void)colorXform;
+ auto innerThreshold = _outer.innerThreshold();
+ (void)innerThreshold;
+ auto outerThreshold = _outer.outerThreshold();
+ (void)outerThreshold;
fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get());
fInnerThresholdVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kHalf_GrSLType, kDefault_GrSLPrecision, "innerThreshold");
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index 5a825f49f5..647afb8076 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -263,6 +263,12 @@ public:
const GrCircleBlurFragmentProcessor& _outer =
args.fFp.cast<GrCircleBlurFragmentProcessor>();
(void)_outer;
+ auto circleRect = _outer.circleRect();
+ (void)circleRect;
+ auto textureRadius = _outer.textureRadius();
+ (void)textureRadius;
+ auto solidRadius = _outer.solidRadius();
+ (void)solidRadius;
fCircleDataVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
kDefault_GrSLPrecision, "circleData");
fragBuilder->codeAppendf(
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index ca7de71914..7da42459f4 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -26,6 +26,7 @@
#include "GrShaderCaps.h"
#include "GrStyle.h"
#include "GrTextureProxy.h"
+#include "effects/GrRectBlurEffect.h"
#include "effects/GrSimpleTextureEffect.h"
#include "effects/GrTextureDomain.h"
#include "glsl/GrGLSLFragmentProcessor.h"
@@ -761,253 +762,6 @@ void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
#if SK_SUPPORT_GPU
-class GrGLRectBlurEffect;
-
-class GrRectBlurEffect : public GrFragmentProcessor {
-public:
- ~GrRectBlurEffect() override { }
-
- const char* name() const override { return "RectBlur"; }
-
- static std::unique_ptr<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
- const SkRect& rect, float sigma) {
- int doubleProfileSize = SkScalarCeilToInt(12*sigma);
-
- if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
- // if the blur sigma is too large so the gaussian overlaps the whole
- // rect in either direction, fall back to CPU path for now.
- return nullptr;
- }
-
- sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(resourceProvider, sigma));
- if (!blurProfile) {
- return nullptr;
- }
- // in OpenGL ES, mediump floats have a minimum range of 2^14. If we have coordinates bigger
- // than that, the shader math will end up with infinities and result in the blur effect not
- // working correctly. To avoid this, we switch into highp when the coordinates are too big.
- // As 2^14 is the minimum range but the actual range can be bigger, we might end up
- // switching to highp sooner than strictly necessary, but most devices that have a bigger
- // range for mediump also have mediump being exactly the same as highp (e.g. all non-OpenGL
- // ES devices), and thus incur no additional penalty for the switch.
- static const SkScalar kMAX_BLUR_COORD = SkIntToScalar(16000);
- GrSLPrecision precision;
- if (SkScalarAbs(rect.top()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.left()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.bottom()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.right()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.width()) > kMAX_BLUR_COORD ||
- SkScalarAbs(rect.height()) > kMAX_BLUR_COORD) {
- precision = kHigh_GrSLPrecision;
- } else {
- precision = kDefault_GrSLPrecision;
- }
-
- return std::unique_ptr<GrFragmentProcessor>(
- new GrRectBlurEffect(rect, sigma, std::move(blurProfile), precision));
- }
-
- std::unique_ptr<GrFragmentProcessor> clone() const override {
- return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(
- fRect, fSigma, sk_ref_sp(fBlurProfileSampler.proxy()), fPrecision));
- }
-
- const SkRect& getRect() const { return fRect; }
- float getSigma() const { return fSigma; }
- GrSLPrecision precision() const { return fPrecision; }
-
-private:
- GrRectBlurEffect(const SkRect& rect, float sigma,
- sk_sp<GrTextureProxy> blurProfile, GrSLPrecision fPrecision);
-
- GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
-
- void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
-
- bool onIsEqual(const GrFragmentProcessor&) const override;
-
- static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrResourceProvider*, float sigma);
-
- SkRect fRect;
- float fSigma;
- TextureSampler fBlurProfileSampler;
- GrSLPrecision fPrecision;
-
- GR_DECLARE_FRAGMENT_PROCESSOR_TEST
-
- typedef GrFragmentProcessor INHERITED;
-};
-
-class GrGLRectBlurEffect : public GrGLSLFragmentProcessor {
-public:
- void emitCode(EmitArgs&) override;
-
- static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b);
-
-protected:
- void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
-
-private:
- typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
-
- UniformHandle fProxyRectUniform;
- UniformHandle fProfileSizeUniform;
-
- typedef GrGLSLFragmentProcessor INHERITED;
-};
-
-void OutputRectBlurProfileLookup(GrGLSLFPFragmentBuilder* fragBuilder,
- GrGLSLFragmentProcessor::SamplerHandle sampler,
- const char *output,
- const char *profileSize, const char *loc,
- const char *blurred_width,
- const char *sharp_width) {
- fragBuilder->codeAppendf("half %s;", output);
- fragBuilder->codeAppendf("{");
- fragBuilder->codeAppendf("half coord = ((abs(%s - 0.5 * %s) - 0.5 * %s)) / %s;",
- loc, blurred_width, sharp_width, profileSize);
- fragBuilder->codeAppendf("%s = ", output);
- fragBuilder->appendTextureLookup(sampler, "half2(coord,0.5)");
- fragBuilder->codeAppend(".a;");
- fragBuilder->codeAppendf("}");
-}
-
-
-void GrGLRectBlurEffect::GenKey(const GrProcessor& proc, const GrShaderCaps&,
- GrProcessorKeyBuilder* b) {
- const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>();
-
- b->add32(rbe.precision());
-}
-
-
-void GrGLRectBlurEffect::emitCode(EmitArgs& args) {
- const GrRectBlurEffect& rbe = args.fFp.cast<GrRectBlurEffect>();
-
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
-
- const char *rectName;
- const char *profileSizeName;
-
- const char* floatType = rbe.precision() == kHigh_GrSLPrecision ? "float" : "half";
- fProxyRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- rbe.precision() == kHigh_GrSLPrecision ?
- kFloat4_GrSLType : kHalf4_GrSLType,
- "proxyRect",
- &rectName);
- fProfileSizeUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kHalf_GrSLType,
- "profileSize",
- &profileSizeName);
-
- GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
-
- if (args.fInputColor) {
- fragBuilder->codeAppendf("half4 src=%s;", args.fInputColor);
- } else {
- fragBuilder->codeAppendf("half4 src=half4(1);");
- }
-
- fragBuilder->codeAppendf("%s2 translatedPos = sk_FragCoord.xy - %s.xy;", floatType, rectName);
- fragBuilder->codeAppendf("%s width = %s.z - %s.x;", floatType, rectName, rectName);
- fragBuilder->codeAppendf("%s height = %s.w - %s.y;", floatType, rectName, rectName);
-
- fragBuilder->codeAppendf("%s2 smallDims = half2(width - %s, height - %s);", floatType,
- profileSizeName, profileSizeName);
- fragBuilder->codeAppendf("%s center = 2.0 * floor(%s/2.0 + .25) - 1.0;", floatType,
- profileSizeName);
- fragBuilder->codeAppendf("%s2 wh = smallDims - half2(center,center);", floatType);
-
- OutputRectBlurProfileLookup(fragBuilder, args.fTexSamplers[0], "horiz_lookup", profileSizeName,
- "translatedPos.x", "width", "wh.x");
- OutputRectBlurProfileLookup(fragBuilder, args.fTexSamplers[0], "vert_lookup", profileSizeName,
- "translatedPos.y", "height", "wh.y");
-
- fragBuilder->codeAppendf("half final = horiz_lookup * vert_lookup;");
- fragBuilder->codeAppendf("%s = src * final;", args.fOutputColor);
-}
-
-void GrGLRectBlurEffect::onSetData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& proc) {
- const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>();
- SkRect rect = rbe.getRect();
-
- pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma()));
-}
-
-sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture(
- GrResourceProvider* resourceProvider,
- float sigma) {
- unsigned int profileSize = SkScalarCeilToInt(6*sigma);
-
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
- GrUniqueKey key;
- GrUniqueKey::Builder builder(&key, kDomain, 1);
- builder[0] = profileSize;
- builder.finish();
-
- sk_sp<GrTextureProxy> blurProfile(resourceProvider->findOrCreateProxyByUniqueKey(
- key, kTopLeft_GrSurfaceOrigin));
- if (!blurProfile) {
- GrSurfaceDesc texDesc;
- texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
- texDesc.fWidth = profileSize;
- texDesc.fHeight = 1;
- texDesc.fConfig = kAlpha_8_GrPixelConfig;
-
- std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
-
- blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider,
- texDesc, SkBudgeted::kYes, profile.get(), 0);
- if (!blurProfile) {
- return nullptr;
- }
-
- SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
- resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get());
- }
-
- return blurProfile;
-}
-
-GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma,
- sk_sp<GrTextureProxy> blurProfile,
- GrSLPrecision precision)
- : INHERITED(kGrRectBlurEffect_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
- , fRect(rect)
- , fSigma(sigma)
- , fBlurProfileSampler(std::move(blurProfile))
- , fPrecision(precision) {
- this->addTextureSampler(&fBlurProfileSampler);
-}
-
-void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const {
- GrGLRectBlurEffect::GenKey(*this, caps, b);
-}
-
-GrGLSLFragmentProcessor* GrRectBlurEffect::onCreateGLSLInstance() const {
- return new GrGLRectBlurEffect;
-}
-
-bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
- const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>();
- return this->getSigma() == s.getSigma() && this->getRect() == s.getRect();
-}
-
-GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
-
-#if GR_TEST_UTILS
-std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::TestCreate(GrProcessorTestData* d) {
- float sigma = d->fRandom->nextRangeF(3,8);
- float width = d->fRandom->nextRangeF(200,300);
- float height = d->fRandom->nextRangeF(200,300);
- return GrRectBlurEffect::Make(d->resourceProvider(),
- SkRect::MakeWH(width, height), sigma);
-}
-#endif
-
bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context,
GrRenderTargetContext* renderTargetContext,
GrPaint&& paint,