Remove GP from drawstate, revision of invariant output for GP
authorjoshualitt <joshualitt@chromium.org>
Wed, 10 Dec 2014 21:48:57 +0000 (13:48 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 10 Dec 2014 21:48:57 +0000 (13:48 -0800)
BUG=skia:

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

51 files changed:
expectations/gm/ignored-tests.txt
gm/beziereffects.cpp
gm/convexpolyeffect.cpp
include/gpu/GrFragmentProcessor.h
include/gpu/GrInvariantOutput.h
include/gpu/GrProcessor.h
include/gpu/GrXferProcessor.h
src/effects/SkAlphaThresholdFilter.cpp
src/effects/SkBlurMaskFilter.cpp
src/effects/SkLightingImageFilter.cpp
src/effects/gradients/SkGradientShader.cpp
src/gpu/GrAAConvexPathRenderer.cpp
src/gpu/GrAADistanceFieldPathRenderer.cpp
src/gpu/GrAAHairLinePathRenderer.cpp
src/gpu/GrAAHairLinePathRenderer.h
src/gpu/GrAARectRenderer.cpp
src/gpu/GrBitmapTextContext.cpp
src/gpu/GrContext.cpp
src/gpu/GrDefaultGeoProcFactory.cpp
src/gpu/GrDefaultPathRenderer.cpp
src/gpu/GrDistanceFieldTextContext.cpp
src/gpu/GrDrawState.cpp
src/gpu/GrDrawState.h
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrGeometryProcessor.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrInOrderDrawBuffer.h
src/gpu/GrOptDrawState.cpp
src/gpu/GrOptDrawState.h
src/gpu/GrOvalRenderer.cpp
src/gpu/GrProcOptInfo.cpp
src/gpu/GrProcOptInfo.h
src/gpu/GrProcessor.cpp
src/gpu/GrStencilAndCoverPathRenderer.cpp
src/gpu/GrStencilAndCoverTextContext.cpp
src/gpu/effects/GrBezierEffect.h
src/gpu/effects/GrBicubicEffect.cpp
src/gpu/effects/GrBitmapTextGeoProc.cpp
src/gpu/effects/GrBitmapTextGeoProc.h
src/gpu/effects/GrConvexPolyEffect.cpp
src/gpu/effects/GrConvolutionEffect.h
src/gpu/effects/GrDashingEffect.cpp
src/gpu/effects/GrDistanceFieldTextureEffect.cpp
src/gpu/effects/GrDistanceFieldTextureEffect.h
src/gpu/effects/GrMatrixConvolutionEffect.h
src/gpu/effects/GrOvalEffect.cpp
src/gpu/effects/GrRRectEffect.cpp
src/gpu/effects/GrSingleTextureEffect.h
src/gpu/effects/GrTextureDomain.cpp
tests/GLProgramsTest.cpp

index 6c93e7a..bdce6d9 100644 (file)
@@ -72,3 +72,8 @@ pictureimagefilter
 clipped-bitmap-shaders-clamp
 clipped-bitmap-shaders-clamp-hq
 
+# joshualitt
+path_primitive
+xfermodes3
+multipicturedraw_sierpinski_tiled
+multipicturedraw_sierpinski_simple
index 6f19ac9..e7e63ea 100644 (file)
@@ -164,11 +164,10 @@ protected:
                         verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
                     }
 
-                    ds.setGeometryProcessor(gp);
                     ds.setRenderTarget(rt);
 
                     tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
-                    tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+                    tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0,4,6);
                 }
                 ++col;
                 if (numCols == col) {
@@ -320,11 +319,10 @@ protected:
                         verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
                     }
 
-                    ds.setGeometryProcessor(gp);
                     ds.setRenderTarget(rt);
 
                     tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
-                    tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+                    tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0,4,6);
                 }
                 ++col;
                 if (numCols == col) {
@@ -505,11 +503,10 @@ protected:
                     GrPathUtils::QuadUVMatrix DevToUV(pts);
                     DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
 
-                    ds.setGeometryProcessor(gp);
                     ds.setRenderTarget(rt);
 
                     tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
-                    tt.target()->drawIndexed(&ds, kTriangles_GrPrimitiveType, 0, 0, 4, 6);
+                    tt.target()->drawIndexed(&ds, gp, kTriangles_GrPrimitiveType, 0, 0, 4, 6);
                 }
                 ++col;
                 if (numCols == col) {
index 365660d..03b9ad2 100644 (file)
@@ -133,8 +133,8 @@ protected:
                 }
 
                 GrDrawState ds;
-                const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(0xff000000);
-                ds.setGeometryProcessor(gp)->unref();
+                SkAutoTUnref<const GrGeometryProcessor> gp(
+                        GrDefaultGeoProcFactory::Create(0xff000000));
                 ds.addCoverageProcessor(fp);
                 ds.setIdentityViewMatrix();
                 ds.setRenderTarget(rt);
@@ -150,7 +150,7 @@ protected:
                 bounds.toQuad(verts);
 
                 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
-                tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+                tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
 
                 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
             }
@@ -190,8 +190,8 @@ protected:
                 }
 
                 GrDrawState ds;
-                const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(0xff000000);
-                ds.setGeometryProcessor(gp)->unref();
+                SkAutoTUnref<const GrGeometryProcessor> gp(
+                        GrDefaultGeoProcFactory::Create(0xff000000));
                 ds.addCoverageProcessor(fp);
                 ds.setIdentityViewMatrix();
                 ds.setRenderTarget(rt);
@@ -205,7 +205,7 @@ protected:
                 bounds.toQuad(verts);
 
                 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
-                tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+                tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
 
                 x += SkScalarCeilToScalar(rect.width() + 10.f);
             }
index 3f308d7..0c15599 100644 (file)
@@ -67,6 +67,16 @@ public:
         return this->onIsEqual(that);
     }
 
+    /**
+     * This function is used to perform optimizations. When called the invarientOuput param
+     * indicate whether the input components to this processor in the FS will have known values.
+     * In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent
+     * member indicates whether the input will be 1 or 4 bytes. The function updates the members of
+     * inout to indicate known values of its output. A component of the color member only has
+     * meaning if the corresponding bit in validFlags is set.
+     */
+    void computeInvariantOutput(GrInvariantOutput* inout) const;
+
 protected:
     /**
      * Fragment Processor subclasses call this from their constructor to register coordinate
@@ -101,6 +111,11 @@ protected:
      */
     void setWillNotUseInputColor() { fWillUseInputColor = false; }
 
+    /**
+     * Subclass implements this to support getConstantColorComponents(...).
+     */
+    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
+
 private:
     /**
      * Subclass implements this to support isEqual(). It will only be called if it is known that
index 1d3eda1..269748a 100644 (file)
 
 #include "GrColor.h"
 
+struct GrInitInvariantOutput {
+    GrInitInvariantOutput()
+        : fValidFlags(0)
+        , fColor(0)
+        , fIsSingleComponent(false)
+        , fIsLCDCoverage(false) {}
+
+    void setKnownFourComponents(GrColor color) {
+        fColor = color;
+        fValidFlags = kRGBA_GrColorComponentFlags;
+        fIsSingleComponent = false;
+    }
+
+    void setUnknownFourComponents() {
+        fValidFlags = 0;
+        fIsSingleComponent = false;
+    }
+
+    void setUnknownOpaqueFourComponents() {
+        fColor = 0xff << GrColor_SHIFT_A;
+        fValidFlags = kA_GrColorComponentFlag;
+        fIsSingleComponent = false;
+    }
+
+    void setKnownSingleComponent(uint8_t alpha) {
+        fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
+        fValidFlags = kRGBA_GrColorComponentFlags;
+        fIsSingleComponent = true;
+    }
+
+    void setUnknownSingleComponent() {
+        fValidFlags = 0;
+        fIsSingleComponent = true;
+    }
+
+    void setUsingLCDCoverage() { fIsLCDCoverage = true; }
+
+    uint32_t fValidFlags;
+    GrColor fColor;
+    bool fIsSingleComponent;
+    bool fIsLCDCoverage; // Temorary data member until texture pixel configs are updated
+};
+
 class GrInvariantOutput {
 public:
     GrInvariantOutput(GrColor color, GrColorComponentFlags flags, bool isSingleComponent)
@@ -20,6 +63,14 @@ public:
         , fWillUseInputColor(true)
         , fIsLCDCoverage(false) {}
 
+    GrInvariantOutput(const GrInitInvariantOutput& io)
+        : fColor(io.fColor)
+        , fValidFlags(io.fValidFlags)
+        , fIsSingleComponent(io.fIsSingleComponent)
+        , fNonMulStageFound(false)
+        , fWillUseInputColor(false)
+        , fIsLCDCoverage(io.fIsLCDCoverage) {}
+
     virtual ~GrInvariantOutput() {}
 
     enum ReadInput {
@@ -27,18 +78,18 @@ public:
         kWillNot_ReadInput,
     };
 
-    void mulByUnknownOpaqueColor() {
+    void mulByUnknownOpaqueFourComponents() {
         if (this->isOpaque()) {
             fValidFlags = kA_GrColorComponentFlag;
             fIsSingleComponent = false;
         } else {
             // Since the current state is not opaque we no longer care if the color being
             // multiplied is opaque.
-            this->mulByUnknownColor(); 
+            this->mulByUnknownFourComponents();
         }
     }
 
-    void mulByUnknownColor() {
+    void mulByUnknownFourComponents() {
         if (this->hasZeroAlpha()) {
             this->internalSetToTransparentBlack();
         } else {
@@ -46,7 +97,7 @@ public:
         }
     }
 
-    void mulByUnknownAlpha() {
+    void mulByUnknownSingleComponent() {
         if (this->hasZeroAlpha()) {
             this->internalSetToTransparentBlack();
         } else {
@@ -55,7 +106,7 @@ public:
         }
     }
 
-    void mulByKnownAlpha(uint8_t alpha) {
+    void mulByKnownSingleComponent(uint8_t alpha) {
         if (this->hasZeroAlpha() || 0 == alpha) {
             this->internalSetToTransparentBlack();
         } else {
@@ -122,6 +173,15 @@ private:
         fWillUseInputColor = true;
     }
 
+    void reset(const GrInitInvariantOutput& io) {
+        fColor = io.fColor;
+        fValidFlags = io.fValidFlags;
+        fIsSingleComponent = io.fIsSingleComponent;
+        fNonMulStageFound = false;
+        fWillUseInputColor = true;
+        fIsLCDCoverage = io.fIsLCDCoverage;
+    }
+
     void internalSetToTransparentBlack() {
         fValidFlags = kRGBA_GrColorComponentFlags;
         fColor = 0;
index 6a497e7..8a8d685 100644 (file)
@@ -61,16 +61,6 @@ public:
 
     virtual ~GrProcessor();
 
-    /**
-     * This function is used to perform optimizations. When called the invarientOuput param
-     * indicate whether the input components to this processor in the FS will have known values.
-     * In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent
-     * member indicates whether the input will be 1 or 4 bytes. The function updates the members of
-     * inout to indicate known values of its output. A component of the color member only has
-     * meaning if the corresponding bit in validFlags is set.
-     */
-    void computeInvariantOutput(GrInvariantOutput* inout) const; 
-
     /** Human-meaningful string to identify this prcoessor; may be embedded
         in generated shader code. */
     virtual const char* name() const = 0;
@@ -132,11 +122,6 @@ protected:
     uint32_t fClassID;
 
 private:
-    /** 
-     * Subclass implements this to support getConstantColorComponents(...).
-     */
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
-    
     static uint32_t GenClassID() {
         // fCurrProcessorClassID has been initialized to kIllegalProcessorClassID. The
         // atomic inc returns the old value not the incremented value. So we add
index 696359b..db0d6e8 100644 (file)
@@ -134,6 +134,11 @@ protected:
      */
     void setWillReadDstColor() { fWillReadDstColor = true; }
 
+    /**
+     * Subclass implements this to support getConstantColorComponents(...).
+     */
+    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
+
 private:
     virtual bool onIsEqual(const GrXferProcessor&) const = 0;
 
index 2703a24..317f6f0 100644 (file)
@@ -230,11 +230,11 @@ bool AlphaThresholdEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
 
 void AlphaThresholdEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
     if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
-        inout->mulByUnknownAlpha();
+        inout->mulByUnknownSingleComponent();
     } else if (GrPixelConfigIsOpaque(this->texture(0)->config()) && fOuterThreshold >= 1.f) {
-        inout->mulByUnknownOpaqueColor();
+        inout->mulByUnknownOpaqueFourComponents();
     } else {
-        inout->mulByUnknownColor();
+        inout->mulByUnknownFourComponents();
     }
 }
 
