Vertex Attrib configurations now handled as pointers vs. SkSTArrays
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Sat, 20 Apr 2013 12:26:07 +0000 (12:26 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Sat, 20 Apr 2013 12:26:07 +0000 (12:26 +0000)
https://codereview.chromium.org/14328009/

git-svn-id: http://skia.googlecode.com/svn/trunk@8787 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/GrAAConvexPathRenderer.cpp
src/gpu/GrAAHairLinePathRenderer.cpp
src/gpu/GrAARectRenderer.cpp
src/gpu/GrContext.cpp
src/gpu/GrDrawState.cpp
src/gpu/GrDrawState.h
src/gpu/GrDrawTarget.cpp
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrOvalRenderer.cpp
src/gpu/GrTextContext.cpp

index 22964e5..d7d19a3 100644 (file)
@@ -558,6 +558,16 @@ bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path,
             stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex());
 }
 
+namespace {
+
+// position + edge
+extern const GrVertexAttrib gPathAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
+    {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
+};
+
+};
+
 bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
                                         const SkStrokeRec&,
                                         GrDrawTarget* target,
@@ -602,12 +612,7 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
         return false;
     }
 
-    // position + edge
-    static const GrVertexAttrib kAttribs[] = {
-        {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-        {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
-    };
-    drawState->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs));
+    drawState->setVertexAttribs<gPathAttribs>(SK_ARRAY_COUNT(gPathAttribs));
 
     enum {
         // the edge effects share this stage with glyph rendering
index 3e9bc1b..0a19d6c 100644 (file)
@@ -694,6 +694,16 @@ GrEffectRef* HairLineEdgeEffect::TestCreate(SkMWCRandom* random,
 
 ///////////////////////////////////////////////////////////////////////////////
 
+namespace {
+
+// position + edge
+extern const GrVertexAttrib gHairlineAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,                  kPosition_GrVertexAttribBinding},
+    {kVec4f_GrVertexAttribType, sizeof(GrPoint),    kEffect_GrVertexAttribBinding}
+};
+
+};
+
 bool GrAAHairLinePathRenderer::createGeom(
             const SkPath& path,
             GrDrawTarget* target,
@@ -707,11 +717,6 @@ bool GrAAHairLinePathRenderer::createGeom(
     target->getClip()->getConservativeBounds(drawState->getRenderTarget(),
                                              &devClipBounds);
 
-    // position + edge
-    static const GrVertexAttrib kAttribs[] = {
-        {kVec2f_GrVertexAttribType, 0,                  kPosition_GrVertexAttribBinding},
-        {kVec4f_GrVertexAttribType, sizeof(GrPoint),    kEffect_GrVertexAttribBinding}
-    };
     SkMatrix viewM = drawState->getViewMatrix();
 
     PREALLOC_PTARRAY(128) lines;
@@ -723,7 +728,7 @@ bool GrAAHairLinePathRenderer::createGeom(
     *lineCnt = lines.count() / 2;
     int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt;
 
-    target->drawState()->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs));
+    target->drawState()->setVertexAttribs<gHairlineAttribs>(SK_ARRAY_COUNT(gHairlineAttribs));
     GrAssert(sizeof(Vertex) == target->getDrawState().getVertexSize());
 
     if (!arg->set(target, vertCnt, 0)) {
index ea15ce3..eacd3f1 100644 (file)
@@ -142,17 +142,22 @@ GrEffectRef* GrRectEffect::TestCreate(SkMWCRandom* random,
 
 namespace {
 
-static void aa_rect_attributes(bool useCoverage, const GrVertexAttrib** attribs, int* count) {
-    static const GrVertexAttrib kCoverageAttribs[] = {
-        {kVec2f_GrVertexAttribType,  0, kPosition_GrVertexAttribBinding},
-        {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kCoverage_GrVertexAttribBinding},
-    };
-    static const GrVertexAttrib kColorAttribs[] = {
-        {kVec2f_GrVertexAttribType,  0, kPosition_GrVertexAttribBinding},
-        {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding},
-    };
-    *attribs = useCoverage ? kCoverageAttribs : kColorAttribs;
-    *count = 2;
+extern const GrVertexAttrib gAARectCoverageAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0,               kPosition_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kCoverage_GrVertexAttribBinding},
+};
+
+extern const GrVertexAttrib gAARectColorAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0,               kPosition_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding},
+};
+
+static void set_aa_rect_vertex_attributes(GrDrawState* drawState, bool useCoverage) {
+    if (useCoverage) {
+        drawState->setVertexAttribs<gAARectCoverageAttribs>(SK_ARRAY_COUNT(gAARectCoverageAttribs));
+    } else {
+        drawState->setVertexAttribs<gAARectColorAttribs>(SK_ARRAY_COUNT(gAARectColorAttribs));
+    }
 }
 
 static void set_inset_fan(GrPoint* pts, size_t stride,
@@ -259,10 +264,7 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu,
                                   bool useVertexCoverage) {
     GrDrawState* drawState = target->drawState();
 
-    const GrVertexAttrib* attribs;
-    int attribCount;
-    aa_rect_attributes(useVertexCoverage, &attribs, &attribCount);
-    drawState->setVertexAttribs(attribs, attribCount);
+    set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0);
     if (!geo.succeeded()) {
@@ -317,6 +319,15 @@ struct RectVertex {
     GrPoint fWidthHeight;
 };
 
+namespace {
+
+extern const GrVertexAttrib gAARectVertexAttribs[] = {
+    { kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding },
+    { kVec4f_GrVertexAttribType, sizeof(GrPoint),   kEffect_GrVertexAttribBinding },
+    { kVec2f_GrVertexAttribType, 3*sizeof(GrPoint), kEffect_GrVertexAttribBinding }
+};
+
+};
 
 void GrAARectRenderer::shaderFillAARect(GrGpu* gpu,
                                         GrDrawTarget* target,
@@ -344,12 +355,7 @@ void GrAARectRenderer::shaderFillAARect(GrGpu* gpu,
     SkScalar newWidth = vec[0].length() / 2.0f + 0.5f;
     SkScalar newHeight = vec[1].length() / 2.0f + 0.5f;
 
-    static const GrVertexAttrib kVertexAttribs[] = {
-        { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
-        { kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding },
-        { kVec2f_GrVertexAttribType, 3*sizeof(GrPoint), kEffect_GrVertexAttribBinding }
-    };
-    drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
+    drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVertexAttribs));
     GrAssert(sizeof(RectVertex) == drawState->getVertexSize());
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
@@ -422,10 +428,7 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu,
         return;
     }
 
-    const GrVertexAttrib* attribs;
-    int attribCount;
-    aa_rect_attributes(useVertexCoverage, &attribs, &attribCount);
-    drawState->setVertexAttribs(attribs, attribCount);
+    set_aa_rect_vertex_attributes(drawState, useVertexCoverage);
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
     if (!geo.succeeded()) {
index 85c241a..2a6e20a 100644 (file)
@@ -322,6 +322,16 @@ static void stretchImage(void* dst,
     }
 }
 
+namespace {
+
+// position + local coordinate
+extern const GrVertexAttrib gVertexAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
+};
+
+};
+
 // The desired texture is NPOT and tiled but that isn't supported by
 // the current hardware. Resize the texture to be a POT
 GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
@@ -358,12 +368,7 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
         GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
         drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params);
 
