diff options
-rw-r--r-- | gn/gpu.gni | 2 | ||||
-rw-r--r-- | gn/sksl.gni | 1 | ||||
-rw-r--r-- | src/gpu/GrProcessor.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrAARectEffect.cpp | 118 | ||||
-rw-r--r-- | src/gpu/effects/GrAARectEffect.fp | 58 | ||||
-rw-r--r-- | src/gpu/effects/GrAARectEffect.h | 43 | ||||
-rw-r--r-- | src/gpu/effects/GrConvexPolyEffect.cpp | 144 | ||||
-rw-r--r-- | src/sksl/SkSLCPP.h | 4 |
8 files changed, 229 insertions, 143 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni index c364c29f03..e283a9f12f 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -314,6 +314,8 @@ skia_gpu_sources = [ "$_src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp", "$_src/gpu/ccpr/GrCoverageCountingPathRenderer.h", + "$_src/gpu/effects/GrAARectEffect.cpp", + "$_src/gpu/effects/GrAARectEffect.h", "$_src/gpu/effects/GrArithmeticFP.cpp", "$_src/gpu/effects/GrArithmeticFP.h", "$_src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp", diff --git a/gn/sksl.gni b/gn/sksl.gni index ca6abcff09..6eec537ebe 100644 --- a/gn/sksl.gni +++ b/gn/sksl.gni @@ -28,6 +28,7 @@ skia_sksl_sources = [ skia_gpu_processor_sources = [ "$_src/effects/GrAlphaThresholdFragmentProcessor.fp", "$_src/effects/GrCircleBlurFragmentProcessor.fp", + "$_src/gpu/effects/GrAARectEffect.fp", "$_src/gpu/effects/GrArithmeticFP.fp", "$_src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp", "$_src/gpu/effects/GrCircleEffect.fp", diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index cafc713a62..adb5df3a42 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -65,7 +65,6 @@ private: class GrProcessor { public: enum ClassID { - kAARectEffect_ClassID, kBigKeyProcessor_ClassID, kBlockInputFragmentProcessor_ClassID, kCircleGeometryProcessor_ClassID, @@ -89,6 +88,7 @@ public: kFocalInside2PtConicalEffect_ClassID, kFocalOutside2PtConicalEffect_ClassID, kGP_ClassID, + kGrAARectEffect_ClassID, kGrAlphaThresholdFragmentProcessor_ClassID, kGrArithmeticFP_ClassID, kGrBicubicEffect_ClassID, diff --git a/src/gpu/effects/GrAARectEffect.cpp b/src/gpu/effects/GrAARectEffect.cpp new file mode 100644 index 0000000000..fcc54dc261 --- /dev/null +++ b/src/gpu/effects/GrAARectEffect.cpp @@ -0,0 +1,118 @@ +/* + * Copyright 2017 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 GrAARectEffect.fp; do not modify. + */ +#include "GrAARectEffect.h" +#if SK_SUPPORT_GPU +#include "glsl/GrGLSLFragmentProcessor.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLProgramBuilder.h" +#include "SkSLCPP.h" +#include "SkSLUtil.h" +class GrGLSLAARectEffect : public GrGLSLFragmentProcessor { +public: + GrGLSLAARectEffect() {} + void emitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + const GrAARectEffect& _outer = args.fFp.cast<GrAARectEffect>(); + (void)_outer; + auto edgeType = _outer.edgeType(); + (void)edgeType; + auto rect = _outer.rect(); + (void)rect; + prevRect = float4(-1.0); + fRectUniformVar = args.fUniformHandler->addUniform( + kFragment_GrShaderFlag, kFloat4_GrSLType, kDefault_GrSLPrecision, "rectUniform"); + fragBuilder->codeAppendf( + "float4 prevRect = float4(%f, %f, %f, %f);\nhalf alpha;\n@switch (%d) {\n case " + "0:\n case 2:\n alpha = half(all(greaterThan(float4(sk_FragCoord.xy, " + "%s.zw), float4(%s.xy, sk_FragCoord.xy))) ? 1 : 0);\n break;\n " + "default:\n half xSub, ySub;\n xSub = half(min(sk_FragCoord.x - " + "%s.x, 0.0));\n xSub += half(min(%s.z - sk_FragCoord.x, 0.0));\n " + "ySub = half(min(sk_FragCoord.y - %s.y, 0.0));\n ySub += half(min(%s.w - " + "sk_FragCoord.y, 0.0));\n alpha = half((1", + prevRect.left(), + prevRect.top(), + prevRect.right(), + prevRect.bottom(), + (int)_outer.edgeType(), + args.fUniformHandler->getUniformCStr(fRectUniformVar), + args.fUniformHandler->getUniformCStr(fRectUniformVar), + args.fUniformHandler->getUniformCStr(fRectUniformVar), + args.fUniformHandler->getUniformCStr(fRectUniformVar), + args.fUniformHandler->getUniformCStr(fRectUniformVar), + args.fUniformHandler->getUniformCStr(fRectUniformVar)); + fragBuilder->codeAppendf( + ".0 + max(float(xSub), -1.0)) * (1.0 + max(float(ySub), -1.0)));\n}\n@if (%d == 2 " + "|| %d == 3) {\n alpha = half(1.0 - float(alpha));\n}\n%s = %s * alpha;\n", + (int)_outer.edgeType(), + (int)_outer.edgeType(), + args.fOutputColor, + args.fInputColor ? args.fInputColor : "half4(1)"); + } + +private: + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& _proc) override { + const GrAARectEffect& _outer = _proc.cast<GrAARectEffect>(); + auto edgeType = _outer.edgeType(); + (void)edgeType; + auto rect = _outer.rect(); + (void)rect; + UniformHandle& rectUniform = fRectUniformVar; + (void)rectUniform; + + const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ? rect.makeInset(.5f, .5f) : rect; + if (newRect != prevRect) { + pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom); + prevRect = newRect; + } + } + SkRect prevRect; + UniformHandle fRectUniformVar; +}; +GrGLSLFragmentProcessor* GrAARectEffect::onCreateGLSLInstance() const { + return new GrGLSLAARectEffect(); +} +void GrAARectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, + GrProcessorKeyBuilder* b) const { + b->add32((int32_t)fEdgeType); +} +bool GrAARectEffect::onIsEqual(const GrFragmentProcessor& other) const { + const GrAARectEffect& that = other.cast<GrAARectEffect>(); + (void)that; + if (fEdgeType != that.fEdgeType) return false; + if (fRect != that.fRect) return false; + return true; +} +GrAARectEffect::GrAARectEffect(const GrAARectEffect& src) + : INHERITED(kGrAARectEffect_ClassID, src.optimizationFlags()) + , fEdgeType(src.fEdgeType) + , fRect(src.fRect) {} +std::unique_ptr<GrFragmentProcessor> GrAARectEffect::clone() const { + return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(*this)); +} +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAARectEffect); +#if GR_TEST_UTILS +std::unique_ptr<GrFragmentProcessor> GrAARectEffect::TestCreate(GrProcessorTestData* d) { + SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(), + d->fRandom->nextSScalar1(), + d->fRandom->nextSScalar1(), + d->fRandom->nextSScalar1()); + std::unique_ptr<GrFragmentProcessor> fp; + do { + GrClipEdgeType edgeType = + static_cast<GrClipEdgeType>(d->fRandom->nextULessThan(kGrClipEdgeTypeCnt)); + + fp = GrAARectEffect::Make(edgeType, rect); + } while (nullptr == fp); + return fp; +} +#endif +#endif diff --git a/src/gpu/effects/GrAARectEffect.fp b/src/gpu/effects/GrAARectEffect.fp new file mode 100644 index 0000000000..b8449c2252 --- /dev/null +++ b/src/gpu/effects/GrAARectEffect.fp @@ -0,0 +1,58 @@ +layout(key) in GrClipEdgeType edgeType; +layout(ctype=SkRect) in float4 rect; +layout(ctype=SkRect) float4 prevRect = float4(-1); +uniform float4 rectUniform; + +@optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag } + +void main() { + half alpha; + @switch (edgeType) { + case GrClipEdgeType::kFillBW: // fall through + case GrClipEdgeType::kInverseFillBW: + // non-AA + alpha = all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw), + float4(rectUniform.xy, sk_FragCoord.xy))) ? 1 : 0; + break; + default: + // The amount of coverage removed in x and y by the edges is computed as a pair of + // negative numbers, xSub and ySub. + half xSub, ySub; + xSub = min(sk_FragCoord.x - rectUniform.x, 0.0); + xSub += min(rectUniform.z - sk_FragCoord.x, 0.0); + ySub = min(sk_FragCoord.y - rectUniform.y, 0.0); + ySub += min(rectUniform.w - sk_FragCoord.y, 0.0); + // Now compute coverage in x and y and multiply them to get the fraction of the pixel + // covered. + alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0)); + } + + @if (edgeType == GrClipEdgeType::kInverseFillBW || edgeType == GrClipEdgeType::kInverseFillAA) { + alpha = 1.0 - alpha; + } + sk_OutColor = sk_InColor * alpha; +} + +@setData(pdman) { + const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ? + rect.makeInset(.5f, .5f) : rect; + if (newRect != prevRect) { + pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom); + prevRect = newRect; + } +} + +@test(d) { + SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(), + d->fRandom->nextSScalar1(), + d->fRandom->nextSScalar1(), + d->fRandom->nextSScalar1()); + std::unique_ptr<GrFragmentProcessor> fp; + do { + GrClipEdgeType edgeType = static_cast<GrClipEdgeType>( + d->fRandom->nextULessThan(kGrClipEdgeTypeCnt)); + + fp = GrAARectEffect::Make(edgeType, rect); + } while (nullptr == fp); + return fp; +} diff --git a/src/gpu/effects/GrAARectEffect.h b/src/gpu/effects/GrAARectEffect.h new file mode 100644 index 0000000000..21f20773f3 --- /dev/null +++ b/src/gpu/effects/GrAARectEffect.h @@ -0,0 +1,43 @@ +/* + * Copyright 2017 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 GrAARectEffect.fp; do not modify. + */ +#ifndef GrAARectEffect_DEFINED +#define GrAARectEffect_DEFINED +#include "SkTypes.h" +#if SK_SUPPORT_GPU +#include "GrFragmentProcessor.h" +#include "GrCoordTransform.h" +class GrAARectEffect : public GrFragmentProcessor { +public: + GrClipEdgeType edgeType() const { return fEdgeType; } + SkRect rect() const { return fRect; } + static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkRect rect) { + return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(edgeType, rect)); + } + GrAARectEffect(const GrAARectEffect& src); + std::unique_ptr<GrFragmentProcessor> clone() const override; + const char* name() const override { return "AARectEffect"; } + +private: + GrAARectEffect(GrClipEdgeType edgeType, SkRect rect) + : INHERITED(kGrAARectEffect_ClassID, + (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag) + , fEdgeType(edgeType) + , fRect(rect) {} + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; + void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; + bool onIsEqual(const GrFragmentProcessor&) const override; + GR_DECLARE_FRAGMENT_PROCESSOR_TEST + GrClipEdgeType fEdgeType; + SkRect fRect; + typedef GrFragmentProcessor INHERITED; +}; +#endif +#endif diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp index d3954fcef2..6df92eef15 100644 --- a/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/src/gpu/effects/GrConvexPolyEffect.cpp @@ -7,6 +7,7 @@ #include "GrConvexPolyEffect.h" #include "SkPathPriv.h" +#include "effects/GrAARectEffect.h" #include "effects/GrConstColorProcessor.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" @@ -15,147 +16,6 @@ #include "../private/GrGLSL.h" ////////////////////////////////////////////////////////////////////////////// -class AARectEffect : public GrFragmentProcessor { -public: - const SkRect& getRect() const { return fRect; } - - static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, - const SkRect& rect) { - return std::unique_ptr<GrFragmentProcessor>(new AARectEffect(edgeType, rect)); - } - - GrClipEdgeType getEdgeType() const { return fEdgeType; } - - const char* name() const override { return "AARect"; } - - std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fEdgeType, fRect); } - -private: - void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; - - AARectEffect(GrClipEdgeType edgeType, const SkRect& rect) - : INHERITED(kAARectEffect_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag) - , fRect(rect) - , fEdgeType(edgeType) { - } - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - - bool onIsEqual(const GrFragmentProcessor& other) const override { - const AARectEffect& aare = other.cast<AARectEffect>(); - return fRect == aare.fRect; - } - - SkRect fRect; - GrClipEdgeType fEdgeType; - - typedef GrFragmentProcessor INHERITED; - - GR_DECLARE_FRAGMENT_PROCESSOR_TEST - -}; - -GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AARectEffect); - -#if GR_TEST_UTILS -std::unique_ptr<GrFragmentProcessor> AARectEffect::TestCreate(GrProcessorTestData* d) { - SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(), - d->fRandom->nextSScalar1(), - d->fRandom->nextSScalar1(), - d->fRandom->nextSScalar1()); - std::unique_ptr<GrFragmentProcessor> fp; - do { - GrClipEdgeType edgeType = static_cast<GrClipEdgeType>( - d->fRandom->nextULessThan(kGrClipEdgeTypeCnt)); - - fp = AARectEffect::Make(edgeType, rect); - } while (nullptr == fp); - return fp; -} -#endif - -////////////////////////////////////////////////////////////////////////////// - -class GLAARectEffect : public GrGLSLFragmentProcessor { -public: - GLAARectEffect() { - fPrevRect.fLeft = SK_ScalarNaN; - } - - void emitCode(EmitArgs&) override; - - static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*); - -protected: - void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; - -private: - GrGLSLProgramDataManager::UniformHandle fRectUniform; - SkRect fPrevRect; - - typedef GrGLSLFragmentProcessor INHERITED; -}; - -void GLAARectEffect::emitCode(EmitArgs& args) { - const AARectEffect& aare = args.fFp.cast<AARectEffect>(); - const char *rectName; - // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), - // respectively. - fRectUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat4_GrSLType, - "rect", - &rectName); - - GrGLSLFPFragmentBuilder* f = args.fFragBuilder; - if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) { - // The amount of coverage removed in x and y by the edges is computed as a pair of negative - // numbers, xSub and ySub. - f->codeAppend("half xSub, ySub;\n"); - f->codeAppendf("xSub = min(sk_FragCoord.x - %s.x, 0.0);\n", rectName); - f->codeAppendf("xSub += min(%s.z - sk_FragCoord.x, 0.0);\n", rectName); - f->codeAppendf("ySub = min(sk_FragCoord.y - %s.y, 0.0);\n", rectName); - f->codeAppendf("ySub += min(%s.w - sk_FragCoord.y, 0.0);\n", rectName); - // Now compute coverage in x and y and multiply them to get the fraction of the pixel - // covered. - f->codeAppendf("half alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); - } else { - f->codeAppendf("half alpha = all(greaterThan(float4(sk_FragCoord.xy, %s.zw), " - "float4(%s.xy, sk_FragCoord.xy))) ? 1 : 0;", - rectName, rectName); - } - - if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) { - f->codeAppend("alpha = 1.0 - alpha;\n"); - } - f->codeAppendf("%s = %s * alpha;\n", args.fOutputColor, args.fInputColor); -} - -void GLAARectEffect::onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& processor) { - const AARectEffect& aare = processor.cast<AARectEffect>(); - const SkRect& rect = GrProcessorEdgeTypeIsAA(aare.getEdgeType()) ? - aare.getRect().makeInset(.5f, .5f) : aare.getRect(); - if (rect != fPrevRect) { - pdman.set4f(fRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); - fPrevRect = rect; - } -} - -void GLAARectEffect::GenKey(const GrProcessor& processor, const GrShaderCaps&, - GrProcessorKeyBuilder* b) { - const AARectEffect& aare = processor.cast<AARectEffect>(); - b->add32((int) aare.getEdgeType()); -} - -void AARectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { - GLAARectEffect::GenKey(*this, caps, b); -} - -GrGLSLFragmentProcessor* AARectEffect::onCreateGLSLInstance() const { - return new GLAARectEffect; -} - -////////////////////////////////////////////////////////////////////////////// class GrGLConvexPolyEffect : public GrGLSLFragmentProcessor { public: @@ -304,7 +164,7 @@ std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType edg if (GrClipEdgeType::kHairlineAA == edgeType){ return nullptr; } - return AARectEffect::Make(edgeType, rect); + return GrAARectEffect::Make(edgeType, rect); } GrConvexPolyEffect::~GrConvexPolyEffect() {} diff --git a/src/sksl/SkSLCPP.h b/src/sksl/SkSLCPP.h index 612a200f28..970e2c73c9 100644 --- a/src/sksl/SkSLCPP.h +++ b/src/sksl/SkSLCPP.h @@ -25,6 +25,10 @@ inline SkPoint float2(float xy) { return SkPoint::Make(xy, xy); } inline SkPoint float2(float x, float y) { return SkPoint::Make(x, y); } +inline SkRect float4(float ltrb) { return SkRect::MakeLTRB(ltrb, ltrb, ltrb, ltrb); } + +inline SkRect float4(float l, float t, float r, float b) { return SkRect::MakeLTRB(l, t, r, b); } + #define half2 float2 #endif |