index feb321a..7c0bbb8 100644 (file)
@@ -817,7 +817,7 @@ bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
 }
 
 void GrRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
@@ -979,7 +979,7 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
 }
 
 void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture)
index adac45b..e53cb02 100644 (file)
@@ -349,7 +349,7 @@ protected:
 
     virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
         // lighting shaders are complicated. We just throw up our hands.
-        inout->mulByUnknownColor();
+        inout->mulByUnknownFourComponents();
     }
 
 private:
index 0c14794..3b73eae 100644 (file)
@@ -1158,9 +1158,9 @@ bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const {
 
 void GrGradientEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
     if (fIsOpaque) {
-        inout->mulByUnknownOpaqueColor();
+        inout->mulByUnknownOpaqueFourComponents();
     } else {
-        inout->mulByUnknownColor();
+        inout->mulByUnknownFourComponents();
     }
 }
 
index 44782dd..0007e33 100644 (file)
@@ -596,8 +596,8 @@ private:
         return true;
     }
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
+        out->setUnknownSingleComponent();
     }
 
     const GrAttribute* fInPosition;
@@ -679,8 +679,7 @@ bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
     // Our computed verts should all be within one pixel of the segment control points.
     devBounds.outset(SK_Scalar1, SK_Scalar1);
 
-    GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create(color);
-    drawState->setGeometryProcessor(quadProcessor)->unref();
+    SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(color));
 
     GrDrawTarget::AutoReleaseGeometry arg(target, vCount, quadProcessor->getVertexStride(), iCount);
     SkASSERT(quadProcessor->getVertexStride() == sizeof(QuadVertex));
