Revert of Default geometry processor (patchset #9 id:160001 of https://codereview...
authorjoshualitt <joshualitt@google.com>
Fri, 7 Nov 2014 20:08:03 +0000 (12:08 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 7 Nov 2014 20:08:03 +0000 (12:08 -0800)
Reason for revert:
breaks nexus 5

Original issue's description:
> Default geometry processor
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/ff343074b2a3fdaa5f120600e28717e366bceadd

TBR=bsalomon@google.com,joshualitt@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/691313003

19 files changed:
gyp/gpu.gypi
include/gpu/GrGeometryProcessor.h
src/gpu/GrAAConvexPathRenderer.cpp
src/gpu/GrAARectRenderer.cpp
src/gpu/GrAARectRenderer.h
src/gpu/GrDefaultGeoProcFactory.cpp [deleted file]
src/gpu/GrDefaultGeoProcFactory.h [deleted file]
src/gpu/GrOptDrawState.cpp
src/gpu/GrOvalRenderer.cpp
src/gpu/GrProcessor.cpp
src/gpu/effects/GrBezierEffect.cpp
src/gpu/effects/GrCustomCoordsTextureEffect.cpp
src/gpu/effects/GrDashingEffect.cpp
src/gpu/effects/GrDistanceFieldTextureEffect.cpp
src/gpu/gl/GrGLSL.h
src/gpu/gl/builders/GrGLProgramBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.h
src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
src/gpu/gl/builders/GrGLVertexShaderBuilder.h

index cf3bdf7..e4bd92a 100644 (file)
@@ -72,8 +72,6 @@
       '<(skia_src_path)/gpu/GrClipMaskManager.h',
       '<(skia_src_path)/gpu/GrClipMaskManager.cpp',
       '<(skia_src_path)/gpu/GrContext.cpp',
-      '<(skia_src_path)/gpu/GrDefaultGeoProcFactory.cpp',
-      '<(skia_src_path)/gpu/GrDefaultGeoProcFactory.h',
       '<(skia_src_path)/gpu/GrDefaultPathRenderer.cpp',
       '<(skia_src_path)/gpu/GrDefaultPathRenderer.h',
       '<(skia_src_path)/gpu/GrDistanceFieldTextContext.h',
index 01401ae..287d7e1 100644 (file)
@@ -43,7 +43,7 @@ public:
     /** Returns true if this and other processor conservatively draw identically. It can only return
         true when the two prcoessors are of the same subclass (i.e. they return the same object from
         from getFactory()).
-        A return value of true from isEqual() should not be used to test whether the processors
+        A return value of true from isEqual() should not be used to test whether the prcoessors
         would generate the same shader code. To test for identical code generation use the
         processors' keys computed by the GrBackendEffectFactory. */
     bool isEqual(const GrGeometryProcessor& that) const {
index 3325b1c..eecc722 100644 (file)
@@ -561,10 +561,6 @@ public:
             const GrShaderVar& inQuadEdge = args.fGP.cast<QuadEdgeEffect>().inQuadEdge();
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
             vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), inQuadEdge.c_str());
-
-            // setup position varying
-            vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), vsBuilder->inPosition());
         }
 
         static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
index 46196e2..ead4ea1 100644 (file)
 #include "GrGeometryProcessor.h"
 
 ///////////////////////////////////////////////////////////////////////////////