-        // position + local coordinate
-        static const GrVertexAttrib kVertexAttribs[] = {
-            {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-            {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
-        };
-        drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
+        drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs));
 
         GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0);
 
@@ -870,6 +875,44 @@ void GrContext::drawRectToRect(const GrPaint& paint,
     target->drawRect(dstRect, dstMatrix, &localRect, localMatrix);
 }
 
+namespace {
+
+extern const GrVertexAttrib gPosUVColorAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0, kPosition_GrVertexAttribBinding },
+    {kVec2f_GrVertexAttribType,  sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding },
+    {kVec4ub_GrVertexAttribType, 2*sizeof(GrPoint), kColor_GrVertexAttribBinding} 
+};
+
+extern const GrVertexAttrib gPosColorAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0, kPosition_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding},
+};
+
+static void set_vertex_attributes(GrDrawState* drawState,
+                                  const GrPoint* texCoords,
+                                  const GrColor* colors,
+                                  int* colorOffset,
+                                  int* texOffset) {
+    *texOffset = -1;
+    *colorOffset = -1;
+
+    if (NULL != texCoords && NULL != colors) {
+        *texOffset = sizeof(GrPoint);
+        *colorOffset = 2*sizeof(GrPoint);
+        drawState->setVertexAttribs<gPosUVColorAttribs>(3);
+    } else if (NULL != texCoords) {
+        *texOffset = sizeof(GrPoint);
+        drawState->setVertexAttribs<gPosUVColorAttribs>(2);
+    } else if (NULL != colors) {
+        *colorOffset = sizeof(GrPoint);
+        drawState->setVertexAttribs<gPosColorAttribs>(2);
+    } else {
+        drawState->setVertexAttribs<gPosColorAttribs>(1);
+    }
+}
+
+};
+
 void GrContext::drawVertices(const GrPaint& paint,
                              GrPrimitiveType primitiveType,
                              int vertexCount,
@@ -887,36 +930,10 @@ void GrContext::drawVertices(const GrPaint& paint,
 
     GrDrawState* drawState = target->drawState();
 
-    GrVertexAttribArray<3> attribs;
-    size_t currentOffset = 0;
     int colorOffset = -1, texOffset = -1;
-
-    // set position attribute
-    GrVertexAttrib currAttrib =
-        {kVec2f_GrVertexAttribType, currentOffset, kPosition_GrVertexAttribBinding};
-    attribs.push_back(currAttrib);
-    currentOffset += sizeof(GrPoint);
-
-    // set up optional texture coordinate attributes
-    if (NULL != texCoords) {
-        currAttrib.set(kVec2f_GrVertexAttribType, currentOffset, kLocalCoord_GrVertexAttribBinding);
-        attribs.push_back(currAttrib);
-        texOffset = currentOffset;
-        currentOffset += sizeof(GrPoint);
-    }
-
-    // set up optional color attributes
-    if (NULL != colors) {
-        currAttrib.set(kVec4ub_GrVertexAttribType, currentOffset, kColor_GrVertexAttribBinding);
-        attribs.push_back(currAttrib);
-        colorOffset = currentOffset;
-        currentOffset += sizeof(GrColor);
-    }
-
-    drawState->setVertexAttribs(attribs.begin(), attribs.count());
+    set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset);
 
     size_t vertexSize = drawState->getVertexSize();
-    GrAssert(vertexSize == currentOffset);
     if (sizeof(GrPoint) != vertexSize) {
         if (!geo.set(target, vertexCount, 0)) {
             GrPrintf("Failed to get space for vertices!\n");
index 21bff8b..90188ea 100644 (file)
@@ -68,14 +68,16 @@ static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
 }
 
 size_t GrDrawState::getVertexSize() const {
-    return vertex_size(fCommon.fVertexAttribs.begin(), fCommon.fVertexAttribs.count());
+    return vertex_size(fCommon.fVAPtr, fCommon.fVACount);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
     GrAssert(count <= kMaxVertexAttribCnt);
-    fCommon.fVertexAttribs.reset(attribs, count);
+
+    fCommon.fVAPtr = attribs;
+    fCommon.fVACount = count;
 
     // Set all the indices to -1
     memset(fCommon.fFixedFunctionVertexAttribIndices,
@@ -109,7 +111,10 @@ void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
 void GrDrawState::setDefaultVertexAttribs() {
     static const GrVertexAttrib kPositionAttrib =
         {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
-    fCommon.fVertexAttribs.reset(&kPositionAttrib, 1);
+
+    fCommon.fVAPtr = &kPositionAttrib;
+    fCommon.fVACount = 1;
+
     // set all the fixed function indices to -1 except position.
     memset(fCommon.fFixedFunctionVertexAttribIndices,
            0xff,
@@ -136,13 +141,13 @@ bool GrDrawState::validateVertexAttribs() const {
             int numAttributes = stage.getVertexAttribIndexCount();
             for (int i = 0; i < numAttributes; ++i) {
                 int attribIndex = attributeIndices[i];
-                if (attribIndex >= fCommon.fVertexAttribs.count() ||
-                    kEffect_GrVertexAttribBinding != fCommon.fVertexAttribs[attribIndex].fBinding) {
+                if (attribIndex >= fCommon.fVACount ||
+                    kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) {
                     return false;
                 }
 
                 GrSLType effectSLType = (*effect)->vertexAttribType(i);
-                GrVertexAttribType attribType = fCommon.fVertexAttribs[attribIndex].fType;
+                GrVertexAttribType attribType = fCommon.fVAPtr[attribIndex].fType;
                 int slVecCount = GrSLTypeVectorCount(effectSLType);
                 int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
                 if (slVecCount != attribVecCount ||
index 0beebf7..e34e4ab 100644 (file)
@@ -120,15 +120,15 @@ public:
      */
 
     /**
-     *  Sets vertex attributes for next draw.
-     *
-     *  @param attribs    the array of vertex attributes to set.
-     *  @param count      the number of attributes being set, limited to kMaxVertexAttribCnt.
+     *  Sets vertex attributes for next draw. The object driving the templatization
+     *  should be a global GrVertexAttrib array that is never changed.
      */
-    void setVertexAttribs(const GrVertexAttrib attribs[], int count);
+    template <const GrVertexAttrib A[]> void setVertexAttribs(int count) {
+        this->setVertexAttribs(A, count);
+    }
 
-    const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVertexAttribs.begin(); }
-    int getVertexAttribCount() const { return fCommon.fVertexAttribs.count(); }
+    const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVAPtr; }
+    int getVertexAttribCount() const { return fCommon.fVACount; }
 
     size_t getVertexSize() const;
 
@@ -177,17 +177,20 @@ public:
          AutoVertexAttribRestore(GrDrawState* drawState) {
              GrAssert(NULL != drawState);
              fDrawState = drawState;
-             fVertexAttribs = drawState->fCommon.fVertexAttribs;
+             fVAPtr = drawState->fCommon.fVAPtr;
+             fVACount = drawState->fCommon.fVACount;
              fDrawState->setDefaultVertexAttribs();
          }
 
          ~AutoVertexAttribRestore(){
-             fDrawState->fCommon.fVertexAttribs = fVertexAttribs;
+             fDrawState->fCommon.fVAPtr = fVAPtr;
+             fDrawState->fCommon.fVACount = fVACount;
          }
 
      private:
-         GrDrawState*                               fDrawState;
-         GrVertexAttribArray<kMaxVertexAttribCnt>   fVertexAttribs;
+         GrDrawState*          fDrawState;
+         const GrVertexAttrib* fVAPtr;
+         int                   fVACount;
      };
 
     /**
@@ -1034,19 +1037,20 @@ private:
     /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
     struct CommonState {
         // These fields are roughly sorted by decreasing likelihood of being different in op==
-        GrColor                                  fColor;
-        SkMatrix                                 fViewMatrix;
-        GrBlendCoeff                             fSrcBlend;
-        GrBlendCoeff                             fDstBlend;
-        GrColor                                  fBlendConstant;
-        uint32_t                                 fFlagBits;
-        GrVertexAttribArray<kMaxVertexAttribCnt> fVertexAttribs;
-        GrStencilSettings                        fStencilSettings;
-        int                                      fFirstCoverageStage;
-        GrColor                                  fCoverage;
-        SkXfermode::Mode                         fColorFilterMode;
-        GrColor                                  fColorFilterColor;
-        DrawFace                                 fDrawFace;
+        GrColor               fColor;
+        SkMatrix              fViewMatrix;
+        GrBlendCoeff          fSrcBlend;
+        GrBlendCoeff          fDstBlend;
+        GrColor               fBlendConstant;
+        uint32_t              fFlagBits;
+        const GrVertexAttrib* fVAPtr;
+        int                   fVACount;
+        GrStencilSettings     fStencilSettings;
+        int                   fFirstCoverageStage;
+        GrColor               fCoverage;
+        SkXfermode::Mode      fColorFilterMode;
+        GrColor               fColorFilterColor;
+        DrawFace              fDrawFace;
 
         // This is simply a different representation of info in fVertexAttribs and thus does
         // not need to be compared in op==.
@@ -1059,7 +1063,8 @@ private:
                           fDstBlend == other.fDstBlend &&
                           fBlendConstant == other.fBlendConstant &&
                           fFlagBits == other.fFlagBits &&
-                          fVertexAttribs == other.fVertexAttribs &&
+                          fVACount == other.fVACount &&
+                          !memcmp(fVAPtr, other.fVAPtr, fVACount * sizeof(GrVertexAttrib)) &&
                           fStencilSettings == other.fStencilSettings &&
                           fFirstCoverageStage == other.fFirstCoverageStage &&
                           fCoverage == other.fCoverage &&
@@ -1146,6 +1151,14 @@ private:
     CommonState                            fCommon;
     GrEffectStage                          fStages[kNumStages];
 
+    /**
+     *  Sets vertex attributes for next draw.
+     *
+     *  @param attribs    the array of vertex attributes to set.
+     *  @param count      the number of attributes being set, limited to kMaxVertexAttribCnt.
+     */
+    void setVertexAttribs(const GrVertexAttrib attribs[], int count);
+
     typedef GrRefCnt INHERITED;
 };
 
index 4e8ae7d..aa876a0 100644 (file)
@@ -590,27 +590,36 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
 
 ////////////////////////////////////////////////////////////////////////////////
 
+namespace {
+
+// position + (optional) texture coord
+extern const GrVertexAttrib gBWRectPosUVAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
+};
+
+void set_vertex_attributes(GrDrawState* drawState, bool hasUVs) {
+    if (hasUVs) {
+        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2);
+    } else {
+        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1);
+    }
+}
+
+};
+
 void GrDrawTarget::onDrawRect(const GrRect& rect,
                               const SkMatrix* matrix,
                               const GrRect* localRect,
                               const SkMatrix* localMatrix) {
-    // position + (optional) texture coord
-    static const GrVertexAttrib kAttribs[] = {
-        {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-        {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
-    };
-    int attribCount = 1;
-
-    if (NULL != localRect) {
-        attribCount = 2;
-    }
 
     GrDrawState::AutoViewMatrixRestore avmr;
     if (NULL != matrix) {
         avmr.set(this->drawState(), *matrix);
     }
 
-    this->drawState()->setVertexAttribs(kAttribs, attribCount);
+    set_vertex_attributes(this->drawState(), NULL != localRect);
+
     AutoReleaseGeometry geo(this, 4, 0);
     if (!geo.succeeded()) {
         GrPrintf("Failed to get space for vertices!\n");
@@ -620,9 +629,8 @@ void GrDrawTarget::onDrawRect(const GrRect& rect,
     size_t vsize = this->drawState()->getVertexSize();
     geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
     if (NULL != localRect) {
-        GrAssert(attribCount == 2);
         GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
-                                            kAttribs[1].fOffset);
+                                            sizeof(GrPoint));
         coords->setRectFan(localRect->fLeft, localRect->fTop,
                            localRect->fRight, localRect->fBottom,
                            vsize);
index 7bd3f5d..fae79c8 100644 (file)
@@ -73,25 +73,26 @@ void get_vertex_bounds(const void* vertices,
 }
 }
 
-void GrInOrderDrawBuffer::onDrawRect(const GrRect& rect,
-                                     const SkMatrix* matrix,
-                                     const GrRect* localRect,
-                                     const SkMatrix* localMatrix) {
-    GrDrawState::AutoColorRestore acr;
 
-    GrDrawState* drawState = this->drawState();
+namespace {
 
-    GrColor color = drawState->getColor();
-    GrVertexAttribArray<3> attribs;
+extern const GrVertexAttrib kRectPosColorUVAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0,               kPosition_GrVertexAttribBinding},
+    {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType,  sizeof(GrPoint)+sizeof(GrColor), 
+                                                  kLocalCoord_GrVertexAttribBinding},
+};
 
-    // set position attrib
-    static const GrVertexAttrib kPosAttrib =
-        {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
-    attribs.push_back(kPosAttrib);
+extern const GrVertexAttrib kRectPosUVAttribs[] = {
+    {kVec2f_GrVertexAttribType,  0,              kPosition_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding},
+};
 
-    size_t currentOffset = sizeof(GrPoint);
-    int colorOffset = -1;
-    int localOffset = -1;
+static void set_vertex_attributes(GrDrawState* drawState,
+                                  bool hasColor, bool hasUVs,
+                                  int* colorOffset, int* localOffset) {
+    *colorOffset = -1;
+    *localOffset = -1;
 
     // Using per-vertex colors allows batching across colors. (A lot of rects in a row differing
     // only in color is a common occurrence in tables). However, having per-vertex colors disables
@@ -99,28 +100,47 @@ void GrInOrderDrawBuffer::onDrawRect(const GrRect& rect,
     // optimizations help determine whether coverage and color can be blended correctly when
     // dual-source blending isn't available. This comes into play when there is coverage. If colors
     // were a stage it could take a hint that every vertex's color will be opaque.
-    if (this->caps()->dualSourceBlendingSupport() || drawState->hasSolidCoverage()) {
-        colorOffset = currentOffset;
-        GrVertexAttrib colorAttrib =
-            {kVec4ub_GrVertexAttribType, currentOffset, kColor_GrVertexAttribBinding};
-        attribs.push_back(colorAttrib);
-        currentOffset += sizeof(GrColor);
+    if (hasColor && hasUVs) {
+        *colorOffset = sizeof(GrPoint);
+        *localOffset = sizeof(GrPoint) + sizeof(GrColor);
+        drawState->setVertexAttribs<kRectPosColorUVAttribs>(3);
+    } else if (hasColor) {
+        *colorOffset = sizeof(GrPoint);
+        drawState->setVertexAttribs<kRectPosColorUVAttribs>(2);
+    } else if (hasUVs) {
+        *localOffset = sizeof(GrPoint);
+        drawState->setVertexAttribs<kRectPosUVAttribs>(2);
+    } else {
+        drawState->setVertexAttribs<kRectPosUVAttribs>(1);
+    }
+}
+
+};
+
+void GrInOrderDrawBuffer::onDrawRect(const GrRect& rect,
+                                     const SkMatrix* matrix,
+                                     const GrRect* localRect,
+                                     const SkMatrix* localMatrix) {
+    GrDrawState::AutoColorRestore acr;
+
+    GrDrawState* drawState = this->drawState();
+
+    GrColor color = drawState->getColor();
+
+    int colorOffset, localOffset;
+    set_vertex_attributes(drawState,
+                   this->caps()->dualSourceBlendingSupport() || drawState->hasSolidCoverage(),
+                   NULL != localRect,
+                   &colorOffset, &localOffset);
+    if (colorOffset >= 0) {
         // We set the draw state's color to white here. This is done so that any batching performed
         // in our subclass's onDraw() won't get a false from GrDrawState::op== due to a color
         // mismatch. TODO: Once vertex layout is owned by GrDrawState it should skip comparing the
-        // constant color in its op== when the kColor layout bit is set and then we can remove this.
+        // constant color in its op== when the kColor layout bit is set and then we can remove 
+        // this.
         acr.set(drawState, 0xFFFFFFFF);
     }
 
-    if (NULL != localRect) {
-        localOffset = currentOffset;
-        GrVertexAttrib localCoordAttrib =
-            {kVec2f_GrVertexAttribType, currentOffset, kLocalCoord_GrVertexAttribBinding};
-        attribs.push_back(localCoordAttrib);
-        currentOffset += sizeof(GrPoint);
-    }
-
-    drawState->setVertexAttribs(attribs.begin(), attribs.count());
     AutoReleaseGeometry geo(this, 4, 0);
     if (!geo.succeeded()) {
         GrPrintf("Failed to get space for vertices!\n");
@@ -144,7 +164,6 @@ void GrInOrderDrawBuffer::onDrawRect(const GrRect& rect,
     }
 
     size_t vsize = drawState->getVertexSize();
-    GrAssert(vsize == currentOffset);
 
     geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
     combinedMatrix.mapPointsWithStride(geo.positions(), vsize, 4);
index c698692..f217262 100644 (file)
@@ -306,6 +306,16 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, co
     return true;
 }
 
+namespace {
+
+// position + edge
+extern const GrVertexAttrib gCircleVertexAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
+    {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
+};
+
+};
+
 void GrOvalRenderer::drawCircle(GrDrawTarget* target,
                                 const GrPaint& paint,
                                 const GrRect& circle,
@@ -324,12 +334,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
         return;
     }
 
-    // position + edge
-    static const GrVertexAttrib kVertexAttribs[] = {
-        {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
-        {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
-    };
-    drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
+    drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs));
     GrAssert(sizeof(CircleVertex) == drawState->getVertexSize());
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
@@ -406,6 +411,17 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
     target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
 }
 
+namespace {
+
+// position + edge
+extern const GrVertexAttrib gEllipseVertexAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, sizeof(GrPoint),   kEffect_GrVertexAttribBinding},
+    {kVec4f_GrVertexAttribType, 2*sizeof(GrPoint), kEffect_GrVertexAttribBinding}
+};
+
+};
+
 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
                                  const GrPaint& paint,
                                  const GrRect& ellipse,
@@ -445,13 +461,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
         return false;
     }
 
-    // position + edge
-    static const GrVertexAttrib kVertexAttribs[] = {
-        {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
-        {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding},
-        {kVec4f_GrVertexAttribType, 2*sizeof(GrPoint), kEffect_GrVertexAttribBinding}
-    };
-    drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
+    drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs));
     GrAssert(sizeof(EllipseVertex) == drawState->getVertexSize());
 
     GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
index 58b3e92..804165b 100644 (file)
@@ -110,6 +110,16 @@ void GrTextContext::flush() {
     this->flushGlyphs();
 }
 
+namespace {
+
+// position + texture coord
+extern const GrVertexAttrib gTextVertexAttribs[] = {
+    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
+    {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
+};
+
+};
+
 void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
                                     GrFixed vx, GrFixed vy,
                                     GrFontScaler* scaler) {
@@ -192,19 +202,13 @@ HAS_ATLAS:
     }
 
     if (NULL == fVertices) {
-        // position + texture coord
-        static const GrVertexAttrib kVertexAttribs[] = {
-            {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-            {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
-        };
-
        // If we need to reserve vertices allow the draw target to suggest
         // a number of verts to reserve and whether to perform a flush.
         fMaxVertices = kMinRequestedVerts;
         bool flush = false;
         fDrawTarget = fContext->getTextTarget(fPaint);
         if (NULL != fDrawTarget) {
-            fDrawTarget->drawState()->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
+            fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_ARRAY_COUNT(gTextVertexAttribs));
             flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
         }
         if (flush) {
@@ -212,7 +216,7 @@ HAS_ATLAS:
             fContext->flush();
             // flushGlyphs() will reset fDrawTarget to NULL.
             fDrawTarget = fContext->getTextTarget(fPaint);
-            fDrawTarget->drawState()->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
+            fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_ARRAY_COUNT(gTextVertexAttribs));
         }
         fMaxVertices = kDefaultRequestedVerts;
         // ignore return, no point in flushing again.