@@ -709,6 +708,7 @@ bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
     for (int i = 0; i < draws.count(); ++i) {
         const Draw& draw = draws[i];
         target->drawIndexed(drawState,
+                            quadProcessor,
                             kTriangles_GrPrimitiveType,
                             vOffset,  // start vertex
                             0,        // start index
index 7a7c1e4..f79d96b 100755 (executable)
@@ -323,14 +323,13 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
     flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
 
     GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
-    if (flags != fEffectFlags || fCachedGeometryProcessor->getColor() != color) {
+    if (flags != fEffectFlags || fCachedGeometryProcessor->color() != color) {
         fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color,
                                                                                    texture,
                                                                                    params,
                                                                                    flags));
         fEffectFlags = flags;
     }
-    drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
 
     void* vertices = NULL;
     bool success = target->reserveVertexAndIndexSpace(4,
@@ -372,7 +371,8 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
     
     vm.mapRect(&r);
     target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
-    target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &r);
+    target->drawIndexedInstances(drawState, fCachedGeometryProcessor.get(),
+                                 kTriangles_GrPrimitiveType, 1, 4, 6, &r);
     target->resetVertexSource();
     
     return true;
index 37150bd..a95f900 100644 (file)
@@ -644,6 +644,7 @@ void add_line(const SkPoint p[2],
 bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
                                               GrDrawState* drawState,
                                               uint8_t coverage,
+                                              size_t vertexStride,
                                               GrDrawTarget::AutoReleaseGeometry* arg,
                                               SkRect* devBounds,
                                               const SkPath& path,
@@ -653,9 +654,8 @@ bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
 
     int vertCnt = kLineSegNumVertices * lineCnt;
 
-    size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
-    SkASSERT(vstride == sizeof(LineVertex));
-    if (!arg->set(target, vertCnt, vstride,  0)) {
+    SkASSERT(vertexStride == sizeof(LineVertex));
+    if (!arg->set(target, vertCnt, vertexStride,  0)) {
         return false;
     }
 
@@ -839,13 +839,14 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
         uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType |
                            GrDefaultGeoProcFactory::kCoverage_GPType;
         GrDrawState::AutoRestoreEffects are(drawState);
-        drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color,
-                                                                        gpFlags,
-                                                                        newCoverage))->unref();
+        SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create(color,
+                                                                                   gpFlags,
+                                                                                   newCoverage));
 
         if (!this->createLineGeom(target,
                                   drawState,
                                   newCoverage,
+                                  gp->getVertexStride(),
                                   &arg,
                                   &devBounds,
                                   path,
@@ -871,6 +872,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
             while (lines < lineCnt) {
                 int n = SkTMin(lineCnt - lines, kLineSegsNumInIdxBuffer);
                 target->drawIndexed(drawState,
+                                    gp,
                                     kTriangles_GrPrimitiveType,
                                     kLineSegNumVertices*lines,     // startV
                                     0,                             // startI
@@ -915,20 +917,20 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
                                             kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt));
 
         if (quadCnt > 0) {
-            GrGeometryProcessor* hairQuadProcessor =
+            SkAutoTUnref<GrGeometryProcessor> hairQuadProcessor(
                     GrQuadEffect::Create(color,
                                          kHairlineAA_GrProcessorEdgeType,
                                          *target->caps(),
-                                         newCoverage);
+                                         newCoverage));
             SkASSERT(hairQuadProcessor);
             GrDrawState::AutoRestoreEffects are(drawState);
             target->setIndexSourceToBuffer(fQuadsIndexBuffer);
 
-            drawState->setGeometryProcessor(hairQuadProcessor)->unref();
             int quads = 0;
             while (quads < quadCnt) {
                 int n = SkTMin(quadCnt - quads, kQuadsNumInIdxBuffer);
                 target->drawIndexed(drawState,
+                                    hairQuadProcessor,
                                     kTriangles_GrPrimitiveType,
                                     kQuadNumVertices*quads,               // startV
                                     0,                                    // startI
@@ -941,15 +943,16 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
 
         if (conicCnt > 0) {
             GrDrawState::AutoRestoreEffects are(drawState);
-            GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create(
-                    color, kHairlineAA_GrProcessorEdgeType, *target->caps(), newCoverage);
+            SkAutoTUnref<GrGeometryProcessor> hairConicProcessor(
+                    GrConicEffect::Create(color, kHairlineAA_GrProcessorEdgeType, *target->caps(),
+                                          newCoverage));
             SkASSERT(hairConicProcessor);
 
-            drawState->setGeometryProcessor(hairConicProcessor)->unref();
             int conics = 0;
             while (conics < conicCnt) {
                 int n = SkTMin(conicCnt - conics, kQuadsNumInIdxBuffer);
                 target->drawIndexed(drawState,
+                                    hairConicProcessor,
                                     kTriangles_GrPrimitiveType,
                                     kQuadNumVertices*(quadCnt + conics),  // startV
                                     0,                                    // startI
index 5d00e7e..5b7b785 100644 (file)
@@ -43,6 +43,7 @@ private:
     bool createLineGeom(GrDrawTarget* target,
                         GrDrawState*,
                         uint8_t coverage,
+                        size_t vertexStride,
                         GrDrawTarget::AutoReleaseGeometry* arg,
                         SkRect* devBounds,
                         const SkPath& path,
index 0cf7575..23757ce 100644 (file)
@@ -25,20 +25,21 @@ enum CoverageAttribType {
 };
 }
 
-static CoverageAttribType set_rect_attribs(GrDrawState* drawState, GrColor color) {
+static const GrGeometryProcessor* create_rect_gp(const GrDrawState& drawState, GrColor color,
+                                                 CoverageAttribType* type) {
     uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType;
-    if (drawState->canTweakAlphaForCoverage()) {
-        drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
-        SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
-                 sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
-        return kUseColor_CoverageAttribType;
+    const GrGeometryProcessor* gp;
+    if (drawState.canTweakAlphaForCoverage()) {
+        gp = GrDefaultGeoProcFactory::Create(color, flags);
+        SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
+        *type = kUseColor_CoverageAttribType;
     } else {
         flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
-        drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
-        SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
-                 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
-        return kUseCoverage_CoverageAttribType;
+        gp = GrDefaultGeoProcFactory::Create(color, flags);
+        SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
+        *type = kUseCoverage_CoverageAttribType;
     }
+    return gp;
 }
 
 static void set_inset_fan(SkPoint* pts, size_t stride,
@@ -182,13 +183,14 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
                                           const SkRect& devRect) {
     GrDrawState::AutoRestoreEffects are(drawState);
 
-    CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
-    if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
+    CoverageAttribType type;
+    SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type));
+    if (kUseCoverage_CoverageAttribType == type && GrColorIsOpaque(color)) {
         drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
     }
 
-    size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
-    GrDrawTarget::AutoReleaseGeometry geo(target, 8, vstride, 0);
+    size_t vertexStride = gp->getVertexStride();
+    GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0);
     if (!geo.succeeded()) {
         SkDebugf("Failed to get space for vertices!\n");
         return;
@@ -209,7 +211,7 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
     intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
 
     SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
-    SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride);
+    SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
 
     SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
     inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
@@ -223,8 +225,8 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
         combinedMatrix.mapRect(&devRect, rect);
 #endif
 
-        set_inset_fan(fan0Pos, vstride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
-        set_inset_fan(fan1Pos, vstride, devRect, inset,  inset);
+        set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
+        set_inset_fan(fan1Pos, vertexStride, devRect, inset,  inset);
     } else {
         // compute transformed (1, 0) and (0, 1) vectors
         SkVector vec[2] = {
@@ -239,38 +241,38 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
 
         // create the rotated rect
         fan0Pos->setRectFan(rect.fLeft, rect.fTop,
-                            rect.fRight, rect.fBottom, vstride);
-        combinedMatrix.mapPointsWithStride(fan0Pos, vstride, 4);
+                            rect.fRight, rect.fBottom, vertexStride);
+        combinedMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
 
         // Now create the inset points and then outset the original
         // rotated points
 
         // TL
-        *((SkPoint*)((intptr_t)fan1Pos + 0 * vstride)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) + vec[0] + vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) -= vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
         // BL
-        *((SkPoint*)((intptr_t)fan1Pos + 1 * vstride)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) + vec[0] - vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) -= vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
         // BR
-        *((SkPoint*)((intptr_t)fan1Pos + 2 * vstride)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) - vec[0] - vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) += vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
         // TR
-        *((SkPoint*)((intptr_t)fan1Pos + 3 * vstride)) =
-            *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) - vec[0] + vec[1];
-        *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) += vec[0] - vec[1];
+        *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
+            *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1];
+        *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
     }
 
     // Make verts point to vertex color and then set all the color and coverage vertex attrs values.
     verts += sizeof(SkPoint);
     for (int i = 0; i < 4; ++i) {
-        if (kUseCoverage_CoverageAttribType == covAttribType) {
-            *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
-            *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = 0;
+        if (kUseCoverage_CoverageAttribType == type) {
+            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
+            *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 0;
         } else {
-            *reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
+            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
         }
     }
 
@@ -282,22 +284,23 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
         scale = 0xff;
     }
 
-    verts += 4 * vstride;
+    verts += 4 * vertexStride;
 
     float innerCoverage = GrNormalizeByteToFloat(scale);
     GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
 
     for (int i = 0; i < 4; ++i) {
-        if (kUseCoverage_CoverageAttribType == covAttribType) {
-            *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
-            *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
+        if (kUseCoverage_CoverageAttribType == type) {
+            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
+            *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = innerCoverage;
         } else {
-            *reinterpret_cast<GrColor*>(verts + i * vstride) = scaledColor; 
+            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
         }
     }
 
     target->setIndexSourceToBuffer(indexBuffer);
     target->drawIndexedInstances(drawState,
+                                 gp,
                                  kTriangles_GrPrimitiveType,
                                  1,
                                  kVertsPerAAFillRect,
@@ -383,9 +386,11 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
                                             const SkRect& devInside,
                                             bool miterStroke) {
     GrDrawState::AutoRestoreEffects are(drawState);
-    CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
 
-    if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
+    CoverageAttribType type;
+    SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type));
+
+    if (kUseCoverage_CoverageAttribType == type && GrColorIsOpaque(color)) {
         drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
     }
 
@@ -393,7 +398,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
     int outerVertexNum = miterStroke ? 4 : 8;
     int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
 
-    size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
+    size_t vstride = gp->getVertexStride();
     GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0);
     if (!geo.succeeded()) {
         SkDebugf("Failed to get space for vertices!\n");
@@ -458,7 +463,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
     // The outermost rect has 0 coverage
     verts += sizeof(SkPoint);
     for (int i = 0; i < outerVertexNum; ++i) {
-        if (kUseCoverage_CoverageAttribType == covAttribType) {
+        if (kUseCoverage_CoverageAttribType == type) {
             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
             *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = 0;
         } else {
@@ -480,7 +485,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
 
     verts += outerVertexNum * vstride;
     for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) {
-        if (kUseCoverage_CoverageAttribType == covAttribType) {
+        if (kUseCoverage_CoverageAttribType == type) {
             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
             *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
         } else {
@@ -491,7 +496,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
     // The innermost rect has 0 coverage
     verts += (outerVertexNum + innerVertexNum) * vstride;
     for (int i = 0; i < innerVertexNum; ++i) {
-        if (kUseCoverage_CoverageAttribType == covAttribType) {
+        if (kUseCoverage_CoverageAttribType == type) {
             *reinterpret_cast<GrColor*>(verts + i * vstride) = color;
             *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
         } else {
@@ -501,6 +506,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
 
     target->setIndexSourceToBuffer(indexBuffer);
     target->drawIndexedInstances(drawState,
+                                 gp,
                                  kTriangles_GrPrimitiveType,
                                  1,
                                  totalVertexNum,
index 6a624ae..7ee5585 100755 (executable)
@@ -561,19 +561,18 @@ void GrBitmapTextContext::flush() {
         if (kARGB_GrMaskFormat == fCurrMaskFormat) {
             uint32_t textureUniqueID = fCurrTexture->getUniqueID();
             if (textureUniqueID != fEffectTextureUniqueID ||
-                fCachedGeometryProcessor->getColor() != color) {
+                fCachedGeometryProcessor->color() != color) {
                 uint32_t flags = GrDefaultGeoProcFactory::kLocalCoord_GPType;
                 fCachedGeometryProcessor.reset(GrDefaultGeoProcFactory::Create(color, flags));
                 fCachedTextureProcessor.reset(GrSimpleTextureEffect::Create(fCurrTexture,
                                                                             SkMatrix::I(),
                                                                             params));
             }
-            drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
             drawState.addColorProcessor(fCachedTextureProcessor.get());
         } else {
             uint32_t textureUniqueID = fCurrTexture->getUniqueID();
             if (textureUniqueID != fEffectTextureUniqueID ||
-                fCachedGeometryProcessor->getColor() != color) {
+                fCachedGeometryProcessor->color() != color) {
                 bool hasColor = kA8_GrMaskFormat == fCurrMaskFormat;
                 fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(color,
                                                                                    fCurrTexture,
@@ -581,12 +580,12 @@ void GrBitmapTextContext::flush() {
                                                                                    hasColor));
                 fEffectTextureUniqueID = textureUniqueID;
             }
-            drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
         }
 
         int nGlyphs = fCurrVertex / kVerticesPerGlyph;
         fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
         fDrawTarget->drawIndexedInstances(&drawState,
+                                          fCachedGeometryProcessor.get(),
                                           kTriangles_GrPrimitiveType,
                                           nGlyphs,
                                           kVerticesPerGlyph,
index 9d07fdf..bfbce35 100755 (executable)
@@ -315,8 +315,8 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
 
         uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
                          GrDefaultGeoProcFactory::kLocalCoord_GPType;
-        const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(GrColor_WHITE, flags);
-        drawState.setGeometryProcessor(gp)->unref();
+        SkAutoTUnref<const GrGeometryProcessor> gp(
+                GrDefaultGeoProcFactory::Create(GrColor_WHITE, flags));
 
         GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStride(),  0);
         SkASSERT(gp->getVertexStride() == 2 * sizeof(SkPoint));
@@ -325,7 +325,7 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
             SkPoint* verts = (SkPoint*) arg.vertices();
             verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(SkPoint));
             verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint));
-            fDrawBuffer->drawNonIndexed(&drawState, kTriangleFan_GrPrimitiveType, 0, 4);
+            fDrawBuffer->drawNonIndexed(&drawState, gp, kTriangleFan_GrPrimitiveType, 0, 4);
         }
     } else {
         // TODO: Our CPU stretch doesn't filter. But we create separate
@@ -758,8 +758,7 @@ void GrContext::drawRect(const GrPaint& paint,
         // unitSquareVertexBuffer()
 
         static const int worstCaseVertCount = 10;
-        const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(color);
-        drawState.setGeometryProcessor(gp)->unref();
+        SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create(color));
         GrDrawTarget::AutoReleaseGeometry geo(target,
                                               worstCaseVertCount,
                                               gp->getVertexStride(),
@@ -790,7 +789,7 @@ void GrContext::drawRect(const GrPaint& paint,
             vertex[4].set(rect.fLeft, rect.fTop);
         }
 
-        target->drawNonIndexed(&drawState, primType, 0, vertCount);
+        target->drawNonIndexed(&drawState, gp, primType, 0, vertCount);
     } else {
         // filled BW rect
         target->drawSimpleRect(&drawState, color, rect);
@@ -813,12 +812,11 @@ void GrContext::drawRectToRect(const GrPaint& paint,
     target->drawRect(&drawState, paint.getColor(), dstRect, &localRect, localMatrix);
 }
 
-static void set_vertex_attributes(GrDrawState* drawState,
-                                  const SkPoint* texCoords,
-                                  const GrColor* colors,
-                                  int* colorOffset,
-                                  int* texOffset,
-                                  GrColor color) {
+static const GrGeometryProcessor* set_vertex_attributes(const SkPoint* texCoords,
+                                                        const GrColor* colors,
+                                                        int* colorOffset,
+                                                        int* texOffset,
+                                                        GrColor color) {
     *texOffset = -1;
     *colorOffset = -1;
 
@@ -835,7 +833,7 @@ static void set_vertex_attributes(GrDrawState* drawState,
         *colorOffset = sizeof(SkPoint);
         flags |= GrDefaultGeoProcFactory::kColor_GPType;
     }
-    drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
+    return GrDefaultGeoProcFactory::Create(color, flags);
 }
 
 void GrContext::drawVertices(const GrPaint& paint,
@@ -858,10 +856,10 @@ void GrContext::drawVertices(const GrPaint& paint,
     GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target);
 
     int colorOffset = -1, texOffset = -1;
-    set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffset,
-                          paint.getColor());
+    SkAutoTUnref<const GrGeometryProcessor> gp(
+            set_vertex_attributes(texCoords, colors, &colorOffset, &texOffset, paint.getColor()));
 
-    size_t vertexStride = drawState.getGeometryProcessor()->getVertexStride();
+    size_t vertexStride = gp->getVertexStride();
     SkASSERT(vertexStride == sizeof(SkPoint) + (SkToBool(texCoords) ? sizeof(SkPoint) : 0)
                                              + (SkToBool(colors) ? sizeof(GrColor) : 0));
     if (!geo.set(target, vertexCount, vertexStride, indexCount)) {
@@ -889,9 +887,9 @@ void GrContext::drawVertices(const GrPaint& paint,
         for (int i = 0; i < indexCount; ++i) {
             curIndex[i] = indices[i];
         }
-        target->drawIndexed(&drawState, primitiveType, 0, 0, vertexCount, indexCount);
+        target->drawIndexed(&drawState, gp, primitiveType, 0, 0, vertexCount, indexCount);
     } else {
-        target->drawNonIndexed(&drawState, primitiveType, 0, vertexCount);
+        target->drawNonIndexed(&drawState, gp, primitiveType, 0, vertexCount);
     }
 }
 
index dca6c1c..a798ee8 100644 (file)
@@ -128,11 +128,12 @@ private:
         return gp.fFlags == this->fFlags;
     }
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
         if (fInCoverage) {
-            inout->mulByUnknownAlpha();
+            out->setUnknownSingleComponent();
         } else {
-            inout->mulByKnownAlpha(255);
+            // uniform coverage
+            out->setKnownSingleComponent(this->coverage());
         }
     }
 
index 24d3c45..07f9208 100644 (file)
@@ -498,12 +498,13 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
                 drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
             }
             GrDrawState::AutoRestoreEffects are(drawState);
-            drawState->setGeometryProcessor(
+            SkAutoTUnref<const GrGeometryProcessor> gp(
                     GrDefaultGeoProcFactory::Create(color,
                                                     GrDefaultGeoProcFactory::kPosition_GPType,
-                                                    newCoverage))->unref();
+                                                    newCoverage));
             if (indexCnt) {
                 target->drawIndexed(drawState,
+                                    gp,
                                     primType,
                                     0,
                                     0,
@@ -511,7 +512,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
                                     indexCnt,
                                     &devBounds);
             } else {
-                target->drawNonIndexed(drawState, primType, 0, vertexCnt, &devBounds);
+                target->drawNonIndexed(drawState, gp, primType, 0, vertexCnt, &devBounds);
             }
         }
     }
index d35ba23..ea72c29 100755 (executable)
@@ -637,9 +637,6 @@ void GrDistanceFieldTextContext::flush() {
         }
         this->setupCoverageEffect(filteredColor);
 
-        // Effects could be stored with one of the cache objects (atlas?)
-        drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
-
         // Set draw state
         if (fUseLCDText) {
             // TODO: move supportsRGBCoverage check to setupCoverageEffect and only add LCD
@@ -648,17 +645,18 @@ void GrDistanceFieldTextContext::flush() {
             if (!drawState.getXPFactory()->supportsRGBCoverage(0, kRGBA_GrColorComponentFlags)) {
                 SkDebugf("LCD Text will not draw correctly.\n");
             }
-            SkASSERT(!drawState.hasColorVertexAttribute());
+            SkASSERT(!fCachedGeometryProcessor->hasVertexColor());
         } else {
             if (0xFF == GrColorUnpackA(fPaint.getColor())) {
                 drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
             }
             // We're using per-vertex color.
-            SkASSERT(drawState.hasColorVertexAttribute());
+            SkASSERT(fCachedGeometryProcessor->hasVertexColor());
         }
         int nGlyphs = fCurrVertex / kVerticesPerGlyph;
         fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
         fDrawTarget->drawIndexedInstances(&drawState,
+                                          fCachedGeometryProcessor.get(),
                                           kTriangles_GrPrimitiveType,
                                           nGlyphs,
                                           kVerticesPerGlyph,
index 465c10c..72ec7a3 100644 (file)
@@ -14,7 +14,7 @@
 #include "GrXferProcessor.h"
 #include "effects/GrPorterDuffXferProcessor.h"
 
-bool GrDrawState::isEqual(const GrDrawState& that) const {
+bool GrDrawState::isEqual(const GrDrawState& that, bool explicitLocalCoords) const {
     if (this->getRenderTarget() != that.getRenderTarget() ||
         this->fColorStages.count() != that.fColorStages.count() ||
         this->fCoverageStages.count() != that.fCoverageStages.count() ||
@@ -25,17 +25,6 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
         return false;
     }
 
-    bool explicitLocalCoords = this->hasLocalCoordAttribute();
-    if (this->hasGeometryProcessor()) {
-        if (!that.hasGeometryProcessor()) {
-            return false;
-        } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
-            return false;
-        }
-    } else if (that.hasGeometryProcessor()) {
-        return false;
-    }
-
     if (!this->getXPFactory()->isEqual(*that.getXPFactory())) {
         return false;
     }
@@ -77,7 +66,6 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
     fFlagBits = that.fFlagBits;
     fStencilSettings = that.fStencilSettings;
     fDrawFace = that.fDrawFace;
-    fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get()));
     fXPFactory.reset(SkRef(that.getXPFactory()));
     fColorStages = that.fColorStages;
     fCoverageStages = that.fCoverageStages;
@@ -96,10 +84,9 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
 }
 
 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
-    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
+    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
     fRenderTarget.reset(NULL);
 
-    fGeometryProcessor.reset(NULL);
     fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
     fColorStages.reset();
     fCoverageStages.reset();
@@ -120,6 +107,10 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
 
     fColorCache = GrColor_ILLEGAL;
     fCoverageCache = GrColor_ILLEGAL;
+
+    fColorPrimProc = NULL;
+    fCoveragePrimProc = NULL;
+
 }
 
 bool GrDrawState::setIdentityViewMatrix()  {
@@ -141,9 +132,8 @@ bool GrDrawState::setIdentityViewMatrix()  {
 }
 
 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
-    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
+    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
 
-    fGeometryProcessor.reset(NULL);
     fColorStages.reset();
     fCoverageStages.reset();
 
@@ -197,7 +187,7 @@ bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCa
                                         this->isCoverageDrawing(), this->isColorWriteDisabled());
 }
 
-bool GrDrawState::hasSolidCoverage(GrColor coverage) const {
+bool GrDrawState::hasSolidCoverage(const GrPrimitiveProcessor* pp) const {
     // If we're drawing coverage directly then coverage is effectively treated as color.
     if (this->isCoverageDrawing()) {
         return true;
@@ -207,15 +197,15 @@ bool GrDrawState::hasSolidCoverage(GrColor coverage) const {
         return false;
     }
 
-    this->calcCoverageInvariantOutput(coverage);
+    this->calcCoverageInvariantOutput(pp);
     return fCoverageProcInfo.isSolidWhite();
 }
 
 //////////////////////////////////////////////////////////////////////////////s
 
-bool GrDrawState::willEffectReadDstColor(GrColor color, GrColor coverage) const {
-    this->calcColorInvariantOutput(color);
-    this->calcCoverageInvariantOutput(coverage);
+bool GrDrawState::willEffectReadDstColor(const GrPrimitiveProcessor* pp) const {
+    this->calcColorInvariantOutput(pp);
+    this->calcCoverageInvariantOutput(pp);
     // TODO: Remove need to create the XP here.
     //       Also once all custom blends are turned into XPs we can remove the need
     //       to check other stages since only xp's will be able to read dst
@@ -235,15 +225,6 @@ bool GrDrawState::willEffectReadDstColor(GrColor color, GrColor coverage) const
 
 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
     if (fDrawState) {
-        // See the big comment on the class definition about GPs.
-        if (SK_InvalidUniqueID == fOriginalGPID) {
-            fDrawState->fGeometryProcessor.reset(NULL);
-        } else {
-            SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
-                     fOriginalGPID);
-            fOriginalGPID = SK_InvalidUniqueID;
-        }
-
         int m = fDrawState->numColorStages() - fColorEffectCnt;
         SkASSERT(m >= 0);
         fDrawState->fColorStages.pop_back_n(m);
@@ -259,10 +240,6 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
     }
     fDrawState = ds;
     if (NULL != ds) {
-        SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
-        if (NULL != ds->getGeometryProcessor()) {
-            fOriginalGPID = ds->getGeometryProcessor()->getUniqueID();
-        }
         fColorEffectCnt = ds->numColorStages();
         fCoverageEffectCnt = ds->numCoverageStages();
         SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
@@ -372,38 +349,35 @@ GrDrawState::~GrDrawState() {
 
 ////////////////////////////////////////////////////////////////////////////////
 
-bool GrDrawState::srcAlphaWillBeOne(GrColor color, GrColor coverage) const {
-    this->calcColorInvariantOutput(color);
-    if (this->isCoverageDrawing()) {
-        this->calcCoverageInvariantOutput(coverage);
-        return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
+bool GrDrawState::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
+    this->calcColorInvariantOutput(pp);
+    this->calcCoverageInvariantOutput(pp);
+    return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
+                                        this->isCoverageDrawing(), this->isColorWriteDisabled());
+}
+
+void GrDrawState::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
+    if (!fColorProcInfoValid || fColorPrimProc != pp) {
+        fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorStages());
+        fColorProcInfoValid = true;
+        fColorPrimProc = pp;
     }
-    return fColorProcInfo.isOpaque();
 }
 
-bool GrDrawState::willBlendWithDst(GrColor color, GrColor coverage) const {
-    this->calcColorInvariantOutput(color);
-    this->calcCoverageInvariantOutput(coverage);
-    return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
-                                        this->isCoverageDrawing(), this->isColorWriteDisabled());
+void GrDrawState::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
+    if (!fCoverageProcInfoValid ||  fCoveragePrimProc != pp) {
+        fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
+                                                   this->numCoverageStages());
+        fCoverageProcInfoValid = true;
+        fCoveragePrimProc = pp;
+    }
 }
 
 void GrDrawState::calcColorInvariantOutput(GrColor color) const {
     if (!fColorProcInfoValid || color != fColorCache) {
-        GrColorComponentFlags flags;
-        if (this->hasColorVertexAttribute()) {
-            if (fHints & kVertexColorsAreOpaque_Hint) {
-                flags = kA_GrColorComponentFlag;
-                color = 0xFF << GrColor_SHIFT_A;
-            } else {
-                flags = static_cast<GrColorComponentFlags>(0);
-                color = 0;
-            }
-        } else {
-            flags = kRGBA_GrColorComponentFlags;
-        }
-        fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(),
-                                             color, flags, false);
+        GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
+        fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color,
+                                             flags, false);
         fColorProcInfoValid = true;
         fColorCache = color;
     }
@@ -411,16 +385,10 @@ void GrDrawState::calcColorInvariantOutput(GrColor color) const {
 
 void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const {
     if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
-        GrColorComponentFlags flags;
-        // Check if per-vertex or constant color may have partial alpha
-        if (this->hasCoverageVertexAttribute()) {
-            flags = static_cast<GrColorComponentFlags>(0);
-            coverage = 0;
-        } else {
-            flags = kRGBA_GrColorComponentFlags;
-        }
-        fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(),
-                                                coverage, flags, true, fGeometryProcessor.get());
+            GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
+            fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
+                                                    this->numCoverageStages(), coverage, flags,
+                                                    true);
         fCoverageProcInfoValid = true;
         fCoverageCache = coverage;
     }
