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 <jvanverth@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp
new file mode 100755
index 0000000..8544a05
--- /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<GrRRectShadowGeoProc>();
+ 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<GrRRectShadowGeoProc>().localMatrix(),
+ pdman, &transformIter);
+ }
+
+ static inline void GenKey(const GrGeometryProcessor& gp,
+ const GrGLSLCaps&,
+ GrProcessorKeyBuilder* b) {
+ const GrRRectShadowGeoProc& rsgp = gp.cast<GrRRectShadowGeoProc>();
+ 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<GrRRectShadowGeoProc>();
+ 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<GrGeometryProcessor> GrRRectShadowGeoProc::TestCreate(GrProcessorTestData* d) {
+ return GrRRectShadowGeoProc::Make(GrTest::TestMatrix(d->fRandom));
+}