| Index: src/effects/SkAlphaThresholdFilter.cpp
|
| diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
|
| index a5484300e1b500357e2a53c9a885fef20a7949fc..0d16ec685ed4f1ee57c994e0e976e5674c3794fb 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<SkImageFilter> 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<AlphaThresholdEffect>();
|
| - 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<AlphaThresholdEffect>();
|
| - 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<AlphaThresholdEffect>();
|
| - 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<SkFlattenable> SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer) {
|
| SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
|
| SkScalar inner = buffer.readScalar();
|
| @@ -376,7 +177,8 @@ sk_sp<SkSpecialImage> SkAlphaThresholdFilterImpl::onFilterImage(SkSpecialImage*
|
| }
|
|
|
| // SRGBTODO: handle sRGB here
|
| - sk_sp<GrFragmentProcessor> fp(AlphaThresholdEffect::Create(inputTexture.get(),
|
| + sk_sp<GrFragmentProcessor> fp(GrAlphaThresholdFragmentProcessor::Make(
|
| + inputTexture.get(),
|
| maskTexture.get(),
|
| fInnerThreshold,
|
| fOuterThreshold,
|
|
|