index 17bd0f4..dff3c73 100644 (file)
@@ -68,21 +68,6 @@ public:
      */
     void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
 
-    ///////////////////////////////////////////////////////////////////////////
-    /// @name Vertex Attributes
-    ////
-
-    // TODO when we move this info off of GrGeometryProcessor, delete these
-    bool hasLocalCoordAttribute() const {
-        return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasLocalCoords();
-    }
-    bool hasColorVertexAttribute() const {
-        return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexColor();
-    }
-    bool hasCoverageVertexAttribute() const {
-        return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexCoverage();
-    }
-
     /// @}
 
     /**
@@ -100,29 +85,13 @@ public:
     /**
      * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
      */
-    bool hasSolidCoverage(GrColor coverage) const;
+    bool hasSolidCoverage(const GrPrimitiveProcessor*) const;
 
     /**
      * This function returns true if the render target destination pixel values will be read for
      * blending during draw.
      */
-    bool willBlendWithDst(GrColor color, GrColor coverage) const;
-
-    /// @}
-
-    /**
-     * The geometry processor is the sole element of the skia pipeline which can use the vertex,
-     * geometry, and tesselation shaders.  The GP may also compute a coverage in its fragment shader
-     * but is never put in the color processing pipeline.
-     */
-
-    const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
-        SkASSERT(geometryProcessor);
-        SkASSERT(!this->hasGeometryProcessor());
-        fGeometryProcessor.reset(SkRef(geometryProcessor));
-        fCoverageProcInfoValid = false;
-        return geometryProcessor;
-    }
+    bool willBlendWithDst(const GrPrimitiveProcessor*) const;
 
     ///////////////////////////////////////////////////////////////////////////
     /// @name Effect Stages
@@ -147,12 +116,6 @@ public:
     int numColorStages() const { return fColorStages.count(); }
     int numCoverageStages() const { return fCoverageStages.count(); }
     int numFragmentStages() const { return this->numColorStages() + this->numCoverageStages(); }
-    int numTotalStages() const {
-         return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
-    }
-
-    bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
-    const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
 
     const GrXPFactory* getXPFactory() const { return fXPFactory.get(); }
 
@@ -163,7 +126,7 @@ public:
      * Checks whether any of the effects will read the dst pixel color.
      * TODO remove when we have an XP
      */
-    bool willEffectReadDstColor(GrColor color, GrColor coverage) const;
+    bool willEffectReadDstColor(const GrPrimitiveProcessor*) const;
 
     /**
      * The xfer processor factory.
@@ -238,13 +201,11 @@ public:
     public:
         AutoRestoreEffects() 
             : fDrawState(NULL)
-            , fOriginalGPID(SK_InvalidUniqueID)
             , fColorEffectCnt(0)
             , fCoverageEffectCnt(0) {}
 
         AutoRestoreEffects(GrDrawState* ds)
             : fDrawState(NULL)
-            , fOriginalGPID(SK_InvalidUniqueID)
             , fColorEffectCnt(0)
             , fCoverageEffectCnt(0) {
             this->set(ds);
@@ -258,7 +219,6 @@ public:
 
     private:
         GrDrawState*    fDrawState;
-        uint32_t        fOriginalGPID;
         int             fColorEffectCnt;
         int             fCoverageEffectCnt;
     };
@@ -555,22 +515,29 @@ public:
     GrDrawState& operator= (const GrDrawState& that);
 
 private:
-    bool isEqual(const GrDrawState& that) const;
+    bool isEqual(const GrDrawState& that, bool explicitLocalCoords) const;
 
-    const GrProcOptInfo& colorProcInfo(GrColor color) const { 
-        this->calcColorInvariantOutput(color);
+    const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const {
+        this->calcColorInvariantOutput(pp);
         return fColorProcInfo;
     }
 
-    const GrProcOptInfo& coverageProcInfo(GrColor coverage) const {
-        this->calcCoverageInvariantOutput(coverage);
+    const GrProcOptInfo& coverageProcInfo(const GrPrimitiveProcessor* pp) const {
+        this->calcCoverageInvariantOutput(pp);
         return fCoverageProcInfo;
     }
 
     /**
-     * Determines whether src alpha is guaranteed to be one for all src pixels
+     * If fColorProcInfoValid is false, function calculates the invariant output for the color
+     * stages and results are stored in fColorProcInfo.
+     */
+    void calcColorInvariantOutput(const GrPrimitiveProcessor*) const;
+
+    /**
+     * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
+     * stages and results are stored in fCoverageProcInfo.
      */