+class GrGLAlignedRectEffect;
+
+// Axis Aligned special case
+class GrAlignedRectEffect : public GrGeometryProcessor {
+public:
+    static GrGeometryProcessor* Create() {
+        GR_CREATE_STATIC_PROCESSOR(gAlignedRectEffect, GrAlignedRectEffect, ());
+        gAlignedRectEffect->ref();
+        return gAlignedRectEffect;
+    }
+
+    virtual ~GrAlignedRectEffect() {}
+
+    static const char* Name() { return "AlignedRectEdge"; }
+
+    const GrShaderVar& inRect() const { return fInRect; }
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<GrAlignedRectEffect>::getInstance();
+    }
+
+    class GLProcessor : public GrGLGeometryProcessor {
+    public:
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
+        : INHERITED (factory) {}
+
+        virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
+            // setup the varying for the Axis aligned rect effect
+            //      xy -> interpolated offset
+            //      zw -> w/2+0.5, h/2+0.5
+            GrGLVertToFrag v(kVec4f_GrSLType);
+            args.fPB->addVarying("Rect", &v);
+
+            const GrShaderVar& inRect = args.fGP.cast<GrAlignedRectEffect>().inRect();
+            GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+            vsBuilder->codeAppendf("\t%s = %s;\n", v.fsIn(), inRect.c_str());
+
+            GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
+            // TODO: compute all these offsets, spans, and scales in the VS
+            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", v.fsIn());
+            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", v.fsIn());
+            fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
+            // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
+            // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
+            fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+            fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
+            // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
+            // value of coverage that is used. In other words it is the coverage that is
+            // used in the interior of the rect after the ramp.
+            fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+            fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+
+            // Compute the coverage for the rect's width
+            fsBuilder->codeAppendf(
+                "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", v.fsIn(),
+                v.fsIn());
+            // Compute the coverage for the rect's height and merge with the width
+            fsBuilder->codeAppendf(
+                "\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
+                v.fsIn(), v.fsIn());
+
+
+            fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+                                   (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("coverage")).c_str());
+        }
+
+        static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+
+        virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
+
+    private:
+        typedef GrGLGeometryProcessor INHERITED;
+    };
+
+
+private:
+    GrAlignedRectEffect()
+        : fInRect(this->addVertexAttrib(GrShaderVar("inRect",
+                                                    kVec4f_GrSLType,
+                                                    GrShaderVar::kAttribute_TypeModifier))) {
+    }
+
+    const GrShaderVar& fInRect;
+
+    virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { return true; }
+
+    virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
+        inout->mulByUnknownAlpha();
+    }
+
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+    typedef GrGeometryProcessor INHERITED;
+};
+
+
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrAlignedRectEffect);
+
+GrGeometryProcessor* GrAlignedRectEffect::TestCreate(SkRandom* random,
+                                                     GrContext* context,
+                                                     const GrDrawTargetCaps&,
+                                                     GrTexture* textures[]) {
+    return GrAlignedRectEffect::Create();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+class GrGLRectEffect;
+
+/**
+ * The output of this effect is a modulation of the input color and coverage
+ * for an arbitrarily oriented rect. The rect is specified as:
+ *      Center of the rect
+ *      Unit vector point down the height of the rect
+ *      Half width + 0.5
+ *      Half height + 0.5
+ * The center and vector are stored in a vec4 varying ("RectEdge") with the
+ * center in the xy components and the vector in the zw components.
+ * The munged width and height are stored in a vec2 varying ("WidthHeight")
+ * with the width in x and the height in y.
+ */
+
+class GrRectEffect : public GrGeometryProcessor {
+public:
+    static GrGeometryProcessor* Create() {
+        GR_CREATE_STATIC_PROCESSOR(gRectEffect, GrRectEffect, ());
+        gRectEffect->ref();
+        return gRectEffect;
+    }
+
+    virtual ~GrRectEffect() {}
+
+    static const char* Name() { return "RectEdge"; }
+
+    const GrShaderVar& inRectEdge() const { return fInRectEdge; }
+    const GrShaderVar& inWidthHeight() const { return fInWidthHeight; }
+
+    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
+        return GrTBackendGeometryProcessorFactory<GrRectEffect>::getInstance();
+    }
+
+    class GLProcessor : public GrGLGeometryProcessor {
+    public:
+        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
+        : INHERITED (factory) {}
+
+        virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
+            // setup the varying for the center point and the unit vector
+            // that points down the height of the rect
+            GrGLVertToFrag rectEdge(kVec4f_GrSLType);
+            args.fPB->addVarying("RectEdge", &rectEdge);
+
+            const GrRectEffect& rectEffect = args.fGP.cast<GrRectEffect>();
+            GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
+            vsBuilder->codeAppendf("%s = %s;", rectEdge.vsOut(), rectEffect.inRectEdge().c_str());
+
+            // setup the varying for width/2+.5 and height/2+.5
+            GrGLVertToFrag widthHeight(kVec2f_GrSLType);
+            args.fPB->addVarying("WidthHeight", &widthHeight);
+            vsBuilder->codeAppendf("%s = %s;",
+                                   widthHeight.vsOut(),
+                                   rectEffect.inWidthHeight().c_str());
+
+            GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
+            // TODO: compute all these offsets, spans, and scales in the VS
+            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", widthHeight.fsIn());
+            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", widthHeight.fsIn());
+            fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
+            // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
+            // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
+            fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
+            fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
+            // For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
+            // value of coverage that is used. In other words it is the coverage that is
+            // used in the interior of the rect after the ramp.
+            fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
+            fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
+
+            // Compute the coverage for the rect's width
+            fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
+                                   fsBuilder->fragmentPosition(), rectEdge.fsIn());
+            fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
+                                   rectEdge.fsIn(), rectEdge.fsIn());
+            fsBuilder->codeAppendf(
+                "\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
+                widthHeight.fsIn());
+
+            // Compute the coverage for the rect's height and merge with the width
+            fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
+                                   rectEdge.fsIn());
+            fsBuilder->codeAppendf(
+                    "\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
+                    widthHeight.fsIn());
+
+
+            fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+                                   (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("coverage")).c_str());
+        }
+
+        static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+
+        virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
+
+    private:
+        typedef GrGLGeometryProcessor INHERITED;
+    };
+
+
+
+private:
+    GrRectEffect()
+        : fInRectEdge(this->addVertexAttrib(GrShaderVar("inRectEdge",
+                                                        kVec4f_GrSLType,
+                                                        GrShaderVar::kAttribute_TypeModifier)))
+        , fInWidthHeight(this->addVertexAttrib(
+                GrShaderVar("inWidthHeight",
+                            kVec2f_GrSLType,
+                            GrShaderVar::kAttribute_TypeModifier))) {
+        this->setWillReadFragmentPosition();
+    }
+
+    virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { return true; }
+
+    virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
+        inout->mulByUnknownAlpha();
+    }
+
+    const GrShaderVar& fInRectEdge;
+    const GrShaderVar& fInWidthHeight;
+
+    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
+
+    typedef GrGeometryProcessor INHERITED;
+};
+
+
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRectEffect);
+
+GrGeometryProcessor* GrRectEffect::TestCreate(SkRandom* random,
+                                              GrContext* context,
+                                              const GrDrawTargetCaps&,
+                                              GrTexture* textures[]) {
+    return GrRectEffect::Create();
+}
+
+///////////////////////////////////////////////////////////////////////////////
 
 namespace {
 extern const GrVertexAttrib gAARectAttribs[] = {
@@ -303,6 +548,155 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
     target->resetIndexSource();
 }
 
+namespace {
+
+// Rotated
+struct RectVertex {
+    SkPoint fPos;
+    SkPoint fCenter;
+    SkPoint fDir;
+    SkPoint fWidthHeight;
+};
+
+// Rotated
+extern const GrVertexAttrib gAARectVertexAttribs[] = {
+    { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
+    { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding }
+};
+
+// Axis Aligned
+struct AARectVertex {
+    SkPoint fPos;
+    SkPoint fOffset;
+    SkPoint fWidthHeight;
+};
+
+// Axis Aligned
+extern const GrVertexAttrib gAAAARectVertexAttribs[] = {
+    { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
+    { kVec4f_GrVertexAttribType, sizeof(SkPoint),   kGeometryProcessor_GrVertexAttribBinding },
+};
+
+};
+
+void GrAARectRenderer::shaderFillAARect(GrDrawTarget* target,
+                                        const SkRect& rect,
+                                        const SkMatrix& combinedMatrix) {
+    GrDrawState* drawState = target->drawState();
+
+    SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY());
+    combinedMatrix.mapPoints(&center, 1);
+
+    // compute transformed (0, 1) vector
+    SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] };
+    dir.normalize();
+
+    // compute transformed (width, 0) and (0, height) vectors
+    SkVector vec[2] = {
+      { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
+      { combinedMatrix[SkMatrix::kMSkewX],  combinedMatrix[SkMatrix::kMScaleY] }
+    };
+
+    SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_ScalarHalf;
+    SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_ScalarHalf;
+    drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVertexAttribs),
+                                                      sizeof(RectVertex));
+
+    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
+    if (!geo.succeeded()) {
+        SkDebugf("Failed to get space for vertices!\n");
+        return;
+    }
+
+    RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices());
+
+    GrGeometryProcessor* gp = GrRectEffect::Create();
+    drawState->setGeometryProcessor(gp)->unref();
+
+    for (int i = 0; i < 4; ++i) {
+        verts[i].fCenter = center;
+        verts[i].fDir = dir;
+        verts[i].fWidthHeight.fX = newWidth;
+        verts[i].fWidthHeight.fY = newHeight;
+    }
+
+    SkRect devRect;
+    combinedMatrix.mapRect(&devRect, rect);
+
+    SkRect devBounds = {
+        devRect.fLeft   - SK_ScalarHalf,
+        devRect.fTop    - SK_ScalarHalf,
+        devRect.fRight  + SK_ScalarHalf,
+        devRect.fBottom + SK_ScalarHalf
+    };
+
+    verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
+    verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
+    verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
+    verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
+
+    target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer());
+    target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
+    target->resetIndexSource();
+}
+
+void GrAARectRenderer::shaderFillAlignedAARect(GrDrawTarget* target,
+                                               const SkRect& rect,
+                                               const SkMatrix& combinedMatrix) {
+    GrDrawState* drawState = target->drawState();
+    SkASSERT(combinedMatrix.rectStaysRect());
+
+    drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARectVertexAttribs),
+                                                        sizeof(AARectVertex));
+
+    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
+    if (!geo.succeeded()) {
+        SkDebugf("Failed to get space for vertices!\n");
+        return;
+    }
+
+    AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices());
+
+    GrGeometryProcessor* gp = GrAlignedRectEffect::Create();
+    drawState->setGeometryProcessor(gp)->unref();
+
+    SkRect devRect;
+    combinedMatrix.mapRect(&devRect, rect);
+
+    SkRect devBounds = {
+        devRect.fLeft   - SK_ScalarHalf,
+        devRect.fTop    - SK_ScalarHalf,
+        devRect.fRight  + SK_ScalarHalf,
+        devRect.fBottom + SK_ScalarHalf
+    };
+
+    SkPoint widthHeight = {
+        SkScalarHalf(devRect.width()) + SK_ScalarHalf,
+        SkScalarHalf(devRect.height()) + SK_ScalarHalf
+    };
+
+    verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
+    verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY);
+    verts[0].fWidthHeight = widthHeight;
+
+    verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
+    verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY);
+    verts[1].fWidthHeight = widthHeight;
+
+    verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
+    verts[2].fOffset = widthHeight;
+    verts[2].fWidthHeight = widthHeight;
+
+    verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
+    verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY);
+    verts[3].fWidthHeight = widthHeight;
+
+    target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer());
+    target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
+    target->resetIndexSource();
+}
+
 void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
                                     const SkRect& rect,
                                     const SkMatrix& combinedMatrix,
