From f7142e71d7c0a7d8406679e207ff766085499d2e Mon Sep 17 00:00:00 2001 From: robertphillips Date: Mon, 18 Apr 2016 07:20:05 -0700 Subject: [PATCH] Split AlphaThresholdEffect out into its own file Mainly mechanical although I did: convert Create method to sk_sp Make version rm extra '\t's and '\n's in emitCode TBR=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1893193002 Review URL: https://codereview.chromium.org/1893193002 --- gyp/effects.gypi | 2 + include/effects/SkAlphaThresholdFilter.h | 3 +- .../GrAlphaThresholdFragmentProcessor.cpp | 175 +++++++++++++++ .../GrAlphaThresholdFragmentProcessor.h | 61 +++++ src/effects/SkAlphaThresholdFilter.cpp | 208 +----------------- tests/FlattenableFactoryToName.cpp | 1 + 6 files changed, 246 insertions(+), 204 deletions(-) create mode 100644 src/effects/GrAlphaThresholdFragmentProcessor.cpp create mode 100644 src/effects/GrAlphaThresholdFragmentProcessor.h diff --git a/gyp/effects.gypi b/gyp/effects.gypi index 24bfaf60ad..0106f84e2e 100644 --- a/gyp/effects.gypi +++ b/gyp/effects.gypi @@ -13,6 +13,8 @@ 'sources': [ '<(skia_src_path)/effects/GrCircleBlurFragmentProcessor.cpp', '<(skia_src_path)/effects/GrCircleBlurFragmentProcessor.h', + '<(skia_src_path)/effects/GrAlphaThresholdFragmentProcessor.cpp', + '<(skia_src_path)/effects/GrAlphaThresholdFragmentProcessor.h', '<(skia_src_path)/effects/Sk1DPathEffect.cpp', '<(skia_src_path)/effects/Sk2DPathEffect.cpp', diff --git a/include/effects/SkAlphaThresholdFilter.h b/include/effects/SkAlphaThresholdFilter.h index a125b3c501..18b760fc9f 100644 --- a/include/effects/SkAlphaThresholdFilter.h +++ b/include/effects/SkAlphaThresholdFilter.h @@ -9,7 +9,8 @@ #define SkAlphaThresholdFilter_DEFINED #include "SkImageFilter.h" -#include "SkRegion.h" + +class SkRegion; class SK_API SkAlphaThresholdFilter { public: diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp new file mode 100644 index 0000000000..143798990f --- /dev/null +++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp @@ -0,0 +1,175 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrAlphaThresholdFragmentProcessor.h" + +#if SK_SUPPORT_GPU + +#include "GrInvariantOutput.h" +#include "GrTextureAccess.h" + +#include "glsl/GrGLSLFragmentProcessor.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLUniformHandler.h" + +sk_sp GrAlphaThresholdFragmentProcessor::Make(GrTexture* texture, + GrTexture* maskTexture, + float innerThreshold, + float outerThreshold, + const SkIRect& bounds) { + return sk_sp(new GrAlphaThresholdFragmentProcessor( + texture, maskTexture, + innerThreshold, outerThreshold, + bounds)); +} + +static SkMatrix make_div_and_translate_matrix(GrTexture* texture, int x, int y) { + SkMatrix matrix = GrCoordTransform::MakeDivByTextureWHMatrix(texture); + matrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y)); + return matrix; +} + +GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(GrTexture* texture, + GrTexture* maskTexture, + float innerThreshold, + float outerThreshold, + const SkIRect& bounds) + : fInnerThreshold(innerThreshold) + , fOuterThreshold(outerThreshold) + , fImageCoordTransform(kLocal_GrCoordSet, + GrCoordTransform::MakeDivByTextureWHMatrix(texture), texture, + GrTextureParams::kNone_FilterMode) + , fImageTextureAccess(texture) + , fMaskCoordTransform(kLocal_GrCoordSet, + make_div_and_translate_matrix(maskTexture, -bounds.x(), -bounds.y()), + maskTexture, + GrTextureParams::kNone_FilterMode) + , fMaskTextureAccess(maskTexture) { + this->initClassID(); + this->addCoordTransform(&fImageCoordTransform); + this->addTextureAccess(&fImageTextureAccess); + this->addCoordTransform(&fMaskCoordTransform); + this->addTextureAccess(&fMaskTextureAccess); +} + +bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& sBase) const { + const GrAlphaThresholdFragmentProcessor& s = sBase.cast(); + return (this->fInnerThreshold == s.fInnerThreshold && + this->fOuterThreshold == s.fOuterThreshold); +} + +void GrAlphaThresholdFragmentProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const { + if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) { + inout->mulByUnknownSingleComponent(); + } else if (GrPixelConfigIsOpaque(this->texture(0)->config()) && fOuterThreshold >= 1.f) { + inout->mulByUnknownOpaqueFourComponents(); + } else { + inout->mulByUnknownFourComponents(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +class GrGLAlphaThresholdFragmentProcessor : public GrGLSLFragmentProcessor { +public: + void emitCode(EmitArgs&) override; + +protected: + void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; + +private: + GrGLSLProgramDataManager::UniformHandle fInnerThresholdVar; + GrGLSLProgramDataManager::UniformHandle fOuterThresholdVar; + + typedef GrGLSLFragmentProcessor INHERITED; +}; + +void GrGLAlphaThresholdFragmentProcessor::emitCode(EmitArgs& args) { + GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; + fInnerThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag, + kFloat_GrSLType, kDefault_GrSLPrecision, + "inner_threshold"); + fOuterThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag, + kFloat_GrSLType, kDefault_GrSLPrecision, + "outer_threshold"); + + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0); + SkString maskCoords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1); + + fragBuilder->codeAppendf("vec2 coord = %s;", coords2D.c_str()); + fragBuilder->codeAppendf("vec2 mask_coord = %s;", maskCoords2D.c_str()); + fragBuilder->codeAppend("vec4 input_color = "); + fragBuilder->appendTextureLookup(args.fTexSamplers[0], "coord"); + fragBuilder->codeAppend(";"); + fragBuilder->codeAppend("vec4 mask_color = "); + fragBuilder->appendTextureLookup(args.fTexSamplers[1], "mask_coord"); + fragBuilder->codeAppend(";"); + + fragBuilder->codeAppendf("float inner_thresh = %s;", + uniformHandler->getUniformCStr(fInnerThresholdVar)); + fragBuilder->codeAppendf("float outer_thresh = %s;", + uniformHandler->getUniformCStr(fOuterThresholdVar)); + fragBuilder->codeAppend("float mask = mask_color.a;"); + + fragBuilder->codeAppend("vec4 color = input_color;"); + fragBuilder->codeAppend("if (mask < 0.5) {" + "if (color.a > outer_thresh) {" + "float scale = outer_thresh / color.a;" + "color.rgb *= scale;" + "color.a = outer_thresh;" + "}" + "} else if (color.a < inner_thresh) {" + "float scale = inner_thresh / max(0.001, color.a);" + "color.rgb *= scale;" + "color.a = inner_thresh;" + "}"); + + fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, + (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str()); +} + +void GrGLAlphaThresholdFragmentProcessor::onSetData(const GrGLSLProgramDataManager& pdman, + const GrProcessor& proc) { + const GrAlphaThresholdFragmentProcessor& atfp = proc.cast(); + pdman.set1f(fInnerThresholdVar, atfp.innerThreshold()); + pdman.set1f(fOuterThresholdVar, atfp.outerThreshold()); +} + +///////////////////////////////////////////////////////////////////// + +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAlphaThresholdFragmentProcessor); + +const GrFragmentProcessor* GrAlphaThresholdFragmentProcessor::TestCreate(GrProcessorTestData* d) { + GrTexture* bmpTex = d->fTextures[GrProcessorUnitTest::kSkiaPMTextureIdx]; + GrTexture* maskTex = d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx]; + float innerThresh = d->fRandom->nextUScalar1(); + float outerThresh = d->fRandom->nextUScalar1(); + const int kMaxWidth = 1000; + const int kMaxHeight = 1000; + uint32_t width = d->fRandom->nextULessThan(kMaxWidth); + uint32_t height = d->fRandom->nextULessThan(kMaxHeight); + uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width); + uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height); + SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height); + return GrAlphaThresholdFragmentProcessor::Make(bmpTex, maskTex, + innerThresh, outerThresh, + bounds).release(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrGLSLCaps& caps, + GrProcessorKeyBuilder* b) const { + GrGLAlphaThresholdFragmentProcessor::GenKey(*this, caps, b); +} + +GrGLSLFragmentProcessor* GrAlphaThresholdFragmentProcessor::onCreateGLSLInstance() const { + return new GrGLAlphaThresholdFragmentProcessor; +} + +#endif diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.h b/src/effects/GrAlphaThresholdFragmentProcessor.h new file mode 100644 index 0000000000..51602910c6 --- /dev/null +++ b/src/effects/GrAlphaThresholdFragmentProcessor.h @@ -0,0 +1,61 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrAlphaThresholdFragmentProcessor_DEFINED +#define GrAlphaThresholdFragmentProcessor_DEFINED + +#include "SkTypes.h" + +#if SK_SUPPORT_GPU + +#include "GrCoordTransform.h" +#include "GrFragmentProcessor.h" +#include "GrProcessorUnitTest.h" + +class GrAlphaThresholdFragmentProcessor : public GrFragmentProcessor { + +public: + static sk_sp Make(GrTexture* texture, + GrTexture* maskTexture, + float innerThreshold, + float outerThreshold, + const SkIRect& bounds); + + const char* name() const override { return "Alpha Threshold"; } + + float innerThreshold() const { return fInnerThreshold; } + float outerThreshold() const { return fOuterThreshold; } + +private: + GrAlphaThresholdFragmentProcessor(GrTexture* texture, + GrTexture* maskTexture, + float innerThreshold, + float outerThreshold, + const SkIRect& bounds); + + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; + + void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; + + bool onIsEqual(const GrFragmentProcessor&) const override; + + void onComputeInvariantOutput(GrInvariantOutput* inout) const override; + + GR_DECLARE_FRAGMENT_PROCESSOR_TEST; + + float fInnerThreshold; + float fOuterThreshold; + GrCoordTransform fImageCoordTransform; + GrTextureAccess fImageTextureAccess; + GrCoordTransform fMaskCoordTransform; + GrTextureAccess fMaskTextureAccess; + + typedef GrFragmentProcessor INHERITED; +}; + +#endif +#endif diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp index a5484300e1..0d16ec685e 100644 --- a/src/effects/SkAlphaThresholdFilter.cpp +++ b/src/effects/SkAlphaThresholdFilter.cpp @@ -12,7 +12,10 @@ #include "SkSpecialImage.h" #include "SkWriteBuffer.h" #include "SkRegion.h" + #if SK_SUPPORT_GPU +#include "GrAlphaThresholdFragmentProcessor.h" +#include "GrContext.h" #include "GrDrawContext.h" #endif @@ -67,208 +70,6 @@ sk_sp SkAlphaThresholdFilter::Make(const SkRegion& region, cropRect)); } -#if SK_SUPPORT_GPU -#include "GrContext.h" -#include "GrCoordTransform.h" -#include "GrFragmentProcessor.h" -#include "GrInvariantOutput.h" -#include "GrTextureAccess.h" -#include "effects/GrPorterDuffXferProcessor.h" - -#include "SkGr.h" - -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "glsl/GrGLSLProgramDataManager.h" -#include "glsl/GrGLSLUniformHandler.h" - -namespace { - -SkMatrix make_div_and_translate_matrix(GrTexture* texture, int x, int y) { - SkMatrix matrix = GrCoordTransform::MakeDivByTextureWHMatrix(texture); - matrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y)); - return matrix; -} - -}; - -class AlphaThresholdEffect : public GrFragmentProcessor { - -public: - static GrFragmentProcessor* Create(GrTexture* texture, - GrTexture* maskTexture, - float innerThreshold, - float outerThreshold, - const SkIRect& bounds) { - return new AlphaThresholdEffect(texture, maskTexture, innerThreshold, outerThreshold, - bounds); - } - - virtual ~AlphaThresholdEffect() {}; - - const char* name() const override { return "Alpha Threshold"; } - - float innerThreshold() const { return fInnerThreshold; } - float outerThreshold() const { return fOuterThreshold; } - -private: - AlphaThresholdEffect(GrTexture* texture, - GrTexture* maskTexture, - float innerThreshold, - float outerThreshold, - const SkIRect& bounds) - : fInnerThreshold(innerThreshold) - , fOuterThreshold(outerThreshold) - , fImageCoordTransform(kLocal_GrCoordSet, - GrCoordTransform::MakeDivByTextureWHMatrix(texture), texture, - GrTextureParams::kNone_FilterMode) - , fImageTextureAccess(texture) - , fMaskCoordTransform(kLocal_GrCoordSet, - make_div_and_translate_matrix(maskTexture, -bounds.x(), -bounds.y()), - maskTexture, - GrTextureParams::kNone_FilterMode) - , fMaskTextureAccess(maskTexture) { - this->initClassID(); - this->addCoordTransform(&fImageCoordTransform); - this->addTextureAccess(&fImageTextureAccess); - this->addCoordTransform(&fMaskCoordTransform); - this->addTextureAccess(&fMaskTextureAccess); - } - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - - void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; - - bool onIsEqual(const GrFragmentProcessor&) const override; - - void onComputeInvariantOutput(GrInvariantOutput* inout) const override; - - GR_DECLARE_FRAGMENT_PROCESSOR_TEST; - - float fInnerThreshold; - float fOuterThreshold; - GrCoordTransform fImageCoordTransform; - GrTextureAccess fImageTextureAccess; - GrCoordTransform fMaskCoordTransform; - GrTextureAccess fMaskTextureAccess; - - typedef GrFragmentProcessor INHERITED; -}; - -class GrGLAlphaThresholdEffect : public GrGLSLFragmentProcessor { -public: - void emitCode(EmitArgs&) override; - -protected: - void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; - -private: - GrGLSLProgramDataManager::UniformHandle fInnerThresholdVar; - GrGLSLProgramDataManager::UniformHandle fOuterThresholdVar; - - typedef GrGLSLFragmentProcessor INHERITED; -}; - -void GrGLAlphaThresholdEffect::emitCode(EmitArgs& args) { - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - fInnerThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, kDefault_GrSLPrecision, - "inner_threshold"); - fOuterThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, kDefault_GrSLPrecision, - "outer_threshold"); - - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0); - SkString maskCoords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1); - - fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); - fragBuilder->codeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str()); - fragBuilder->codeAppend("\t\tvec4 input_color = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], "coord"); - fragBuilder->codeAppend(";\n"); - fragBuilder->codeAppend("\t\tvec4 mask_color = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[1], "mask_coord"); - fragBuilder->codeAppend(";\n"); - - fragBuilder->codeAppendf("\t\tfloat inner_thresh = %s;\n", - uniformHandler->getUniformCStr(fInnerThresholdVar)); - fragBuilder->codeAppendf("\t\tfloat outer_thresh = %s;\n", - uniformHandler->getUniformCStr(fOuterThresholdVar)); - fragBuilder->codeAppend("\t\tfloat mask = mask_color.a;\n"); - - fragBuilder->codeAppend("vec4 color = input_color;\n"); - fragBuilder->codeAppend("\t\tif (mask < 0.5) {\n" - "\t\t\tif (color.a > outer_thresh) {\n" - "\t\t\t\tfloat scale = outer_thresh / color.a;\n" - "\t\t\t\tcolor.rgb *= scale;\n" - "\t\t\t\tcolor.a = outer_thresh;\n" - "\t\t\t}\n" - "\t\t} else if (color.a < inner_thresh) {\n" - "\t\t\tfloat scale = inner_thresh / max(0.001, color.a);\n" - "\t\t\tcolor.rgb *= scale;\n" - "\t\t\tcolor.a = inner_thresh;\n" - "\t\t}\n"); - - fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, - (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str()); -} - -void GrGLAlphaThresholdEffect::onSetData(const GrGLSLProgramDataManager& pdman, - const GrProcessor& proc) { - const AlphaThresholdEffect& alpha_threshold = proc.cast(); - pdman.set1f(fInnerThresholdVar, alpha_threshold.innerThreshold()); - pdman.set1f(fOuterThresholdVar, alpha_threshold.outerThreshold()); -} - -///////////////////////////////////////////////////////////////////// - -GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AlphaThresholdEffect); - -const GrFragmentProcessor* AlphaThresholdEffect::TestCreate(GrProcessorTestData* d) { - GrTexture* bmpTex = d->fTextures[GrProcessorUnitTest::kSkiaPMTextureIdx]; - GrTexture* maskTex = d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx]; - float innerThresh = d->fRandom->nextUScalar1(); - float outerThresh = d->fRandom->nextUScalar1(); - const int kMaxWidth = 1000; - const int kMaxHeight = 1000; - uint32_t width = d->fRandom->nextULessThan(kMaxWidth); - uint32_t height = d->fRandom->nextULessThan(kMaxHeight); - uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width); - uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height); - SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height); - return AlphaThresholdEffect::Create(bmpTex, maskTex, innerThresh, outerThresh, bounds); -} - -/////////////////////////////////////////////////////////////////////////////// - -void AlphaThresholdEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, - GrProcessorKeyBuilder* b) const { - GrGLAlphaThresholdEffect::GenKey(*this, caps, b); -} - -GrGLSLFragmentProcessor* AlphaThresholdEffect::onCreateGLSLInstance() const { - return new GrGLAlphaThresholdEffect; -} - -bool AlphaThresholdEffect::onIsEqual(const GrFragmentProcessor& sBase) const { - const AlphaThresholdEffect& s = sBase.cast(); - return (this->fInnerThreshold == s.fInnerThreshold && - this->fOuterThreshold == s.fOuterThreshold); -} - -void AlphaThresholdEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { - if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) { - inout->mulByUnknownSingleComponent(); - } else if (GrPixelConfigIsOpaque(this->texture(0)->config()) && fOuterThreshold >= 1.f) { - inout->mulByUnknownOpaqueFourComponents(); - } else { - inout->mulByUnknownFourComponents(); - } -} - -#endif - sk_sp SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer) { SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); SkScalar inner = buffer.readScalar(); @@ -376,7 +177,8 @@ sk_sp SkAlphaThresholdFilterImpl::onFilterImage(SkSpecialImage* } // SRGBTODO: handle sRGB here - sk_sp fp(AlphaThresholdEffect::Create(inputTexture.get(), + sk_sp fp(GrAlphaThresholdFragmentProcessor::Make( + inputTexture.get(), maskTexture.get(), fInnerThreshold, fOuterThreshold, diff --git a/tests/FlattenableFactoryToName.cpp b/tests/FlattenableFactoryToName.cpp index a22f0b1c3e..35ec98493f 100644 --- a/tests/FlattenableFactoryToName.cpp +++ b/tests/FlattenableFactoryToName.cpp @@ -7,6 +7,7 @@ #include "SkAlphaThresholdFilter.h" #include "SkImage.h" +#include "SkRegion.h" #include "Test.h" static void test_flattenable(skiatest::Reporter* r, -- 2.34.1