-    bool srcAlphaWillBeOne(GrColor color, GrColor coverage) const;
+    void calcCoverageInvariantOutput(const GrPrimitiveProcessor*) const;
 
     /**
      * If fColorProcInfoValid is false, function calculates the invariant output for the color
@@ -597,7 +564,6 @@ private:
     uint32_t                                fFlagBits;
     GrStencilSettings                       fStencilSettings;
     DrawFace                                fDrawFace;
-    SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
     SkAutoTUnref<const GrXPFactory>         fXPFactory;
     FragmentStageArray                      fColorStages;
     FragmentStageArray                      fCoverageStages;
@@ -609,6 +575,8 @@ private:
     mutable bool fCoverageProcInfoValid;
     mutable GrColor fColorCache;
     mutable GrColor fCoverageCache;
+    mutable const GrPrimitiveProcessor* fColorPrimProc;
+    mutable const GrPrimitiveProcessor* fCoveragePrimProc;
 
     friend class GrOptDrawState;
 };
index adb7128..96594b1 100644 (file)
@@ -307,6 +307,7 @@ void GrDrawTarget::popGeometrySource() {
 ////////////////////////////////////////////////////////////////////////////////
 
 bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
+                             const GrGeometryProcessor* gp,
                              GrPrimitiveType type,
                              int startVertex,
                              int startIndex,
@@ -349,8 +350,7 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
 
     SkASSERT(drawState.getRenderTarget());
 
-    if (drawState.hasGeometryProcessor()) {
-        const GrGeometryProcessor* gp = drawState.getGeometryProcessor();
+    if (gp) {
         int numTextures = gp->numTextures();
         for (int t = 0; t < numTextures; ++t) {
             GrTexture* texture = gp->texture(t);
@@ -383,12 +383,10 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
 }
 
 bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds,
-                                           GrColor color,
-                                           uint8_t coverage,
+                                           const GrPrimitiveProcessor* primProc,
                                            GrDeviceCoordTexture* dstCopy,
                                            const SkRect* drawBounds) {
-    GrColor c = GrColorPackRGBA(coverage, coverage, coverage, coverage);
-    if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor(color, c)) {
+    if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor(primProc)) {
         return true;
     }
     SkIRect copyRect;
@@ -436,6 +434,7 @@ bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds,
 }
 
 void GrDrawTarget::drawIndexed(GrDrawState* ds,
+                               const GrGeometryProcessor* gp,
                                GrPrimitiveType type,
                                int startVertex,
                                int startIndex,
@@ -444,7 +443,7 @@ void GrDrawTarget::drawIndexed(GrDrawState* ds,
                                const SkRect* devBounds) {
     SkASSERT(ds);
     if (indexCount > 0 &&
-        this->checkDraw(*ds, type, startVertex, startIndex, vertexCount, indexCount)) {
+        this->checkDraw(*ds, gp, type, startVertex, startIndex, vertexCount, indexCount)) {
 
         // Setup clip
         GrClipMaskManager::ScissorState scissorState;
@@ -471,24 +470,23 @@ void GrDrawTarget::drawIndexed(GrDrawState* ds,
 
         // TODO: We should continue with incorrect blending.
         GrDeviceCoordTexture dstCopy;
-        const GrGeometryProcessor* gp = ds->getGeometryProcessor();
-        if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,
-                                           devBounds)) {
+        if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy, devBounds)) {
             return;
         }
         this->setDrawBuffers(&info, gp->getVertexStride());
 
-        this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
+        this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
     }
 }
 
 void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
+                                  const GrGeometryProcessor* gp,
                                   GrPrimitiveType type,
                                   int startVertex,
                                   int vertexCount,
                                   const SkRect* devBounds) {
     SkASSERT(ds);
-    if (vertexCount > 0 && this->checkDraw(*ds, type, startVertex, -1, vertexCount, -1)) {
+    if (vertexCount > 0 && this->checkDraw(*ds, gp, type, startVertex, -1, vertexCount, -1)) {
 
         // Setup clip
         GrClipMaskManager::ScissorState scissorState;
@@ -515,15 +513,13 @@ void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
 
         // TODO: We should continue with incorrect blending.
         GrDeviceCoordTexture dstCopy;
-        const GrGeometryProcessor* gp = ds->getGeometryProcessor();
-        if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,
-                                           devBounds)) {
+        if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy, devBounds)) {
             return;
         }
 
         this->setDrawBuffers(&info, gp->getVertexStride());
 
-        this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
+        this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
     }
 }
 
@@ -563,6 +559,7 @@ void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType f
 }
 
 void GrDrawTarget::stencilPath(GrDrawState* ds,
+                               const GrPathProcessor* pathProc,
                                const GrPath* path,
                                GrPathRendering::FillType fill) {
     // TODO: extract portions of checkDraw that are relevant to path stenciling.
@@ -584,11 +581,11 @@ void GrDrawTarget::stencilPath(GrDrawState* ds,
                                             ds->getRenderTarget()->getStencilBuffer(),
                                             &stencilSettings);
 
-    this->onStencilPath(*ds, path, scissorState, stencilSettings);
+    this->onStencilPath(*ds, pathProc, path, scissorState, stencilSettings);
 }
 
 void GrDrawTarget::drawPath(GrDrawState* ds,
-                            GrColor color,
+                            const GrPathProcessor* pathProc,
                             const GrPath* path,
                             GrPathRendering::FillType fill) {
     // TODO: extract portions of checkDraw that are relevant to path rendering.
@@ -615,16 +612,16 @@ void GrDrawTarget::drawPath(GrDrawState* ds,
                                             &stencilSettings);
 
     GrDeviceCoordTexture dstCopy;
-    if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, &devBounds)) {
+    if (!this->setupDstReadIfNecessary(ds, pathProc, &dstCopy, &devBounds)) {
         return;
     }
 
-    this->onDrawPath(*ds, color, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy :
-                                                                                          NULL);
+    this->onDrawPath(*ds, pathProc, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy :
+                                                                                       NULL);
 }
 
 void GrDrawTarget::drawPaths(GrDrawState* ds,
-                             GrColor color,
+                             const GrPathProcessor* pathProc,
                              const GrPathRange* pathRange,
                              const void* indices,
                              PathIndexType indexType,
@@ -659,11 +656,11 @@ void GrDrawTarget::drawPaths(GrDrawState* ds,
     // point, because any context that supports NV_path_rendering will also
     // support NV_blend_equation_advanced.
     GrDeviceCoordTexture dstCopy;
-    if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, NULL)) {
+    if (!this->setupDstReadIfNecessary(ds, pathProc, &dstCopy, NULL)) {
         return;
     }
 
-    this->onDrawPaths(*ds, color, pathRange, indices, indexType, transformValues, transformType,
+    this->onDrawPaths(*ds, pathProc, pathRange, indices, indexType, transformValues, transformType,
                       count, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
 }
 
@@ -733,6 +730,7 @@ void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
+                                        const GrGeometryProcessor* gp,
                                         GrPrimitiveType type,
                                         int instanceCount,
                                         int verticesPerInstance,
@@ -771,8 +769,7 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
 
     // TODO: We should continue with incorrect blending.
     GrDeviceCoordTexture dstCopy;
-    const GrGeometryProcessor* gp = ds->getGeometryProcessor();
-    if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,devBounds)) {
+    if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy,devBounds)) {
         return;
     }
 
@@ -782,13 +779,14 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
         info.fIndexCount = info.fInstanceCount * indicesPerInstance;
 
         if (this->checkDraw(*ds,
+                            gp,
                             type,
                             info.fStartVertex,
                             info.fStartIndex,
                             info.fVertexCount,
                             info.fIndexCount)) {
             this->setDrawBuffers(&info, gp->getVertexStride());
-            this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
+            this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
         }
         info.fStartVertex += info.fVertexCount;
         instanceCount -= info.fInstanceCount;
index fc2ee76..770e885 100644 (file)
@@ -233,6 +233,7 @@ public:
      *                     not a request for clipping.
      */
     void drawIndexed(GrDrawState*,
+                     const GrGeometryProcessor*,
                      GrPrimitiveType type,
                      int startVertex,
                      int startIndex,
@@ -252,6 +253,7 @@ public:
      *                     not a request for clipping.
      */
     void drawNonIndexed(GrDrawState*,
+                        const GrGeometryProcessor*,
                         GrPrimitiveType type,
                         int startVertex,
                         int vertexCount,
@@ -263,13 +265,13 @@ public:
      * on the draw state (if possible in the 3D API).  Note, we will never have an inverse fill
      * with stencil path
      */
-    void stencilPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill);
+    void stencilPath(GrDrawState*, const GrPathProcessor*, const GrPath*,GrPathRendering::FillType);
 
     /**
      * Draws a path. Fill must not be a hairline. It will respect the HW
      * antialias flag on the draw state (if possible in the 3D API).
      */
-    void drawPath(GrDrawState*, GrColor, const GrPath*, GrPathRendering::FillType fill);
+    void drawPath(GrDrawState*, const GrPathProcessor*, const GrPath*, GrPathRendering::FillType);
 
     /**
      * Draws the aggregate path from combining multiple. Note that this will not
@@ -285,7 +287,7 @@ public:
      * @param fill            Fill type for drawing all the paths
      */
     void drawPaths(GrDrawState*,
-                   GrColor,
+                   const GrPathProcessor*,
                    const GrPathRange* pathRange,
                    const void* indices,
                    PathIndexType indexType,
@@ -357,6 +359,7 @@ public:
      *                     not a request for clipping.
      */
     void drawIndexedInstances(GrDrawState*,
+                              const GrGeometryProcessor*,
                               GrPrimitiveType type,
                               int instanceCount,
                               int verticesPerInstance,
@@ -656,8 +659,7 @@ protected:
     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
     // needs to be accessed by GLPrograms to setup a correct drawstate
     bool setupDstReadIfNecessary(GrDrawState*,
-                                 GrColor,
-                                 uint8_t,
+                                 const GrPrimitiveProcessor*,
                                  GrDeviceCoordTexture* dstCopy,
                                  const SkRect* drawBounds);
 
@@ -698,6 +700,7 @@ private:
     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
     // subclass called to perform drawing
     virtual void onDraw(const GrDrawState&,
+                        const GrGeometryProcessor*,
                         const DrawInfo&,
                         const GrClipMaskManager::ScissorState&,
                         const GrDeviceCoordTexture* dstCopy) = 0;
@@ -709,17 +712,18 @@ private:
                             const SkMatrix* localMatrix) = 0;
 
     virtual void onStencilPath(const GrDrawState&,
+                               const GrPathProcessor*,
                                const GrPath*,
                                const GrClipMaskManager::ScissorState&,
                                const GrStencilSettings&) = 0;
     virtual void onDrawPath(const GrDrawState&,
-                            GrColor,
+                            const GrPathProcessor*,
                             const GrPath*,
                             const GrClipMaskManager::ScissorState&,
                             const GrStencilSettings&,
                             const GrDeviceCoordTexture* dstCopy) = 0;
     virtual void onDrawPaths(const GrDrawState&,
-                             GrColor,
+                             const GrPathProcessor*,
                              const GrPathRange*,
                              const void* indices,
                              PathIndexType,
@@ -766,6 +770,7 @@ private:
     // called by drawIndexed and drawNonIndexed. Use a negative indexCount to
     // indicate non-indexed drawing.
     bool checkDraw(const GrDrawState&,
+                   const GrGeometryProcessor*,
                    GrPrimitiveType type,
                    int startVertex,
                    int startIndex,
index a0cfc09..4411049 100644 (file)
@@ -39,6 +39,23 @@ class GrGLCaps;
 class GrGLGeometryProcessor;
 class GrOptDrawState;
 
+struct GrInitInvariantOutput;
+
+/*
+ * GrGeometryProcessors and GrPathProcessors may effect invariantColor
+ */
+class GrPrimitiveProcessor : public GrProcessor {
+public:
+    // TODO GPs and PPs have to provide an initial coverage because the coverage invariant code is
+    // broken right now
+    virtual uint8_t coverage() const = 0;
+    virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
+    virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
+
+private:
+    typedef GrProcessor INHERITED;
+};
+
 /**
  * A GrGeometryProcessor is used to perform computation in the vertex shader and
  * add support for custom vertex attributes. A GrGemeotryProcessor is typically
@@ -49,7 +66,7 @@ class GrOptDrawState;
  * added to the vertex attribute array specified on the GrDrawState.
  * GrGeometryProcessor subclasses should be immutable after construction.
  */
-class GrGeometryProcessor : public GrProcessor {
+class GrGeometryProcessor : public GrPrimitiveProcessor {
 public:
     GrGeometryProcessor(GrColor color, uint8_t coverage = 0xff)
         : fVertexStride(0)
@@ -114,11 +131,13 @@ public:
             return false;
         }
 
-        if (!fHasVertexColor && this->getColor() != that.getColor()) {
+        if (!fHasVertexColor && this->color() != that.color()) {
             return false;
         }
 
-        if (!fHasVertexCoverage && this->getCoverage() != that.getCoverage()) {
+        // TODO this is fragile, most gps set their coverage to 0xff so this is okay.  In the long
+        // term this should move to subclasses which set explicit coverage
+        if (!fHasVertexCoverage && this->coverage() != that.coverage()) {
             return false;
         }
         return this->onIsEqual(that);
@@ -133,8 +152,8 @@ public:
 
     virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const {}
 
-    GrColor getColor() const { return fColor; }
-    uint8_t getCoverage() const { return fCoverage; }
+    GrColor color() const { return fColor; }
+    uint8_t coverage() const { return fCoverage; }
 
     // TODO this is a total hack until the gp can own whether or not it uses uniform
     // color / coverage
@@ -142,7 +161,8 @@ public:
     bool hasVertexCoverage() const { return fHasVertexCoverage; }
     bool hasLocalCoords() const { return fHasLocalCoords; }
 
-    void computeInvariantColor(GrInvariantOutput* inout) const;
+    void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
+    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE;
 
 protected:
     /**
@@ -163,6 +183,9 @@ protected:
     void setHasVertexCoverage() { fHasVertexCoverage = true; }
     void setHasLocalCoords() { fHasLocalCoords = true; }
 
+    virtual void onGetInvariantOutputColor(GrInitInvariantOutput*) const {}
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const = 0;
+
 private:
     virtual bool onIsEqual(const GrGeometryProcessor&) const = 0;
 
@@ -177,4 +200,26 @@ private:
 
     typedef GrProcessor INHERITED;
 };
+
+/*
+ * The path equivalent of the GP.  For now this just manages color. In the long term we plan on
+ * extending this class to handle all nvpr uniform / varying / program work.
+ */
+class GrPathProcessor : public GrPrimitiveProcessor {
+public:
+    static GrPathProcessor* Create(GrColor color) {
+        return SkNEW_ARGS(GrPathProcessor, (color));
+    }
+
+    const char* name() const SK_OVERRIDE { return "PathProcessor"; }
+    uint8_t coverage() const SK_OVERRIDE { return 0xff; }
+    void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
+    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE;
+
+private:
+    GrPathProcessor(GrColor color) : fColor(color) {}
+    GrColor fColor;
+
+    typedef GrProcessor INHERITED;
+};
 #endif
index 493420d..0b5c968 100644 (file)
@@ -62,14 +62,17 @@ void get_vertex_bounds(const void* vertices,
 
     The vertex attrib order is always pos, color, [local coords].
  */
-static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, GrColor color) {
+static const GrGeometryProcessor* create_rect_gp(GrDrawState* drawState,
+                                                 bool hasLocalCoords,
+                                                 GrColor color) {
     uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
                      GrDefaultGeoProcFactory::kColor_GPType;
     flags |= hasLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
-    drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
+    const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(color, flags);
     if (0xFF == GrColorUnpackA(color)) {
         drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
     }
+    return gp;
 }
 
 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
@@ -116,9 +119,10 @@ void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
                                      const SkMatrix* localMatrix) {
     GrDrawState::AutoRestoreEffects are(ds);
 
-    set_vertex_attributes(ds, SkToBool(localRect),  color);
+    SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(ds, SkToBool(localRect),
+                                                                     color));
 
-    size_t vstride = ds->getGeometryProcessor()->getVertexStride();
+    size_t vstride = gp->getVertexStride();
     SkASSERT(vstride == sizeof(SkPoint) + sizeof(GrColor) + (SkToBool(localRect) ? sizeof(SkPoint) :
                                                                                    0));
     AutoReleaseGeometry geo(this, 4, vstride, 0);
@@ -165,7 +169,7 @@ void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
     }
 
     this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
-    this->drawIndexedInstances(ds, kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
+    this->drawIndexedInstances(ds, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
 }
 
 int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds, const DrawInfo& info) {
@@ -221,13 +225,13 @@ int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds, const DrawIn
 }
 
 void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
+                                 const GrGeometryProcessor* gp,
                                  const DrawInfo& info,
                                  const ScissorState& scissorState,
                                  const GrDeviceCoordTexture* dstCopy) {
     SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
 
-    const GrGeometryProcessor* gp = ds.getGeometryProcessor();
-    if (!this->recordStateAndShouldDraw(ds, gp->getColor(), gp->getCoverage(),
+    if (!this->recordStateAndShouldDraw(ds, gp, NULL,
                                         GrGpu::PrimTypeToDrawType(info.primitiveType()),
                                         scissorState, dstCopy)) {
         return;
@@ -249,11 +253,12 @@ void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
 }
 
 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
+                                        const GrPathProcessor* pathProc,
                                         const GrPath* path,
                                         const GrClipMaskManager::ScissorState& scissorState,
                                         const GrStencilSettings& stencilSettings) {
     // Only compare the subset of GrDrawState relevant to path stenciling?
-    if (!this->recordStateAndShouldDraw(ds, GrColor_WHITE, 0xff, GrGpu::kStencilPath_DrawType,
+    if (!this->recordStateAndShouldDraw(ds, NULL, pathProc, GrGpu::kStencilPath_DrawType,
                                         scissorState, NULL)) {
         return;
     }
@@ -263,14 +268,14 @@ void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
 }
 
 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
-                                     GrColor color,
+                                     const GrPathProcessor* pathProc,
                                      const GrPath* path,
                                      const GrClipMaskManager::ScissorState& scissorState,
                                      const GrStencilSettings& stencilSettings,
                                      const GrDeviceCoordTexture* dstCopy) {
     // TODO: Only compare the subset of GrDrawState relevant to path covering?
-    if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState,
-                                        dstCopy)) {
+    if (!this->recordStateAndShouldDraw(ds, NULL, pathProc, GrGpu::kDrawPath_DrawType,
+                                        scissorState, dstCopy)) {
         return;
     }
     DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
@@ -279,7 +284,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
 }
 
 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
-                                      GrColor color,
+                                      const GrPathProcessor* pathProc,
                                       const GrPathRange* pathRange,
                                       const void* indices,
                                       PathIndexType indexType,
@@ -293,7 +298,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
     SkASSERT(indices);
     SkASSERT(transformValues);
 
-    if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState,
+    if (!this->recordStateAndShouldDraw(ds, NULL, pathProc, GrGpu::kDrawPath_DrawType, scissorState,
                                         dstCopy)) {
         return;
     }
@@ -324,7 +329,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
             transformType == previous->fTransformType &&
             stencilSettings == previous->fStencilSettings &&
             path_fill_type_is_winding(stencilSettings) &&
-            !ds.willBlendWithDst(color, GrColor_WHITE)) {
+            !ds.willBlendWithDst(pathProc)) {
             // Fold this DrawPaths call into the one previous.
             previous->fCount += count;
             return;
@@ -490,13 +495,13 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
 }
 
 bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds,
-                                                   GrColor color,
-                                                   uint8_t coverage,
+                                                   const GrGeometryProcessor* gp,
+                                                   const GrPathProcessor* pathProc,
                                                    GrGpu::DrawType drawType,
                                                    const GrClipMaskManager::ScissorState& scissor,
                                                    const GrDeviceCoordTexture* dstCopy) {
     SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
-                                            (ds, color, coverage, *this->getGpu()->caps(), scissor,
+                                            (ds, gp, pathProc, *this->getGpu()->caps(), scissor,
                                              dstCopy, drawType));
     if (ss->fState.mustSkip()) {
         fCmdBuffer.pop_back();
index 6771fcc..9b850a7 100644 (file)
@@ -171,11 +171,12 @@ private:
     };
 
     struct SetState : public Cmd {
-        SetState(const GrDrawState& drawState, GrColor color, uint8_t coverage,
-                 const GrDrawTargetCaps& caps, const ScissorState& scissor,
-                 const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType)
+        SetState(const GrDrawState& drawState, const GrGeometryProcessor* gp,
+                 const GrPathProcessor* pp, const GrDrawTargetCaps& caps,
+                 const ScissorState& scissor, const GrDeviceCoordTexture* dstCopy,
+                 GrGpu::DrawType drawType)
         : Cmd(kSetState_Cmd)
-        , fState(drawState, color, coverage, caps, scissor, dstCopy, drawType) {}
+        , fState(drawState, gp, pp, caps, scissor, dstCopy, drawType) {}
 
         void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE;
 
@@ -190,6 +191,7 @@ private:
 
     // overrides from GrDrawTarget
     void onDraw(const GrDrawState&,
+                const GrGeometryProcessor*,
                 const DrawInfo&,
                 const ScissorState&,
                 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
@@ -200,17 +202,18 @@ private:
                     const SkMatrix* localMatrix) SK_OVERRIDE;
 
     void onStencilPath(const GrDrawState&,
+                       const GrPathProcessor*,
                        const GrPath*,
                        const ScissorState&,
                        const GrStencilSettings&) SK_OVERRIDE;
     void onDrawPath(const GrDrawState&,
-                    GrColor,
+                    const GrPathProcessor*,
                     const GrPath*,
                     const ScissorState&,
                     const GrStencilSettings&,
                     const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
     void onDrawPaths(const GrDrawState&,
-                     GrColor,
+                     const GrPathProcessor*,
                      const GrPathRange*,
                      const void* indices,
                      PathIndexType,
@@ -237,8 +240,8 @@ private:
     // records it. If the draw can be skipped false is returned and no new GrOptDrawState is
     // recorded.
     bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(const GrDrawState&,
-                                                        GrColor,
-                                                        uint8_t coverage,
+                                                        const GrGeometryProcessor*,
+                                                        const GrPathProcessor*,
                                                         GrGpu::DrawType,
                                                         const GrClipMaskManager::ScissorState&,
                                                         const GrDeviceCoordTexture*);
index 9ebe551..010fe4b 100644 (file)
 #include "GrXferProcessor.h"
 
 GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
-                               GrColor color,
-                               uint8_t coverage,
+                               const GrGeometryProcessor* gp,
+                               const GrPathProcessor* pathProc,
                                const GrDrawTargetCaps& caps,
                                const ScissorState& scissorState,
                                const GrDeviceCoordTexture* dstCopy,
                                GrGpu::DrawType drawType)
     : fFinalized(false) {
-    GrColor coverageColor = GrColorPackRGBA(coverage, coverage, coverage, coverage);
     fDrawType = drawType;
 
-    const GrProcOptInfo& colorPOI = drawState.colorProcInfo(color);
-    const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(coverageColor);
+    // Copy GeometryProcesssor from DS or ODS
+    if (gp) {
+        SkASSERT(!pathProc);
+        SkASSERT(!(GrGpu::IsPathRenderingDrawType(drawType) ||
+                   GrGpu::kStencilPath_DrawType == drawType));
+        fGeometryProcessor.reset(gp);
+        fPrimitiveProcessor.reset(gp);
+    } else {
+        SkASSERT(!gp && pathProc && (GrGpu::IsPathRenderingDrawType(drawType) ||
+                               GrGpu::kStencilPath_DrawType == drawType));
+        fPrimitiveProcessor.reset(pathProc);
+    }
+
+
+    const GrProcOptInfo& colorPOI = drawState.colorProcInfo(fPrimitiveProcessor);
+    const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(fPrimitiveProcessor);
     
     fColor = colorPOI.inputColorToEffectiveStage();
-    fCoverage = coverage;
+    // TODO fix this when coverage stages work correctly
+    // fCoverage = coveragePOI.inputColorToEffectiveStage();
+    fCoverage = fPrimitiveProcessor->coverage();
 
     // Create XferProcessor from DS's XPFactory
     SkAutoTUnref<GrXferProcessor> xferProcessor(
@@ -86,14 +101,11 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
         fFlags |= kDither_Flag;
     }
 
-    fDescInfo.fHasVertexColor = drawState.hasGeometryProcessor() &&
-                                drawState.getGeometryProcessor()->hasVertexColor();
+    fDescInfo.fHasVertexColor = gp && gp->hasVertexColor();
 
-    fDescInfo.fHasVertexCoverage = drawState.hasGeometryProcessor() &&
-                                   drawState.getGeometryProcessor()->hasVertexCoverage();
+    fDescInfo.fHasVertexCoverage = gp && gp->hasVertexCoverage();
 
-    bool hasLocalCoords = drawState.hasGeometryProcessor() &&
-                          drawState.getGeometryProcessor()->hasLocalCoords();
+    bool hasLocalCoords = gp && gp->hasLocalCoords();
 
     int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
     fDescInfo.fInputColorIsUsed = colorPOI.inputColorIsUsed();
@@ -106,7 +118,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
     int firstCoverageStageIdx = 0;
     fDescInfo.fInputCoverageIsUsed = true;
 
-
     GrXferProcessor::BlendInfo blendInfo;
     fXferProcessor->getBlendInfo(&blendInfo);
     fSrcBlend = blendInfo.fSrcBlend;
@@ -118,12 +129,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
 
     fDescInfo.fRequiresLocalCoordAttrib = hasLocalCoords;
 
-    // Copy GeometryProcesssor from DS or ODS
-    SkASSERT(GrGpu::IsPathRenderingDrawType(drawType) ||
-             GrGpu::kStencilPath_DrawType ||
-             drawState.hasGeometryProcessor());
-    fGeometryProcessor.reset(drawState.getGeometryProcessor());
-
     // Copy Stages from DS to ODS
     for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) {
         SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
@@ -139,7 +144,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
     }
 
     // let the GP init the batch tracker
-    if (drawState.hasGeometryProcessor()) {
+    if (gp) {
         GrGeometryProcessor::InitBT init;
         init.fOutputColor = fDescInfo.fInputColorIsUsed;
         init.fOutputCoverage = fDescInfo.fInputCoverageIsUsed;
index 55a5071..1e7b5e5 100644 (file)
@@ -19,6 +19,7 @@
 
 class GrDeviceCoordTexture;
 class GrDrawState;
+class GrPathProcessor;
 
 /**
  * Class that holds an optimized version of a GrDrawState. It is meant to be an immutable class,
@@ -30,8 +31,9 @@ public:
 
     typedef GrClipMaskManager::ScissorState ScissorState;
 
-    GrOptDrawState(const GrDrawState& drawState, GrColor, uint8_t coverage, const GrDrawTargetCaps&,
-                   const ScissorState&, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
+    GrOptDrawState(const GrDrawState& drawState, const GrGeometryProcessor*, const GrPathProcessor*,
+                   const GrDrawTargetCaps&, const ScissorState&,
+                   const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
 
     bool operator== (const GrOptDrawState& that) const;
     bool operator!= (const GrOptDrawState& that) const { return !(*this == that); }
@@ -207,7 +209,7 @@ private:
      * the function may adjust the blend coefficients. After this function is called the src and dst
      * blend coeffs will represent those used by backend API.
      */
-    void setOutputStateInfo(const GrDrawState& ds, GrColor coverage, GrXferProcessor::OptFlags,
+    void setOutputStateInfo(const GrDrawState& ds, GrXferProcessor::OptFlags,
                             const GrDrawTargetCaps&);
 
     enum Flags {
@@ -219,6 +221,7 @@ private:
     typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
     typedef SkSTArray<8, GrPendingFragmentStage> FragmentStageArray;
     typedef GrPendingProgramElement<const GrGeometryProcessor> ProgramGeometryProcessor;
+    typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
     typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
     RenderTarget                        fRenderTarget;
     ScissorState                        fScissorState;
@@ -233,6 +236,7 @@ private:
     GrBlendCoeff                        fDstBlend;
     uint32_t                            fFlags;
     ProgramGeometryProcessor            fGeometryProcessor;
+    ProgramPrimitiveProcessor           fPrimitiveProcessor;
     GrBatchTracker                      fBatchTracker;
     ProgramXferProcessor                fXferProcessor;
     FragmentStageArray                  fFragmentStages;
index eac6fb4..22a18d2 100644 (file)
@@ -144,8 +144,8 @@ private:
         return cee.fStroke == fStroke;
     }
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
+        out->setUnknownSingleComponent();
     }
 
     const GrAttribute* fInPosition;
@@ -290,8 +290,8 @@ private:
         return eee.fStroke == fStroke;
     }
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
+        out->setUnknownSingleComponent();
     }
 
     const GrAttribute* fInPosition;
@@ -455,8 +455,8 @@ private:
         return eee.fMode == fMode;
     }
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
+        out->setUnknownSingleComponent();
     }
 
     const GrAttribute* fInPosition;
@@ -562,8 +562,8 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
         }
     }
 
-    GrGeometryProcessor* gp = CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0);
-    drawState->setGeometryProcessor(gp)->unref();
+    SkAutoTUnref<GrGeometryProcessor> gp(
+            CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(),  0);
     SkASSERT(gp->getVertexStride() == sizeof(CircleVertex));
@@ -609,7 +609,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
     verts[3].fInnerRadius = innerRadius;
 
     target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
-    target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
+    target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
     target->resetIndexSource();
 }
 
@@ -689,11 +689,8 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
         return false;
     }
 
-    GrGeometryProcessor* gp = EllipseEdgeEffect::Create(color,
-                                                        isStrokeOnly &&
-                                                        innerXRadius > 0 && innerYRadius > 0);
-
-    drawState->setGeometryProcessor(gp)->unref();
+    SkAutoTUnref<GrGeometryProcessor> gp(
+            EllipseEdgeEffect::Create(color, isStrokeOnly && innerXRadius > 0 && innerYRadius > 0));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(),  0);
     SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex));