index e39b87a..c6e3976 100644 (file)
@@ -44,7 +44,17 @@ public:
                     const SkRect& rect,
                     const SkMatrix& combinedMatrix,
                     const SkRect& devRect) {
+#ifdef SHADER_AA_FILL_RECT
+        if (combinedMatrix.rectStaysRect()) {
+            this->shaderFillAlignedAARect(gpu, target,
+                                          rect, combinedMatrix);
+        } else {
+            this->shaderFillAARect(gpu, target,
+                                   rect, combinedMatrix);
+        }
+#else
         this->geometryFillAARect(target, rect, combinedMatrix, devRect);
+#endif
     }
 
     void strokeAARect(GrDrawTarget* target,
@@ -66,6 +76,14 @@ private:
                             const SkMatrix& combinedMatrix,
                             const SkRect& devRect);
 
+    void shaderFillAARect(GrDrawTarget* target,
+                          const SkRect& rect,
+                          const SkMatrix& combinedMatrix);
+
+    void shaderFillAlignedAARect(GrDrawTarget* target,
+                                 const SkRect& rect,
+                                 const SkMatrix& combinedMatrix);
+
     void geometryStrokeAARect(GrDrawTarget* target,
                               const SkRect& devOutside,
                               const SkRect& devOutsideAssist,
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
deleted file mode 100644 (file)
index 8e93f37..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrDefaultGeoProcFactory.h"
-
-#include "gl/builders/GrGLProgramBuilder.h"
-#include "gl/GrGLGeometryProcessor.h"
-#include "GrDrawState.h"
-#include "GrTBackendProcessorFactory.h"
-
-/*
- * The default Geometry Processor simply takes position and multiplies it by the uniform view
- * matrix. It also leaves coverage untouched.  Behind the scenes, we may add per vertex color or
- * local coords.
- */
-class DefaultGeoProc : public GrGeometryProcessor {
-public:
-    static GrGeometryProcessor* Create() {
-        GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, ());
-        return SkRef(gDefaultGeoProc);
-    }
-
-    static const char* Name() { return "DefaultGeometryProcessor"; }
-
-    virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
-        return GrTBackendGeometryProcessorFactory<DefaultGeoProc>::getInstance();
-    }
-
-    class GLProcessor : public GrGLGeometryProcessor {
-    public:
-        GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
-            : INHERITED (factory) {}
-
-        virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
-            GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder();
-
-            // setup position varying
-            vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(),
-                            vs->inPosition());
-
-            // output coverage in FS(pass through)
-            GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
-            fs->codeAppendf("%s = %s;", args.fOutput, GrGLSLExpr4(args.fInput).c_str());
-        }
-
-        static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
-
-        virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
-
-    private:
-        typedef GrGLGeometryProcessor INHERITED;
-    };
-
-private:
-    DefaultGeoProc() {}
-
-    virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
-        return true;
-    }
-
-    virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
-    }
-
-    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
-
-    typedef GrFragmentProcessor INHERITED;
-};
-
-GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
-
-GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
-                                                GrContext*,
-                                                const GrDrawTargetCaps& caps,
-                                                GrTexture*[]) {
-    return DefaultGeoProc::Create();
-}
-
-// We use these arrays to customize our default GP.  We only need 4 because we omit coverage if
-// coverage is not requested in the flags to the create function.
-GrVertexAttrib kDefaultPositionGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                kPosition_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosColorGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                                  kPosition_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint),                   kColor_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosUVGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                    kPosition_GrVertexAttribBinding },
-    { kVec2f_GrVertexAttribType, sizeof(SkPoint),      kLocalCoord_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
-};
-
-GrVertexAttrib kDefaultPosColUVGeoProc[] = {
-    { kVec2f_GrVertexAttribType, 0,                                      kPosition_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, sizeof(SkPoint),                       kColor_GrVertexAttribBinding },
-    { kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor),      kLocalCoord_GrVertexAttribBinding },
-    { kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
-};
-
-static size_t get_size(GrDefaultGeoProcFactory::GPType flag) {
-    switch (flag) {
-        case GrDefaultGeoProcFactory::kPosition_GPType:
-            return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
-        case GrDefaultGeoProcFactory::kColor_GPType:
-            return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType);
-        case GrDefaultGeoProcFactory::kLocalCoord_GPType:
-            return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
-        case GrDefaultGeoProcFactory::kCoverage_GPType:
-            return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType);
-        default:
-            SkFAIL("Should never get here");
-            return 0;
-    }
-}
-
-const GrGeometryProcessor*
-GrDefaultGeoProcFactory::CreateAndSetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) {
-    SkASSERT(ds);
-    // always atleast position in the GP
-    size_t size = get_size(kPosition_GPType);
-    int count = 1;
-
-    bool hasColor = SkToBool(gpTypeFlags & kColor_GPType);
-    bool hasLocalCoord = SkToBool(gpTypeFlags & kLocalCoord_GPType);
-    bool hasCoverage = SkToBool(gpTypeFlags & kCoverage_GPType);
-
-    if (hasColor) {
-        size += get_size(kColor_GPType);
-        count++;
-        if (hasLocalCoord) {
-            size += get_size(kLocalCoord_GPType);
-            count++;
-            if (hasCoverage) {
-                size += get_size(kCoverage_GPType);
-                count++;
-                ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size);
-            } else {
-                ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size);
-
-            }
-        } else {
-            if (hasCoverage) {
-                size += get_size(kCoverage_GPType);
-                count++;
-                ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size);
-            } else {
-                ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size);
-            }
-        }
-    } else if (hasLocalCoord) {
-        size += get_size(kLocalCoord_GPType);
-        count++;
-        if (hasCoverage) {
-            size += get_size(kCoverage_GPType);
-            count++;
-            ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size);
-        } else {
-            ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size);
-        }
-    } else if (hasCoverage) {
-        size += get_size(kCoverage_GPType);
-        count++;
-        ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
-    } else {
-        // Just position
-        ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
-    }
-    return DefaultGeoProc::Create();
-}
-
-const GrGeometryProcessor* GrDefaultGeoProcFactory::Create() {
-    return DefaultGeoProc::Create();
-}
diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h
deleted file mode 100644 (file)
index 26ce662..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrDefaultGeoProcFactory_DEFINED
-#define GrDefaultGeoProcFactory_DEFINED
-
-#include "GrGeometryProcessor.h"
-
-class GrDrawState;
-
-/*
- * A factory for creating default Geometry Processors which simply multiply position by the uniform
- * view matrix and wire through color, coverage, UV coords if requested.  Right now this is only
- * used in the creation of optimized draw states because adding default GPs to the drawstate can
- * interfere with batching due to updating the drawstate.
- * TODO When we track geometry state separately from the draw state, we should be able use a default
- * GP with every draw call
- */
-class GrDefaultGeoProcFactory {
-public:
-    // Structs for adding vertex attributes
-    struct PositionAttr {
-        SkPoint fPosition;
-    };
-
-    struct PositionCoverageAttr {
-        SkPoint fPosition;
-        GrColor fCoverage;
-    };
-
-    struct PositionColorAttr {
-        SkPoint fPosition;
-        SkColor fColor;
-    };
-
-    struct PositionColorCoverageAttr {
-        SkPoint fPosition;
-        SkColor fColor;
-        GrColor fCoverage;
-    };
-
-    struct PositionLocalCoordAttr {
-        SkPoint fPosition;
-        SkPoint fLocalCoord;
-    };
-
-    struct PositionLocalCoordCoverageAttr {
-        SkPoint fPosition;
-        SkPoint fLocalCoord;
-        GrColor fCoverage;
-    };
-
-    struct PositionColorLocalCoordAttr {
-        SkPoint fPosition;
-        GrColor fColor;
-        SkPoint fLocalCoord;
-    };
-
-    struct PositionColorLocalCoordCoverage {
-        SkPoint fPosition;
-        GrColor fColor;
-        SkPoint fLocalCoord;
-        GrColor fCoverage;
-    };
-
-    enum GPType {
-        kPosition_GPType = 0x0, // we ALWAYS have position
-        kColor_GPType = 0x01,
-        kLocalCoord_GPType = 0x02,
-        kCoverage_GPType= 0x04,
-        kLastGPType = kCoverage_GPType
-    };
-
-    // YOU MUST UNREF
-    static const GrGeometryProcessor* CreateAndSetAttribs(GrDrawState*, uint32_t GPTypeFlags);
-    static const GrGeometryProcessor* Create();
-};
-
-#endif
index a9d8ec4..529e9ed 100644 (file)
@@ -7,10 +7,9 @@
 
 #include "GrOptDrawState.h"
 
