From c59034145862bf6dc0c503cb1e47eecd321ffa8c Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Thu, 17 Nov 2016 15:27:09 -0500 Subject: Add shadowrrect geometry processor GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4233 Change-Id: I637099709cfe30f7d3c1883e23840a47a7a25c10 Reviewed-on: https://skia-review.googlesource.com/4233 Commit-Queue: Jim Van Verth Reviewed-by: Robert Phillips --- src/gpu/effects/GrShadowGeoProc.cpp | 104 ++++++++++++++++++++++++++++++++++++ src/gpu/effects/GrShadowGeoProc.h | 56 +++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100755 src/gpu/effects/GrShadowGeoProc.cpp create mode 100755 src/gpu/effects/GrShadowGeoProc.h (limited to 'src/gpu/effects') diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp new file mode 100755 index 0000000000..8544a05e35 --- /dev/null +++ b/src/gpu/effects/GrShadowGeoProc.cpp @@ -0,0 +1,104 @@ +/* + * 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 "GrShadowGeoProc.h" + +#include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLGeometryProcessor.h" +#include "glsl/GrGLSLUniformHandler.h" +#include "glsl/GrGLSLVarying.h" +#include "glsl/GrGLSLVertexShaderBuilder.h" + +class GrGLSLRRectShadowGeoProc : public GrGLSLGeometryProcessor { +public: + GrGLSLRRectShadowGeoProc() {} + + void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { + const GrRRectShadowGeoProc& rsgp = args.fGP.cast(); + GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; + GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; + GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; + + // emit attributes + varyingHandler->emitAttributes(rsgp); + fragBuilder->codeAppend("vec4 shadowParams;"); + varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams"); + + // setup pass through color + varyingHandler->addPassThroughAttribute(rsgp.inColor(), args.fOutputColor); + + // Setup position + this->setupPosition(vertBuilder, gpArgs, rsgp.inPosition()->fName); + + // emit transforms + this->emitTransforms(vertBuilder, + varyingHandler, + uniformHandler, + gpArgs->fPositionVar, + rsgp.inPosition()->fName, + rsgp.localMatrix(), + args.fFPCoordTransformHandler); + + fragBuilder->codeAppend("float d = length(shadowParams.xy);"); + fragBuilder->codeAppend("float distance = shadowParams.z * (1.0 - d);"); + + fragBuilder->codeAppend("float radius = shadowParams.w;"); + + fragBuilder->codeAppend("float factor = 1.0 - clamp(distance/radius, 0.0, 1.0);"); + fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;"); + fragBuilder->codeAppendf("%s = vec4(factor);", + args.fOutputCoverage); + } + + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, + FPCoordTransformIter&& transformIter) override { + this->setTransformDataHelper(proc.cast().localMatrix(), + pdman, &transformIter); + } + + static inline void GenKey(const GrGeometryProcessor& gp, + const GrGLSLCaps&, + GrProcessorKeyBuilder* b) { + const GrRRectShadowGeoProc& rsgp = gp.cast(); + uint16_t key; + key = rsgp.localMatrix().hasPerspective() ? 0x1 : 0x0; + b->add32(key); + } + +private: + typedef GrGLSLGeometryProcessor INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +GrRRectShadowGeoProc::GrRRectShadowGeoProc(const SkMatrix& localMatrix) + : fLocalMatrix(localMatrix) { + + this->initClassID(); + fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType, + kHigh_GrSLPrecision); + fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType); + fInShadowParams = &this->addVertexAttrib("inShadowParams", kVec4f_GrVertexAttribType); +} + +void GrRRectShadowGeoProc::getGLSLProcessorKey(const GrGLSLCaps& caps, + GrProcessorKeyBuilder* b) const { + GrGLSLRRectShadowGeoProc::GenKey(*this, caps, b); +} + +GrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrGLSLCaps&) const { + return new GrGLSLRRectShadowGeoProc(); +} + +/////////////////////////////////////////////////////////////////////////////// + +GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRRectShadowGeoProc); + +sk_sp GrRRectShadowGeoProc::TestCreate(GrProcessorTestData* d) { + return GrRRectShadowGeoProc::Make(GrTest::TestMatrix(d->fRandom)); +} diff --git a/src/gpu/effects/GrShadowGeoProc.h b/src/gpu/effects/GrShadowGeoProc.h new file mode 100755 index 0000000000..29e2bde84d --- /dev/null +++ b/src/gpu/effects/GrShadowGeoProc.h @@ -0,0 +1,56 @@ +/* + * 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 GrShadowGeoProc_DEFINED +#define GrShadowGeoProc_DEFINED + +#include "GrProcessor.h" +#include "GrGeometryProcessor.h" + +class GrGLRRectShadowGeoProc; + +/** + * The output color of this effect is a coverage mask for a rrect shadow, + * assuming circular corner geometry. + */ +class GrRRectShadowGeoProc : public GrGeometryProcessor { +public: + static sk_sp Make(const SkMatrix& localMatrix) { + return sk_sp(new GrRRectShadowGeoProc(localMatrix)); + } + + ~GrRRectShadowGeoProc() override {} + + const char* name() const override { return "RRectShadow"; } + + const Attribute* inPosition() const { return fInPosition; } + const Attribute* inColor() const { return fInColor; } + const Attribute* inShadowParams() const { return fInShadowParams; } + GrColor color() const { return fColor; } + bool colorIgnored() const { return GrColor_ILLEGAL == fColor; } + const SkMatrix& localMatrix() const { return fLocalMatrix; } + + void getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; + + GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override; + +private: + GrRRectShadowGeoProc(const SkMatrix& localMatrix); + + GrColor fColor; + SkMatrix fLocalMatrix; + const Attribute* fInPosition; + const Attribute* fInColor; + const Attribute* fInShadowParams; + + GR_DECLARE_GEOMETRY_PROCESSOR_TEST; + + typedef GrGeometryProcessor INHERITED; +}; + + +#endif -- cgit v1.2.3