@@ -744,7 +741,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
     verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
 
     target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
-    target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
+    target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
     target->resetIndexSource();
 
     return true;
@@ -809,9 +806,7 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
     SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
     SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
 
-    GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(color, mode);
-
-    drawState->setGeometryProcessor(gp)->unref();
+    SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(color, mode));
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(),  0);
     SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex));
@@ -857,7 +852,7 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
     verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
 
     target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
-    target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
+    target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
     target->resetIndexSource();
 
     return true;
@@ -1077,8 +1072,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
 
         isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
 
-        GrGeometryProcessor* effect = CircleEdgeEffect::Create(color, isStrokeOnly);
-        drawState->setGeometryProcessor(effect)->unref();
+        SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color, isStrokeOnly));
 
         GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(),  0);
         SkASSERT(effect->getVertexStride() == sizeof(CircleVertex));
@@ -1140,7 +1134,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
         int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
                                       SK_ARRAY_COUNT(gRRectIndices);
         target->setIndexSourceToBuffer(indexBuffer);
-        target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
+        target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
                                      &bounds);
 
     // otherwise we use the ellipse renderer
@@ -1179,8 +1173,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
 
         isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
 
-        GrGeometryProcessor* effect = EllipseEdgeEffect::Create(color, isStrokeOnly);
-        drawState->setGeometryProcessor(effect)->unref();
+        SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color, isStrokeOnly));
 
         GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(),  0);
         SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex));