-#include "GrDefaultGeoProcFactory.h"
 #include "GrDrawState.h"
 #include "GrDrawTargetCaps.h"
-#include "GrGpu.h"
+#include "gl/GrGpuGL.h"
 
 GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
                                BlendOptFlags blendOptFlags,
@@ -64,10 +63,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
     // Copy GeometryProcesssor from DS or ODS
     if (drawState.hasGeometryProcessor()) {
         fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
-    } else if (!GrGpu::IsPathRenderingDrawType(drawType)) {
-        // Install default GP, this will be ignored if we are rendering with fragment shader only
-        // TODO(joshualitt) rendering code should do this
-        fGeometryProcessor.reset(GrDefaultGeoProcFactory::Create());
     } else {
         fGeometryProcessor.reset(NULL);
     }
index c06909d..4575287 100644 (file)
@@ -100,10 +100,6 @@ public:
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
             vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleEdge().c_str());
 
-            // setup position varying
-            vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), vsBuilder->inPosition());
-
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
             fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0);", v.fsIn());
@@ -223,10 +219,6 @@ public:
             vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
                                    ellipseEffect.inEllipseRadii().c_str());
 
-            // setup position varying
-            vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), vsBuilder->inPosition());
-
             // for outer curve
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
@@ -373,10 +365,6 @@ public:
             vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
                                    ellipseEffect.inEllipseOffsets1().c_str());
 