@@ -1247,7 +1240,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
         int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
                                       SK_ARRAY_COUNT(gRRectIndices);
         target->setIndexSourceToBuffer(indexBuffer);
-        target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
+        target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
                                      &bounds);
     }
 
index a84ac2e..ebcf016 100644 (file)
 #include "GrFragmentStage.h"
 #include "GrGeometryProcessor.h"
 
+void GrProcOptInfo::calcColorWithPrimProc(const GrPrimitiveProcessor* primProc,
+                                          const GrFragmentStage* stages,
+                                          int stageCount) {
+    GrInitInvariantOutput out;
+    primProc->getInvariantOutputColor(&out);
+    fInOut.reset(out);
+    this->internalCalc(stages, stageCount, primProc->willReadFragmentPosition());
+}
+
+void GrProcOptInfo::calcCoverageWithPrimProc(const GrPrimitiveProcessor* primProc,
+                                             const GrFragmentStage* stages,
+                                             int stageCount) {
+    GrInitInvariantOutput out;
+    primProc->getInvariantOutputCoverage(&out);
+    fInOut.reset(out);
+    this->internalCalc(stages, stageCount, primProc->willReadFragmentPosition());
+}
+
 void GrProcOptInfo::calcWithInitialValues(const GrFragmentStage* stages,
                                           int stageCount,
                                           GrColor startColor,
                                           GrColorComponentFlags flags,
-                                          bool areCoverageStages,
-                                          const GrGeometryProcessor* gp) {
-    fInOut.reset(startColor, flags, areCoverageStages);
+                                          bool areCoverageStages) {
+    GrInitInvariantOutput out;
+    out.fIsSingleComponent = areCoverageStages;
+    out.fColor = startColor;
+    out.fValidFlags = flags;
+    this->internalCalc(stages, stageCount, false);
+}
+
+void GrProcOptInfo::internalCalc(const GrFragmentStage* stages,
+                                 int stageCount,
+                                 bool initWillReadFragmentPosition) {
     fFirstEffectStageIndex = 0;
     fInputColorIsUsed = true;
-    fInputColor = startColor;
+    fInputColor = fInOut.color();
     fRemoveVertexAttrib = false;
     fReadsDst = false;
-    fReadsFragPosition = false;
-
-    if (areCoverageStages && gp) {
-        gp->computeInvariantOutput(&fInOut);
-    }
+    fReadsFragPosition = initWillReadFragmentPosition;
 
     for (int i = 0; i < stageCount; ++i) {
         const GrFragmentProcessor* processor = stages[i].getProcessor();
         fInOut.resetWillUseInputColor();
         processor->computeInvariantOutput(&fInOut);
-#ifdef SK_DEBUG
-        fInOut.validate();
-#endif
+        SkDEBUGCODE(fInOut.validate());
         if (!fInOut.willUseInputColor()) {
             fFirstEffectStageIndex = i;
             fInputColorIsUsed = false;
             // Reset these since we don't care if previous stages read these values
             fReadsDst = false;
-            fReadsFragPosition = false;
+            fReadsFragPosition = initWillReadFragmentPosition;
         }
         if (processor->willReadDstColor()) {
             fReadsDst = true;
@@ -59,8 +79,7 @@ void GrProcOptInfo::calcWithInitialValues(const GrFragmentStage* stages,
             fInOut.resetNonMulStageFound();
             // Reset these since we don't care if previous stages read these values
             fReadsDst = false;
-            fReadsFragPosition = false;
+            fReadsFragPosition = initWillReadFragmentPosition;
         }
     }
 }
-
index 91ff5f9..30b286f 100644 (file)
@@ -13,7 +13,7 @@
 
 class GrFragmentStage;
 class GrFragmentProcessor;
-class GrGeometryProcessor;
+class GrPrimitiveProcessor;
 class GrProcessor;
 
 /**
@@ -33,8 +33,11 @@ public:
         , fReadsFragPosition(false) {}
 
     void calcWithInitialValues(const GrFragmentStage*, int stageCount, GrColor startColor,
-                               GrColorComponentFlags flags, bool areCoverageStages,
-                               const GrGeometryProcessor* gp = NULL);
+                               GrColorComponentFlags flags, bool areCoverageStages);
+
+    void calcColorWithPrimProc(const GrPrimitiveProcessor*, const GrFragmentStage*, int stagecount);
+    void calcCoverageWithPrimProc(const GrPrimitiveProcessor*, const GrFragmentStage*,
+                                  int stagecount);
 
     bool isSolidWhite() const { return fInOut.isSolidWhite(); }
     bool isOpaque() const { return fInOut.isOpaque(); }
@@ -89,6 +92,8 @@ public:
     bool readsFragPosition() const { return fReadsFragPosition; }
 
 private:
+    void internalCalc(const GrFragmentStage*, int stagecount, bool initWillReadFragPosition);
+
     GrInvariantOutput fInOut;
     int fFirstEffectStageIndex;
     bool fInputColorIsUsed;
index 2bcd9b4..c937c2e 100644 (file)
@@ -145,10 +145,6 @@ bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const {
     return true;
 }
 
-void GrProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
-    this->onComputeInvariantOutput(inout);
-}
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
@@ -169,10 +165,33 @@ bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) con
     return true;
 }
 
+void GrFragmentProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
+    this->onComputeInvariantOutput(inout);
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-void GrGeometryProcessor::computeInvariantColor(GrInvariantOutput* intout) const {
+void GrGeometryProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
+    if (fHasVertexColor) {
+        out->setUnknownFourComponents();
+    } else {
+        out->setKnownFourComponents(fColor);
+    }
+    this->onGetInvariantOutputColor(out);
+}
 
+void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+    this->onGetInvariantOutputCoverage(out);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
+    out->setKnownFourComponents(fColor);
+}
+
+void GrPathProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+    out->setKnownSingleComponent(0xff);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -193,4 +212,3 @@ void GrGeometryData::operator delete(void* target) {
 // Initial static variable from GrXPFactory
 int32_t GrXPFactory::gCurrXPFClassID =
         GrXPFactory::kIllegalXPFClassID;
-
index e7c4fc8..d8470f3 100644 (file)
@@ -85,8 +85,9 @@ void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target,
                                                   const SkPath& path,
                                                   const SkStrokeRec& stroke) {
     SkASSERT(!path.isInverseFillType());
+    SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE));
     SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
-    target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillType()));
+    target->stencilPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
 }
 
 bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
@@ -117,7 +118,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
         drawState->setStencil(kInvertedStencilPass);
 
         // fake inverse with a stencil and cover
-        target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillType()));
+        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE));
+        target->stencilPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
 
         GrDrawState::AutoViewMatrixRestore avmr;
         SkRect bounds = SkRect::MakeLTRB(0, 0,
@@ -145,7 +147,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
             0xffff);
 
         drawState->setStencil(kStencilPass);
-        target->drawPath(drawState, color, p, convert_skpath_filltype(path.getFillType()));
+        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(color));
+        target->drawPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
     }
 
     drawState->stencil()->setDisabled();
index bf1e58d..42f74ea 100644 (file)
@@ -399,7 +399,8 @@ static const SkScalar* get_xy_scalar_array(const SkPoint* pointArray) {
 
 void GrStencilAndCoverTextContext::flush() {
     if (fQueuedGlyphCount > 0) {
-        fDrawTarget->drawPaths(&fDrawState, fPaint.getColor(), fGlyphs,
+        SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor()));
+        fDrawTarget->drawPaths(&fDrawState, pp, fGlyphs,
                                fGlyphIndices, GrPathRange::kU16_PathIndexType,
                                get_xy_scalar_array(fGlyphPositions),
                                GrPathRendering::kTranslate_PathTransformType,
index a9cbeb0..53b1053 100644 (file)
@@ -102,8 +102,8 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
+        out->setUnknownSingleComponent();
     }
 
     GrPrimitiveEdgeType   fEdgeType;
@@ -171,8 +171,8 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
+        out->setUnknownSingleComponent();
     }
 
     GrPrimitiveEdgeType   fEdgeType;
@@ -241,8 +241,8 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
-        inout->mulByUnknownAlpha();
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
+        out->setUnknownSingleComponent();
     }
 
     GrPrimitiveEdgeType   fEdgeType;
index 8ada70e..76edff0 100644 (file)
@@ -175,7 +175,7 @@ bool GrBicubicEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
 
 void GrBicubicEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
     // FIXME: Perhaps we can do better.
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect);
index 1578fd8..9c5e82e 100644 (file)
@@ -84,15 +84,15 @@ bool GrBitmapTextGeoProc::onIsEqual(const GrGeometryProcessor& other) const {
     return SkToBool(this->inColor()) == SkToBool(gp.inColor());
 }
 
-void GrBitmapTextGeoProc::onComputeInvariantOutput(GrInvariantOutput* inout) const {
+void GrBitmapTextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
     if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
-        inout->mulByUnknownAlpha();
+        out->setUnknownSingleComponent();
     } else if (GrPixelConfigIsOpaque(this->texture(0)->config())) {
-        inout->mulByUnknownOpaqueColor();
-        inout->setUsingLCDCoverage();
+        out->setUnknownOpaqueFourComponents();
+        out->setUsingLCDCoverage();
     } else {
-        inout->mulByUnknownColor();
-        inout->setUsingLCDCoverage();
+        out->setUnknownFourComponents();
+        out->setUsingLCDCoverage();
     }
 }
 
index ce235ae..ef86704 100644 (file)
@@ -45,7 +45,7 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
 
     GrTextureAccess    fTextureAccess;
     const GrAttribute* fInPosition;
index 248cd17..1430716 100644 (file)
@@ -44,9 +44,9 @@ private:
     virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
         if (fRect.isEmpty()) {
             // An empty rect will have no coverage anywhere.
-            inout->mulByKnownAlpha(0);
+            inout->mulByKnownSingleComponent(0);
         } else {
-            inout->mulByUnknownAlpha();
+            inout->mulByUnknownSingleComponent();
         }
     }
 
@@ -323,7 +323,7 @@ GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, co
 GrConvexPolyEffect::~GrConvexPolyEffect() {}
 
 void GrConvexPolyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 void GrConvexPolyEffect::getGLProcessorKey(const GrGLCaps& caps,
index 7fda369..1d0950b 100644 (file)
@@ -99,7 +99,7 @@ private:
     virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const {
         // If the texture was opaque we could know that the output color if we knew the sum of the
         // kernel values.
-        inout->mulByUnknownColor();
+        inout->mulByUnknownFourComponents();
     }
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
index b59b2a6..1641d27 100644 (file)
@@ -335,7 +335,7 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
         devIntervals[0] = lineLength;
     }
 
-    const GrGeometryProcessor* gp;
+    SkAutoTUnref<const GrGeometryProcessor> gp;
     bool fullDash = devIntervals[1] > 0.f || useAA;
     if (fullDash) {
         SkPathEffect::DashInfo devInfo;
@@ -347,14 +347,12 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
         bool isRoundCap = SkPaint::kRound_Cap == cap;
         GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_DashCap :
                                                         GrDashingEffect::kNonRound_DashCap;
-        gp = GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType);
+        gp.reset(GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType));
     } else {
         // Set up the vertex data for the line and start/end dashes
-        gp = GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory::kPosition_GPType);
+        gp.reset(GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory::kPosition_GPType));
     }
 
-    drawState->setGeometryProcessor(gp)->unref();
-
     int totalRectCnt = 0;
 
     totalRectCnt += !lineDone ? 1 : 0;
@@ -435,7 +433,7 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
     }
 
     target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
-    target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, totalRectCnt, 4, 6);
+    target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, totalRectCnt, 4, 6);
     target->resetIndexSource();
     return true;
 }
@@ -489,7 +487,7 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
 
     GrPrimitiveEdgeType fEdgeType;
     const GrAttribute*  fInPosition;
@@ -614,8 +612,8 @@ GrGeometryProcessor* DashingCircleEffect::Create(GrColor color,
 
 DashingCircleEffect::~DashingCircleEffect() {}
 
-void DashingCircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+    out->setUnknownSingleComponent();
 }
 
 void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt,
@@ -719,7 +717,7 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
 
     GrPrimitiveEdgeType fEdgeType;
     const GrAttribute*  fInPosition;
@@ -857,8 +855,8 @@ GrGeometryProcessor* DashingLineEffect::Create(GrColor color,
 
 DashingLineEffect::~DashingLineEffect() {}
 
-void DashingLineEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+    out->setUnknownSingleComponent();
 }
 
 void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt,
index f408d2d..be06c1d 100755 (executable)
@@ -206,8 +206,8 @@ bool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) c
            fFlags == cte.fFlags;
 }
 
-void GrDistanceFieldTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+void GrDistanceFieldTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+    out->setUnknownSingleComponent();
 }
 
 void GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
@@ -407,8 +407,8 @@ bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrGeometryProcessor& o
     return fFlags == cte.fFlags;
 }
 
-void GrDistanceFieldNoGammaTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
+    out->setUnknownSingleComponent();
 }
 
 void GrDistanceFieldNoGammaTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
@@ -665,9 +665,9 @@ bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other
             fFlags == cte.fFlags);
 }
 
-void GrDistanceFieldLCDTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownColor();
-    inout->setUsingLCDCoverage();
+void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+    out->setUnknownFourComponents();
+    out->setUsingLCDCoverage();
 }
 
 void GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
index f0f7e3b..a290d57 100644 (file)
@@ -87,7 +87,7 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
 
     GrTextureAccess    fTextureAccess;
 #ifdef SK_GAMMA_APPLY_TO_A8
@@ -139,7 +139,7 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
 
     GrTextureAccess    fTextureAccess;
     uint32_t           fFlags;
@@ -190,7 +190,7 @@ private:
 
     virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
 
-    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
+    virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
 
     GrTextureAccess    fTextureAccess;
     GrTextureAccess    fGammaTextureAccess;
index 6d60609..8d6bb7c 100644 (file)
@@ -81,7 +81,7 @@ private:
 
     virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
         // TODO: Try to do better?
-        inout->mulByUnknownColor();
+        inout->mulByUnknownFourComponents();
     }
 
     SkIRect         fBounds;
index b750599..f1d1e68 100644 (file)
@@ -56,7 +56,7 @@ GrFragmentProcessor* CircleEffect::Create(GrPrimitiveEdgeType edgeType, const Sk
 }
 
 void CircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
@@ -233,7 +233,7 @@ GrFragmentProcessor* EllipseEffect::Create(GrPrimitiveEdgeType edgeType,
 }
 
 void EllipseEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry)
index 64a9d41..1c1bd18 100644 (file)
@@ -86,7 +86,7 @@ GrFragmentProcessor* CircularRRectEffect::Create(GrPrimitiveEdgeType edgeType,
 }
 
 void CircularRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags,
@@ -426,7 +426,7 @@ EllipticalRRectEffect::Create(GrPrimitiveEdgeType edgeType, const SkRRect& rrect
 }
 
 void EllipticalRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->mulByUnknownAlpha();
+    inout->mulByUnknownSingleComponent();
 }
 
 EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)
index 6fd6819..9df0cff 100644 (file)
@@ -41,11 +41,11 @@ protected:
      */
     void updateInvariantOutputForModulation(GrInvariantOutput* inout) const {
         if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
-            inout->mulByUnknownAlpha();
+            inout->mulByUnknownSingleComponent();
         } else if (GrPixelConfigIsOpaque(this->texture(0)->config())) {
-            inout->mulByUnknownOpaqueColor();
+            inout->mulByUnknownOpaqueFourComponents();
         } else {
-            inout->mulByUnknownColor();
+            inout->mulByUnknownFourComponents();
         }
     }
 
index b5b9ae4..f1ef618 100644 (file)
@@ -273,9 +273,9 @@ bool GrTextureDomainEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
 void GrTextureDomainEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
     if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper
         if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
-            inout->mulByUnknownAlpha();
+            inout->mulByUnknownSingleComponent();
         } else {
-            inout->mulByUnknownColor();
+            inout->mulByUnknownFourComponents();
         }
     } else {
         this->updateInvariantOutputForModulation(inout);
index 953b5e0..c0de2a5 100644 (file)
@@ -129,19 +129,14 @@ static void set_random_xpf(GrContext* context, const GrDrawTargetCaps& caps, GrD
     ds->setXPFactory(xpf.get());
 }
 
-static void set_random_gp(GrContext* context,
-                          const GrDrawTargetCaps& caps,
-                          GrDrawState* ds,
-                          SkRandom* random,
-                          GrTexture* dummyTextures[]) {
-    SkAutoTUnref<const GrGeometryProcessor> gp(
-            GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random,
-                                                                     context,
-                                                                     caps,
-                                                                     dummyTextures));
-    SkASSERT(gp);
-
-    ds->setGeometryProcessor(gp);
+static const GrGeometryProcessor* get_random_gp(GrContext* context,
+                                                const GrDrawTargetCaps& caps,
+                                                SkRandom* random,
+                                                GrTexture* dummyTextures[]) {
+    return GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random,
+                                                                    context,
+                                                                    caps,
+                                                                    dummyTextures);
 }
 
 static void set_random_color_coverage_stages(GrGpuGL* gpu,
@@ -293,8 +288,12 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
 
         // twiddle drawstate knobs randomly
         bool hasGeometryProcessor = !usePathRendering;
+        const GrGeometryProcessor* gp = NULL;
+        const GrPathProcessor* pathProc = NULL;
         if (hasGeometryProcessor) {
-            set_random_gp(fContext, gpu->glCaps(), &ds, &random, dummyTextures);
+            gp = get_random_gp(fContext, gpu->glCaps(), &random, dummyTextures);
+        } else {
+            pathProc = GrPathProcessor::Create(GrColor_WHITE);
         }
         set_random_color_coverage_stages(gpu,
                                          &ds,
@@ -312,19 +311,20 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
 
         GrDeviceCoordTexture dstCopy;
 
-        // TODO take color off the PP when its installed
-        GrColor color = ds.hasGeometryProcessor() ? ds.getGeometryProcessor()->getColor() :
-                                                    GrColor_WHITE;
-        uint8_t coverage = ds.hasGeometryProcessor() ? ds.getGeometryProcessor()->getCoverage() :
-                                                       0xff;
-        if (!this->setupDstReadIfNecessary(&ds, color, coverage, &dstCopy, NULL)) {
+        const GrPrimitiveProcessor* primProc;
+        if (hasGeometryProcessor) {
+            primProc = gp;
+        } else {
+            primProc = pathProc;
+        }
+        if (!this->setupDstReadIfNecessary(&ds, primProc, &dstCopy, NULL)) {
             SkDebugf("Couldn't setup dst read texture");
             return false;
         }
 
         // create optimized draw state, setup readDst texture if required, and build a descriptor
         // and program.  ODS creation can fail, so we have to check
-        GrOptDrawState ods(ds, color, coverage, *gpu->caps(), scissor, &dstCopy, drawType);
+        GrOptDrawState ods(ds, gp, pathProc, *gpu->caps(), scissor, &dstCopy, drawType);
         if (ods.mustSkip()) {
             continue;
         }