-            // setup position varying
-            vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                                   vsBuilder->uViewM(), vsBuilder->inPosition());
-
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
index 3de1dcf..79798b6 100644 (file)
@@ -38,7 +38,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
  * manually adjusted.
  */
 static const int kFPFactoryCount = 37;
-static const int kGPFactoryCount = 14;
+static const int kGPFactoryCount = 15;
 
 template<>
 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
index 26049b3..196168c 100644 (file)
@@ -44,10 +44,6 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
     vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inConicCoeffs.c_str());
 
-    // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
-                           vsBuilder->inPosition());
-
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppend("float edgeAlpha;");
 
@@ -188,10 +184,6 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
     const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
     vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inHairQuadEdge.c_str());
 
-    // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
-                           vsBuilder->inPosition());
-
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppendf("float edgeAlpha;");
 
@@ -318,10 +310,6 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
     const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
     vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inCubicCoeffs.c_str());
 
-    // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
-                           vsBuilder->inPosition());
-
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 
     GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
index 77e7994..afa0754 100644 (file)
@@ -31,10 +31,6 @@ public:
         const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
         vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inTextureCoords.c_str());
 
-        // setup position varying
-        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), vsBuilder->inPosition());
-
         GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
         fsBuilder->codeAppendf("%s = ", args.fOutput);
         fsBuilder->appendTextureLookupAndModulate(args.fInput,
index 65ba848..f2e4438 100644 (file)
@@ -520,10 +520,6 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
     vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str());
 
-    // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
-                           vsBuilder->inPosition());
-
     // transforms all points so that we can compare them to our test circle
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
@@ -727,10 +723,6 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) {
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
     vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str());
 
-    // setup position varying
-    vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
-                           vsBuilder->inPosition());
-
     // transforms all points so that we can compare them to our test rect
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
index 0c7a9a3..b977698 100755 (executable)
@@ -45,10 +45,6 @@ public:
         GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
         vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
 
-        // setup position varying
-        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), vsBuilder->inPosition());
-
         const char* textureSizeUniName = NULL;
         fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                                kVec2f_GrSLType, "TextureSize",
@@ -260,10 +256,6 @@ public:
         GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
         vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
 
-        // setup position varying
-        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), vsBuilder->inPosition());
-
         const char* textureSizeUniName = NULL;
         fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                               kVec2f_GrSLType, "TextureSize",
@@ -418,10 +410,6 @@ public:
         GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
         vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
 
-        // setup position varying
-        vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
-                               vsBuilder->uViewM(), vsBuilder->inPosition());
-
         const char* textureSizeUniName = NULL;
         // width, height, 1/(3*width)
         fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
index 99671c1..b031a40 100644 (file)
@@ -106,10 +106,6 @@ public:
         return fExpr.c_str();
     }
 
-    bool isValid() const {
-        return kFullExpr_ExprType != fType || !fExpr.isEmpty();
-    }
-
 protected:
     /** Constructs an invalid expression.
      * Useful only as a return value from functions that never actually return
@@ -170,6 +166,10 @@ protected:
         fExpr.appendf(format, in0, in1);
     }
 
+    bool isValid() const {
+        return kFullExpr_ExprType != fType || !fExpr.isEmpty();
+    }
+
     /** Returns expression casted to another type.
      * Generic implementation that is called for non-trivial cases of casts. */
     template <typename T>
index de4a1d5..8fc6020 100644 (file)
@@ -57,11 +57,9 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
     bool hasVertexShader = !(header.fUseNvpr &&
                              gpu->glPathRendering()->texturingMode() ==
                              GrGLPathRendering::FixedFunction_TexturingMode);
-
     if (hasVertexShader) {
-        pb->fVS.setupUniformViewMatrix();
-        pb->fVS.setupPositionAndLocalCoords();
-
+        pb->fVS.setupLocalCoords();
+        pb->fVS.transformGLToSkiaCoords();
         if (header.fEmitsPointSize) {
             pb->fVS.codeAppend("gl_PointSize = 1.0;");
         }
@@ -77,10 +75,10 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
     // remove this cast to a vec4.
     GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
 
-    pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4);
+    pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4);
 
     if (hasVertexShader) {
-        pb->fVS.transformToNormalizedDeviceSpace();
+        pb->fVS.transformSkiaToGLCoords();
     }
 
     // write the secondary color output if necessary
@@ -173,17 +171,7 @@ GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32
     UniformInfo& uni = fUniforms.push_back();
     uni.fVariable.setType(type);
     uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
-    // TODO this is a bit hacky, lets think of a better way.  Basically we need to be able to use
-    // the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB
-    // exactly what name it wants to use for the uniform view matrix.  If we prefix anythings, then
-    // the names will mismatch.  I think the correct solution is to have all GPs which need the
-    // uniform view matrix, they should upload the view matrix in their setData along with regular
-    // uniforms.
-    char prefix = 'u';
-    if ('u' == name[0]) {
-        prefix = '\0';
-    }
-    this->nameVariable(uni.fVariable.accessName(), prefix, name);
+    this->nameVariable(uni.fVariable.accessName(), 'u', name);
     uni.fVariable.setArrayCount(count);
     uni.fVisibility = visibility;
 
@@ -242,40 +230,23 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
     }
 }
 
-void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
+void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
+                                             GrGLSLExpr4* inputColor,
                                              GrGLSLExpr4* inputCoverage) {
-    // We need to collect all of the transforms to thread them through the GP in the case of GPs
-    // which use additional shader stages between the VS and the FS.  To do this we emit a dummy
-    // input coverage
-    GrGLSLExpr4 coverageInput = *inputCoverage;
-    if (fOptState.hasGeometryProcessor()) {
-        AutoStageAdvance adv(this);
-        SkString outColorName;
-        this->nameVariable(&outColorName, '\0', "gpOutput");
-        coverageInput = outColorName;
-    }
-    GrGLSLExpr4 gpOutput = coverageInput;
-
-    // Emit fragment processors
     fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
-    int numProcs = fOptState.numFragmentStages();
-    this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
-    this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs,  &coverageInput);
-
-    // We have to save the existing code stack, and then append it to the fragment shader code
-    // after emiting the GP
-    if (fOptState.hasGeometryProcessor()) {
-        SkString existingCode(fFS.fCode);
-        fFS.fCode.reset();
-        const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor();
+    int numProcs = optState.numFragmentStages();
+    this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
+    if (optState.hasGeometryProcessor()) {
+        const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
         fVS.emitAttributes(gp);
         ProcKeyProvider keyProvider(&fDesc,
                                     ProcKeyProvider::kGeometry_ProcessorType,
                                     GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
-        this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &gpOutput);
-        fFS.fCode.append(existingCode);
+        GrGLSLExpr4 output;
+        this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
+        *inputCoverage = output;
     }
-    *inputCoverage = coverageInput;
+    this->emitAndInstallFragProcs(optState.numColorStages(), numProcs,  inputCoverage);
 }
 
 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
@@ -301,14 +272,9 @@ void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
     // Program builders have a bit of state we need to clear with each effect
     AutoStageAdvance adv(this);
 
-    // create var to hold stage result.  If we already have a valid output name, just use that
-    // otherwise create a new mangled one.
+    // create var to hold stage result
     SkString outColorName;
-    if (output->isValid()) {
-        outColorName = output->c_str();
-    } else {
-        this->nameVariable(&outColorName, '\0', "output");
-    }
+    this->nameVariable(&outColorName, '\0', "output");
     fFS.codeAppendf("vec4 %s;", outColorName.c_str());
     *output = outColorName;
 
@@ -349,8 +315,8 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentStage& fs,
 
 void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
                                             const GrProcessorKey& key,
-                                            const char* outCoverage,
-                                            const char* inCoverage) {
+                                            const char* outColor,
+                                            const char* inColor) {
     SkASSERT(!fGeometryProcessor);
     fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
 
@@ -359,7 +325,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
     this->emitSamplers(gp, &samplers, fGeometryProcessor);
 
-    GrGLGeometryProcessor::EmitArgs args(this, gp, key, outCoverage, inCoverage, samplers);
+    GrGLGeometryProcessor::EmitArgs args(this, gp, key, outColor, inColor, samplers);
     fGeometryProcessor->fGLProc->emitCode(args);
 
     // We have to check that effects and the code they emit are consistent, ie if an effect
@@ -408,13 +374,23 @@ void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
             suffixedVaryingName.appendf("_%i", t);
             varyingName = suffixedVaryingName.c_str();
         }
-        const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
-                                                     fVS.positionAttribute().c_str() :
-                                                     fVS.localCoordsAttribute().c_str();
         GrGLVertToFrag v(varyingType);
-        this->addCoordVarying(varyingName, &v, uniName, coords);
+        this->addVarying(varyingName, &v);
 
+        const GrGLShaderVar& coords =
+                kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
+                                          fVS.positionAttribute() :
+                                          fVS.localCoordsAttribute();
+
+        // varying = matrix * coords (logically)
         SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+        if (kVec2f_GrSLType == varyingType) {
+            fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
+                            v.vsOut(), uniName, coords.c_str());
+        } else {
+            fVS.codeAppendf("%s = %s * vec3(%s, 1);",
+                            v.vsOut(), uniName, coords.c_str());
+        }
         SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
                                (SkString(v.fsIn()), varyingType));
     }
index a44fa91..4bcf50b 100644 (file)
@@ -241,7 +241,8 @@ protected:
     // generating stage code.
     void nameVariable(SkString* out, char prefix, const char* name);
     void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr1* inputCoverage);
-    void emitAndInstallProcs(GrGLSLExpr4* inputColor,
+    void emitAndInstallProcs(const GrOptDrawState& optState,
+                             GrGLSLExpr4* inputColor,
                              GrGLSLExpr4* inputCoverage);
     void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
     template <class Proc>
@@ -258,8 +259,8 @@ protected:
                             const char* inColor);
     void emitAndInstallProc(const GrGeometryProcessor&,
                             const GrProcessorKey&,
-                            const char* outCoverage,
-                            const char* inCoverage);
+                            const char* outColor,
+                            const char* inColor);
     void verify(const GrGeometryProcessor&);
     void verify(const GrFragmentProcessor&);
     void emitSamplers(const GrProcessor&,
@@ -313,22 +314,6 @@ protected:
     void enterStage() { fOutOfStage = false; }
     int stageIndex() const { return fStageIndex; }
 
-    struct TransformVarying {
-        TransformVarying(const GrGLVarying& v, const char* uniName, const char* sourceCoords)
-            : fV(v), fUniName(uniName), fSourceCoords(sourceCoords) {}
-        GrGLVarying fV;
-        SkString fUniName;
-        SkString fSourceCoords;
-    };
-
-    void addCoordVarying(const char* name, GrGLVarying* v, const char* uniName,
-                         const char* sourceCoords) {
-        this->addVarying(name, v);
-        fCoordVaryings.push_back(TransformVarying(*v, uniName, sourceCoords));
-    }
-
-    const char* rtAdjustment() const { return "rtAdjustment"; }
-
     // number of each input/output type in a single allocation block, used by many builders
     static const int kVarsPerBlock;
 
@@ -346,7 +331,6 @@ protected:
     const GrProgramDesc& fDesc;
     GrGpuGL* fGpu;
     UniformInfoArray fUniforms;
-    SkSTArray<16, TransformVarying, true> fCoordVaryings;
 
     friend class GrGLShaderBuilder;
     friend class GrGLVertexBuilder;
index 7af5ce9..2bef113 100644 (file)
@@ -20,7 +20,6 @@ GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
     : INHERITED(program)
     , fPositionVar(NULL)
     , fLocalCoordsVar(NULL)
-    , fRtAdjustName(NULL)
     , fEffectAttribOffset(0) {
 }
 
@@ -32,22 +31,9 @@ void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
     v->fVsOut = fOutputs.back().getName().c_str();
 }
 
-void GrGLVertexBuilder::setupUniformViewMatrix() {
-    fProgramBuilder->fUniformHandles.fViewMatrixUni =
-            fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
-                                        kMat33f_GrSLType,
-                                        this->uViewM());
-}
-
-void GrGLVertexBuilder::setupPositionAndLocalCoords() {
-    // Setup position
-    this->codeAppendf("vec3 %s;", this->glPosition());
-
-    // setup position and local coords attribute
+void GrGLVertexBuilder::setupLocalCoords() {
     fPositionVar = &fInputs.push_back();
-    fPositionVar->set(kVec2f_GrSLType,
-                      GrGLShaderVar::kAttribute_TypeModifier,
-                      this->inPosition());
+    fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "inPosition");
     if (-1 != fProgramBuilder->header().fLocalCoordAttributeIndex) {
         fLocalCoordsVar = &fInputs.push_back();
         fLocalCoordsVar->set(kVec2f_GrSLType,
@@ -59,6 +45,18 @@ void GrGLVertexBuilder::setupPositionAndLocalCoords() {
     fEffectAttribOffset = fInputs.count();
 }
 
+void GrGLVertexBuilder::transformGLToSkiaCoords() {
+    const char* viewMName;
+    fProgramBuilder->fUniformHandles.fViewMatrixUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+                                        kMat33f_GrSLType,
+                                        "ViewM",
+                                        &viewMName);
+
+    // Transform the position into Skia's device coords.
+    this->codeAppendf("vec3 pos3 = %s * vec3(%s, 1);", viewMName, fPositionVar->c_str());
+}
+
 void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out) {
     GrGLVertToFrag v(kFloat_GrSLType);
     fProgramBuilder->addVarying(inName, &v);
@@ -93,34 +91,17 @@ void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) {
     }
 }
 
-void GrGLVertexBuilder::transformToNormalizedDeviceSpace() {
-    // setup RT Uniform
+void GrGLVertexBuilder::transformSkiaToGLCoords() {
+    const char* rtAdjustName;
     fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
             fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
                                         kVec4f_GrSLType,
-                                        fProgramBuilder->rtAdjustment(),
-                                        &fRtAdjustName);
-    // Wire transforms
-    SkTArray<GrGLProgramBuilder::TransformVarying, true>& transVs = fProgramBuilder->fCoordVaryings;
-    int transformCount = transVs.count();
-    for (int i = 0; i < transformCount; i++) {
-        const char* coords = transVs[i].fSourceCoords.c_str();
-
-        // varying = matrix * coords (logically)
-        const GrGLVarying& v = transVs[i].fV;
-        if (kVec2f_GrSLType == v.fType) {
-            this->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.fVsOut, transVs[i].fUniName.c_str(),
-                              coords);
-        } else {
-            this->codeAppendf("%s = %s * vec3(%s, 1);", v.fVsOut, transVs[i].fUniName.c_str(),
-                              coords);
-        }
-    }
+                                        "rtAdjustment",
+                                        &rtAdjustName);
 
     // Transform from Skia's device coords to GL's normalized device coords.
-    this->codeAppendf("gl_Position = vec4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);",
-                      this->glPosition(), fRtAdjustName, this->glPosition(), fRtAdjustName,
-                      this->glPosition());
+    this->codeAppendf("gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);",
+                    rtAdjustName, rtAdjustName);
 }
 
 void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
index 7d6d95e..2f14bd7 100644 (file)
@@ -31,15 +31,6 @@ public:
       */
     const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
 
-    /** returns the expected position output */
-    const char* glPosition() const { return "pos3"; }
-
-    /** returns the expected uviewM matrix */
-    // TODO all of this fixed function stuff can live on the GP/PP
-    const char* uViewM() const { return "uViewM"; }
-    const char* inPosition() const { return "inPosition"; }
-
-
 private:
     /*
      * Internal call for GrGLProgramBuilder.addVarying
@@ -49,13 +40,12 @@ private:
     /*
      * private helpers for compilation by GrGLProgramBuilder
      */
-    void transformToNormalizedDeviceSpace();
-    //TODO GP itself should setup the uniform view matrix
-    void setupUniformViewMatrix();
-    void setupPositionAndLocalCoords();
+    void setupLocalCoords();
+    void transformGLToSkiaCoords();
     void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out);
     void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out);
     void emitAttributes(const GrGeometryProcessor& gp);
+    void transformSkiaToGLCoords();
     void bindVertexAttributes(GrGLuint programID);
     bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
 
@@ -71,7 +61,6 @@ private:
 
     GrGLShaderVar*                      fPositionVar;
     GrGLShaderVar*                      fLocalCoordsVar;
-    const char*                         fRtAdjustName;
     int                                 fEffectAttribOffset;
 
     friend class GrGLProgramBuilder;