diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrContext.cpp | 27 | ||||
-rw-r--r-- | src/gpu/GrDrawState.cpp | 357 | ||||
-rw-r--r-- | src/gpu/GrDrawState.h | 70 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 25 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 33 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 27 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 5 | ||||
-rw-r--r-- | src/gpu/GrSWMaskHelper.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrTextContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 43 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 46 |
12 files changed, 213 insertions, 429 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 70db25601f..8ca74c3d2d 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -312,7 +312,7 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering); drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params); - static const GrVertexLayout layout = GrDrawState::StageTexCoordVertexLayoutBit(0,0); + static const GrVertexLayout layout = GrDrawState::StageTexCoordVertexLayoutBit(0); drawState->setVertexLayout(layout); GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0); @@ -853,12 +853,7 @@ void GrContext::drawRectToRect(const GrPaint& paint, #else GrDrawState::AutoStageDisable atr(fDrawState); - const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; - const SkMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; - srcRects[0] = &srcRect; - srcMatrices[0] = srcMatrix; - - target->drawRect(dstRect, dstMatrix, srcRects, srcMatrices); + target->drawRect(dstRect, dstMatrix, &srcRect, srcMatrix, 0); #endif } @@ -879,7 +874,7 @@ void GrContext::drawVertices(const GrPaint& paint, GrVertexLayout layout = 0; if (NULL != texCoords) { - layout |= GrDrawState::StageTexCoordVertexLayoutBit(0, 0); + layout |= GrDrawState::StageTexCoordVertexLayoutBit(0); } if (NULL != colors) { layout |= GrDrawState::kColor_VertexLayoutBit; @@ -892,20 +887,20 @@ void GrContext::drawVertices(const GrPaint& paint, GrPrintf("Failed to get space for vertices!\n"); return; } - int texOffsets[GrDrawState::kMaxTexCoords]; + int texOffset; int colorOffset; - GrDrawState::VertexSizeAndOffsetsByIdx(layout, - texOffsets, - &colorOffset, - NULL, - NULL); + GrDrawState::VertexSizeAndOffsets(layout, + &texOffset, + &colorOffset, + NULL, + NULL); void* curVertex = geo.vertices(); for (int i = 0; i < vertexCount; ++i) { *((GrPoint*)curVertex) = positions[i]; - if (texOffsets[0] > 0) { - *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; + if (texOffset > 0) { + *(GrPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; } if (colorOffset > 0) { *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index f2c69778de..3ff8a97f55 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -49,100 +49,25 @@ void GrDrawState::setFromPaint(const GrPaint& paint) { namespace { /** - * This function generates some masks that we like to have known at compile - * time. When the number of stages or tex coords is bumped or the way bits - * are defined in GrDrawState.h changes this function should be rerun to - * generate the new masks. (We attempted to force the compiler to generate the - * masks using recursive templates but always wound up with static initializers - * under gcc, even if they were just a series of immediate->memory moves.) + * This function generates a mask that we like to have known at compile + * time. When the number of stages is bumped or the way bits are defined in + * GrDrawState.h changes this function should be rerun to generate the new mask. + * (We attempted to force the compiler to generate the mask using recursive + * templates but always wound up with static initializers under gcc, even if + * they were just a series of immediate->memory moves.) * */ -void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks, - GrVertexLayout* texCoordMasks) { +void gen_tex_coord_mask(GrVertexLayout* texCoordMask) { + *texCoordMask = 0; for (int s = 0; s < GrDrawState::kNumStages; ++s) { - stageTexCoordMasks[s] = 0; - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - stageTexCoordMasks[s] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t); - } - } - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - texCoordMasks[t] = 0; - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - texCoordMasks[t] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t); - } + *texCoordMask |= GrDrawState::StageTexCoordVertexLayoutBit(s); } } -/** - * Uncomment and run the gen_globals function to generate - * the code that declares the global masks. - * - * #if 0'ed out to avoid unused function warning. - */ - -#if 0 -void gen_globals() { - GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages]; - GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords]; - gen_mask_arrays(stageTexCoordMasks, texCoordMasks); +const GrVertexLayout kTexCoordMask = (1 << GrDrawState::kNumStages)-1; - GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n"); - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - GrPrintf(" 0x%x,\n", stageTexCoordMasks[s]); - } - GrPrintf("};\n"); - GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n"); - GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n"); - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - GrPrintf(" 0x%x,\n", texCoordMasks[t]); - } - GrPrintf("};\n"); - GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n"); -} -#endif - -/* These values were generated by the above function */ - -const GrVertexLayout gStageTexCoordMasks[] = { - 0x108421, - 0x210842, - 0x421084, - 0x842108, - 0x1084210, -}; -GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks)); - -const GrVertexLayout gTexCoordMasks[] = { - 0x1f, - 0x3e0, - 0x7c00, - 0xf8000, - 0x1f00000, -}; -GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks)); - -#ifdef SK_DEBUG -bool check_layout(GrVertexLayout layout) { - // can only have 1 or 0 bits set for each stage. - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - int stageBits = layout & gStageTexCoordMasks[s]; - if (stageBits && !GrIsPow2(stageBits)) { - return false; - } - } - return true; -} -#endif - -int num_tex_coords(GrVertexLayout layout) { - int cnt = 0; - // figure out how many tex coordinates are present - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - if (gTexCoordMasks[t] & layout) { - ++cnt; - } - } - return cnt; +inline int num_tex_coords(GrVertexLayout layout) { + return (kTexCoordMask & layout) ? 1 : 0; } } //unnamed namespace @@ -150,8 +75,6 @@ int num_tex_coords(GrVertexLayout layout) { static const size_t kVec2Size = sizeof(GrPoint); size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - size_t size = kVec2Size; // position size += num_tex_coords(vertexLayout) * kVec2Size; if (vertexLayout & kColor_VertexLayoutBit) { @@ -174,38 +97,20 @@ size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) { * * Order of vertex components: * Position - * Tex Coord 0 - * ... - * Tex Coord GrDrawState::kMaxTexCoords-1 + * Tex Coord * Color * Coverage */ int GrDrawState::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - if (!StageUsesTexCoords(vertexLayout, stageIdx)) { return 0; } - int tcIdx = VertexTexCoordsForStage(stageIdx, vertexLayout); - if (tcIdx >= 0) { - int offset = kVec2Size; // position - // figure out how many tex coordinates are present and precede this one. - for (int t = 0; t < tcIdx; ++t) { - if (gTexCoordMasks[t] & vertexLayout) { - offset += kVec2Size; - } - } - return offset; - } - - return -1; + return kVec2Size; } int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - if (vertexLayout & kColor_VertexLayoutBit) { return kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos } @@ -213,8 +118,6 @@ int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) { } int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - if (vertexLayout & kCoverage_VertexLayoutBit) { int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1); if (vertexLayout & kColor_VertexLayoutBit) { @@ -226,8 +129,6 @@ int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) { } int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - // edge pts are after the pos, tex coords, and color if (vertexLayout & kEdge_VertexLayoutBit) { int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos @@ -242,26 +143,22 @@ int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) { return -1; } -int GrDrawState::VertexSizeAndOffsetsByIdx( +int GrDrawState::VertexSizeAndOffsets( GrVertexLayout vertexLayout, - int texCoordOffsetsByIdx[kMaxTexCoords], + int* texCoordOffset, int* colorOffset, int* coverageOffset, int* edgeOffset) { - GrAssert(check_layout(vertexLayout)); - int size = kVec2Size; // position - for (int t = 0; t < kMaxTexCoords; ++t) { - if (gTexCoordMasks[t] & vertexLayout) { - if (NULL != texCoordOffsetsByIdx) { - texCoordOffsetsByIdx[t] = size; - } - size += kVec2Size; - } else { - if (NULL != texCoordOffsetsByIdx) { - texCoordOffsetsByIdx[t] = -1; - } + if (kTexCoordMask & vertexLayout) { + if (NULL != texCoordOffset) { + *texCoordOffset = size; + } + size += kVec2Size; + } else { + if (NULL != texCoordOffset) { + *texCoordOffset = -1; } } if (kColor_VertexLayoutBit & vertexLayout) { @@ -303,21 +200,17 @@ int GrDrawState::VertexSizeAndOffsetsByStage( int* colorOffset, int* coverageOffset, int* edgeOffset) { - GrAssert(check_layout(vertexLayout)); - - int texCoordOffsetsByIdx[kMaxTexCoords]; - int size = VertexSizeAndOffsetsByIdx(vertexLayout, - (NULL == texCoordOffsetsByStage) ? - NULL : - texCoordOffsetsByIdx, - colorOffset, - coverageOffset, - edgeOffset); + + int texCoordOffset; + int size = VertexSizeAndOffsets(vertexLayout, + &texCoordOffset, + colorOffset, + coverageOffset, + edgeOffset); if (NULL != texCoordOffsetsByStage) { for (int s = 0; s < GrDrawState::kNumStages; ++s) { - int tcIdx = VertexTexCoordsForStage(s, vertexLayout); - texCoordOffsetsByStage[s] = - tcIdx < 0 ? 0 : texCoordOffsetsByIdx[tcIdx]; + texCoordOffsetsByStage[s] = StageUsesTexCoords(vertexLayout, s) ? + texCoordOffset : 0; } } return size; @@ -325,131 +218,93 @@ int GrDrawState::VertexSizeAndOffsetsByStage( //////////////////////////////////////////////////////////////////////////////// -bool GrDrawState::VertexUsesTexCoordIdx(int coordIndex, - GrVertexLayout vertexLayout) { - GrAssert(coordIndex < kMaxTexCoords); - GrAssert(check_layout(vertexLayout)); - return !!(gTexCoordMasks[coordIndex] & vertexLayout); -} - -int GrDrawState::VertexTexCoordsForStage(int stageIdx, - GrVertexLayout vertexLayout) { - GrAssert(stageIdx < GrDrawState::kNumStages); - GrAssert(check_layout(vertexLayout)); - int bit = vertexLayout & gStageTexCoordMasks[stageIdx]; - if (bit) { - // figure out which set of texture coordates is used - // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ... - // and start at bit 0. - GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t)); - return (32 - SkCLZ(bit) - 1) / GrDrawState::kNumStages; - } - return -1; +bool GrDrawState::VertexUsesTexCoords(GrVertexLayout vertexLayout) { + return SkToBool(kTexCoordMask & vertexLayout); } //////////////////////////////////////////////////////////////////////////////// void GrDrawState::VertexLayoutUnitTest() { - // Ensure that our globals mask arrays are correct - GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages]; - GrVertexLayout texCoordMasks[kMaxTexCoords]; - gen_mask_arrays(stageTexCoordMasks, texCoordMasks); - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]); - } - for (int t = 0; t < kMaxTexCoords; ++t) { - GrAssert(texCoordMasks[t] == gTexCoordMasks[t]); - } + // Ensure that our tex coord mask is correct + GrVertexLayout texCoordMask; + gen_tex_coord_mask(&texCoordMask); + GrAssert(texCoordMask == kTexCoordMask); // not necessarily exhaustive static bool run; if (!run) { run = true; + GrVertexLayout tcMask = 0; + GrAssert(!VertexUsesTexCoords(0)); for (int s = 0; s < GrDrawState::kNumStages; ++s) { + tcMask |= StageTexCoordVertexLayoutBit(s); + GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); + GrAssert(VertexUsesTexCoords(tcMask)); + GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask)); + GrAssert(StageUsesTexCoords(tcMask, s)); + for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) { + GrAssert(!StageUsesTexCoords(tcMask, s2)); - GrVertexLayout stageMask = 0; - for (int t = 0; t < kMaxTexCoords; ++t) { - stageMask |= StageTexCoordVertexLayoutBit(s,t); - } - GrAssert(1 == kMaxTexCoords || - !check_layout(stageMask)); - GrAssert(gStageTexCoordMasks[s] == stageMask); - GrAssert(!check_layout(stageMask)); - } - for (int t = 0; t < kMaxTexCoords; ++t) { - GrVertexLayout tcMask = 0; - GrAssert(!VertexUsesTexCoordIdx(t, 0)); - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - tcMask |= StageTexCoordVertexLayoutBit(s,t); - GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); - GrAssert(VertexUsesTexCoordIdx(t, tcMask)); - GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask)); - GrAssert(t == VertexTexCoordsForStage(s, tcMask)); - for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) { - GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask)); - - #if GR_DEBUG - GrVertexLayout posAsTex = tcMask; - #endif - GrAssert(0 == VertexStageCoordOffset(s2, posAsTex)); - GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex)); - GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex)); - GrAssert(-1 == VertexEdgeOffset(posAsTex)); - } - GrAssert(-1 == VertexEdgeOffset(tcMask)); - GrAssert(-1 == VertexColorOffset(tcMask)); - GrAssert(-1 == VertexCoverageOffset(tcMask)); - #if GR_DEBUG - GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit; - #endif - GrAssert(-1 == VertexCoverageOffset(withColor)); - GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor)); - GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor)); - #if GR_DEBUG - GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit; - #endif - GrAssert(-1 == VertexColorOffset(withEdge)); - GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge)); - GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge)); - #if GR_DEBUG - GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit; - #endif - GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge)); - GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge)); - GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge)); #if GR_DEBUG - GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit; + GrVertexLayout posAsTex = tcMask; #endif - GrAssert(-1 == VertexColorOffset(withCoverage)); - GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage)); - GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage)); - #if GR_DEBUG - GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit | - kColor_VertexLayoutBit; - #endif - GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor)); - GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor)); - GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor)); - } - GrAssert(gTexCoordMasks[t] == tcMask); - GrAssert(check_layout(tcMask)); - - int stageOffsets[GrDrawState::kNumStages]; - int colorOffset; - int edgeOffset; - int coverageOffset; - int size; - size = VertexSizeAndOffsetsByStage(tcMask, - stageOffsets, &colorOffset, - &coverageOffset, &edgeOffset); - GrAssert(2*sizeof(GrPoint) == size); - GrAssert(-1 == colorOffset); - GrAssert(-1 == coverageOffset); - GrAssert(-1 == edgeOffset); - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - GrAssert(sizeof(GrPoint) == stageOffsets[s]); - GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); + GrAssert(0 == VertexStageCoordOffset(s2, posAsTex)); + GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex)); + GrAssert(!StageUsesTexCoords(posAsTex, s2)); + GrAssert(-1 == VertexEdgeOffset(posAsTex)); } + GrAssert(-1 == VertexEdgeOffset(tcMask)); + GrAssert(-1 == VertexColorOffset(tcMask)); + GrAssert(-1 == VertexCoverageOffset(tcMask)); + #if GR_DEBUG + GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit; + #endif + GrAssert(-1 == VertexCoverageOffset(withColor)); + GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor)); + GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor)); + #if GR_DEBUG + GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit; + #endif + GrAssert(-1 == VertexColorOffset(withEdge)); + GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge)); + GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge)); + #if GR_DEBUG + GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit; + #endif + GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge)); + GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge)); + GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge)); + #if GR_DEBUG + GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit; + #endif + GrAssert(-1 == VertexColorOffset(withCoverage)); + GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage)); + GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage)); + #if GR_DEBUG + GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit | + kColor_VertexLayoutBit; + #endif + GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor)); + GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor)); + GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor)); + } + GrAssert(kTexCoordMask == tcMask); + + int stageOffsets[GrDrawState::kNumStages]; + int colorOffset; + int edgeOffset; + int coverageOffset; + int size; + size = VertexSizeAndOffsetsByStage(tcMask, + stageOffsets, &colorOffset, + &coverageOffset, &edgeOffset); + GrAssert(2*sizeof(GrPoint) == size); + GrAssert(-1 == colorOffset); + GrAssert(-1 == coverageOffset); + GrAssert(-1 == edgeOffset); + for (int s = 0; s < GrDrawState::kNumStages; ++s) { + GrAssert(sizeof(GrPoint) == stageOffsets[s]); + GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); } } } @@ -457,7 +312,7 @@ void GrDrawState::VertexLayoutUnitTest() { //////////////////////////////////////////////////////////////////////////////// bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) { - return SkToBool(layout & gStageTexCoordMasks[stageIdx]); + return SkToBool(layout & StageTexCoordVertexLayoutBit(stageIdx)); } bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const { diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 1124ebb368..ad31e0d5fc 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -55,7 +55,6 @@ public: */ enum { kNumStages = 5, - kMaxTexCoords = kNumStages }; GrDrawState() { @@ -114,45 +113,35 @@ public: /** * The format of vertices is represented as a bitfield of flags. * Flags that indicate the layout of vertex data. Vertices always contain - * positions and may also contain up to GrDrawState::kMaxTexCoords sets - * of 2D texture coordinates, per-vertex colors, and per-vertex coverage. - * Each stage can - * use any of the texture coordinates as its input texture coordinates or it - * may use the positions as texture coordinates. + * positions and may also contain texture coordinates, per-vertex colors, + * and per-vertex coverage. Each stage can use any texture coordinates as + * its input texture coordinates or it may use the positions as texture + * coordinates. * * If no texture coordinates are specified for a stage then the stage is * disabled. * - * Only one type of texture coord can be specified per stage. For - * example StageTexCoordVertexLayoutBit(0, 2) and - * StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified. - * - * The order in memory is always (position, texture coord 0, ..., color, - * coverage) with any unused fields omitted. Note that this means that if - * only texture coordinates 1 is referenced then there is no texture - * coordinates 0 and the order would be (position, texture coordinate 1 - * [, color][, coverage]). + * The order in memory is always (position, texture coords, color, coverage) + * with any unused fields omitted. */ /** * Generates a bit indicating that a texture stage uses texture coordinates * * @param stageIdx the stage that will use texture coordinates. - * @param texCoordIdx the index of the texture coordinates to use * * @return the bit to add to a GrVertexLayout bitfield. */ - static int StageTexCoordVertexLayoutBit(int stageIdx, int texCoordIdx) { + static int StageTexCoordVertexLayoutBit(int stageIdx) { GrAssert(stageIdx < kNumStages); - GrAssert(texCoordIdx < kMaxTexCoords); - return 1 << (stageIdx + (texCoordIdx * kNumStages)); + return (1 << stageIdx); } static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx); private: // non-stage bits start at this index. - static const int STAGE_BIT_CNT = kNumStages * kMaxTexCoords; + static const int STAGE_BIT_CNT = kNumStages; public: /** @@ -200,24 +189,9 @@ public: static size_t VertexSize(GrVertexLayout vertexLayout); /** - * Helper function for determining the index of texture coordinates that - * is input for a texture stage. Note that a stage may instead use positions - * as texture coordinates, in which case the result of the function is - * indistinguishable from the case when the stage is disabled. - * - * @param stageIdx the stage to query - * @param vertexLayout layout to query - * - * @return the texture coordinate index or -1 if the stage doesn't use - * separate (non-position) texture coordinates. - */ - static int VertexTexCoordsForStage(int stageIdx, GrVertexLayout vertexLayout); - - /** * Helper function to compute the offset of texture coordinates in a vertex - * @return offset of texture coordinates in vertex layout or -1 if the - * layout has no texture coordinates. Will be 0 if positions are - * used as texture coordinates for the stage. + * @return offset of texture coordinates in vertex layout or 0 if positions + * are used as texture coordinates for the stage. */ static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout); @@ -244,27 +218,23 @@ public: /** * Helper function to determine if vertex layout contains explicit texture - * coordinates of some index. + * coordinates. * - * @param coordIndex the tex coord index to query * @param vertexLayout layout to query * - * @return true if vertex specifies texture coordinates for the index, - * false otherwise. + * @return true if vertex specifies texture coordinates, + * false otherwise. */ - static bool VertexUsesTexCoordIdx(int coordIndex, - GrVertexLayout vertexLayout); + static bool VertexUsesTexCoords(GrVertexLayout vertexLayout); /** * Helper function to compute the size of each vertex and the offsets of - * texture coordinates and color. Determines tex coord offsets by tex coord - * index rather than by stage. (Each stage can be mapped to any t.c. index - * by StageTexCoordVertexLayoutBit.) + * texture coordinates and color. * * @param vertexLayout the layout to query - * @param texCoordOffsetsByIdx after return it is the offset of each + * @param texCoordOffset after return it is the offset of the * tex coord index in the vertex or -1 if - * index isn't used. (optional) + * tex coords aren't used. (optional) * @param colorOffset after return it is the offset of the * color field in each vertex, or -1 if * there aren't per-vertex colors. (optional) @@ -278,8 +248,8 @@ public: * (optional) * @return size of a single vertex */ - static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout, - int texCoordOffsetsByIdx[kMaxTexCoords], + static int VertexSizeAndOffsets(GrVertexLayout vertexLayout, + int *texCoordOffset, int *colorOffset, int *coverageOffset, int* edgeOffset); diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index c00a5ce509..7fc2c13aa7 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -523,20 +523,15 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type, void GrDrawTarget::drawRect(const GrRect& rect, const SkMatrix* matrix, - const GrRect* srcRects[], - const SkMatrix* srcMatrices[]) { + const GrRect* srcRect, + const SkMatrix* srcMatrix, + int stage) { GrVertexLayout layout = 0; uint32_t explicitCoordMask = 0; - if (NULL != srcRects) { - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - int numTC = 0; - if (NULL != srcRects[s]) { - layout |= GrDrawState::StageTexCoordVertexLayoutBit(s, numTC); - explicitCoordMask |= (1 << s); - ++numTC; - } - } + if (NULL != srcRect) { + layout |= GrDrawState::StageTexCoordVertexLayoutBit(stage); + explicitCoordMask = (1 << stage); } GrDrawState::AutoViewMatrixRestore avmr; @@ -560,11 +555,11 @@ void GrDrawTarget::drawRect(const GrRect& rect, GrAssert(0 != stageOffsets[i]); GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + stageOffsets[i]); - coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, - srcRects[i]->fRight, srcRects[i]->fBottom, + coords->setRectFan(srcRect->fLeft, srcRect->fTop, + srcRect->fRight, srcRect->fBottom, vsize); - if (NULL != srcMatrices && NULL != srcMatrices[i]) { - srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); + if (NULL != srcMatrix) { + srcMatrix->mapPointsWithStride(coords, vsize, 4); } } else { GrAssert(0 == stageOffsets[i]); diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 1f4189145b..aad819c92b 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -385,39 +385,40 @@ public: * have changed. They should be reestablished before the next drawIndexed * or drawNonIndexed. This cannot be called between reserving and releasing * geometry. - * + * * A subclass may override this to perform more optimal rect rendering. Its * draws should be funneled through one of the public GrDrawTarget draw methods * (e.g. drawNonIndexed, drawIndexedInstances, ...). The base class draws a two * triangle fan using drawNonIndexed from reserved vertex space. - * + * * @param rect the rect to draw * @param matrix optional matrix applied to rect (before viewMatrix) - * @param srcRects specifies rects for stages enabled by stageEnableMask. - * if stageEnableMask bit i is 1, srcRects is not NULL, - * and srcRects[i] is not NULL, then srcRects[i] will be - * used as coordinates for stage i. Otherwise, if stage i - * is enabled then rect is used as the coordinates. - * @param srcMatrices optional matrices applied to srcRects. If - * srcRect[i] is non-NULL and srcMatrices[i] is - * non-NULL then srcRect[i] will be transformed by - * srcMatrix[i]. srcMatrices can be NULL when no - * srcMatrices are desired. + * @param srcRects specifies rect for explicit texture coordinates. + * if srcRect is non-NULL then that rect will be used + * as the coordinates for the given stage. + * @param srcMatrix optional matrix applied to srcRect. If + * srcRect is non-NULL and srcMatrix is non-NULL + * then srcRect will be transformed by srcMatrix. + * srcMatrix can be NULL when no srcMatrix is desired. + * @param stage the stage to be given explicit texture coordinates. + * Ignored if srcRect is NULL. */ virtual void drawRect(const GrRect& rect, const SkMatrix* matrix, - const GrRect* srcRects[], - const SkMatrix* srcMatrices[]); + const GrRect* srcRect, + const SkMatrix* srcMatrix, + int stage); + /** * Helper for drawRect when the caller doesn't need separate src rects or * matrices. */ void drawSimpleRect(const GrRect& rect, const SkMatrix* matrix = NULL) { - drawRect(rect, matrix, NULL, NULL); + drawRect(rect, matrix, NULL, NULL, 0); } void drawSimpleRect(const GrIRect& irect, const SkMatrix* matrix = NULL) { SkRect rect = SkRect::MakeFromIRect(irect); - this->drawRect(rect, matrix, NULL, NULL); + this->drawRect(rect, matrix, NULL, NULL, 0); } /** diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 991d858174..0ebf81055f 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -72,8 +72,9 @@ void get_vertex_bounds(const void* vertices, void GrInOrderDrawBuffer::drawRect(const GrRect& rect, const SkMatrix* matrix, - const GrRect* srcRects[], - const SkMatrix* srcMatrices[]) { + const GrRect* srcRect, + const SkMatrix* srcMatrix, + int stage) { GrVertexLayout layout = 0; GrDrawState::AutoColorRestore acr; @@ -96,15 +97,9 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, } uint32_t explicitCoordMask = 0; - if (NULL != srcRects) { - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - int numTC = 0; - if (NULL != srcRects[s]) { - layout |= GrDrawState::StageTexCoordVertexLayoutBit(s, numTC); - ++numTC; - explicitCoordMask |= (1 << s); - } - } + if (NULL != srcRect) { + layout |= GrDrawState::StageTexCoordVertexLayoutBit(stage); + explicitCoordMask = (1 << stage); } this->drawState()->setVertexLayout(layout); @@ -122,7 +117,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, combinedMatrix.reset(); } combinedMatrix.postConcat(this->drawState()->getViewMatrix()); - // When the caller has provided an explicit source rects for a stage then we don't want to + // When the caller has provided an explicit source rect for a stage then we don't want to // modify that stage's matrix. Otherwise if the effect is generating its source rect from // the vertex positions then we have to account for the view matrix change. GrDrawState::AutoDeviceCoordDraw adcd(this->drawState(), explicitCoordMask); @@ -147,11 +142,11 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, GrAssert(0 != stageOffsets[i]); GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + stageOffsets[i]); - coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, - srcRects[i]->fRight, srcRects[i]->fBottom, + coords->setRectFan(srcRect->fLeft, srcRect->fTop, + srcRect->fRight, srcRect->fBottom, vsize); - if (NULL != srcMatrices && NULL != srcMatrices[i]) { - srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); + if (NULL != srcMatrix) { + srcMatrix->mapPointsWithStride(coords, vsize, 4); } } else { GrAssert(0 == stageOffsets[i]); diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index d9bdd1974b..b1aa9e9bf2 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -89,8 +89,9 @@ public: GrRenderTarget* renderTarget = NULL) SK_OVERRIDE; virtual void drawRect(const GrRect& rect, const SkMatrix* matrix, - const GrRect* srcRects[], - const SkMatrix* srcMatrices[]) SK_OVERRIDE; + const GrRect* srcRect, + const SkMatrix* srcMatrix, + int stage) SK_OVERRIDE; protected: virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE; diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index c05209137c..9682ec427f 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -203,13 +203,11 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture, GrRect maskRect = GrRect::MakeWH(w / texture->width(), h / texture->height()); - const GrRect* srcRects[GrDrawState::kNumStages] = { NULL }; - srcRects[kPathMaskStage] = &maskRect; GrRect dstRect = GrRect::MakeLTRB( SK_Scalar1 * rect.fLeft, SK_Scalar1 * rect.fTop, SK_Scalar1 * rect.fRight, SK_Scalar1 * rect.fBottom); - target->drawRect(dstRect, NULL, srcRects, NULL); + target->drawRect(dstRect, NULL, &maskRect, NULL, kPathMaskStage); drawState->disableStage(kPathMaskStage); } diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index 0a819da4c6..e599fc9500 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -93,7 +93,7 @@ GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint( fVertices = NULL; fMaxVertices = 0; - fVertexLayout = GrDrawState::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0); + fVertexLayout = GrDrawState::StageTexCoordVertexLayoutBit(kGlyphMaskStage); } GrTextContext::~GrTextContext() { diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index a5014a6a9d..8620c5cb4a 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -25,19 +25,14 @@ SK_DEFINE_INST_COUNT(GrGLProgram) SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, "Print the source code for all shaders generated."); +#define TEX_ATTR_NAME "aTexCoord" #define COL_ATTR_NAME "aColor" #define COV_ATTR_NAME "aCoverage" #define EDGE_ATTR_NAME "aEdge" namespace { -inline void tex_attr_name(int coordIdx, SkString* s) { - *s = "aTexCoord"; - s->appendS32(coordIdx); -} - inline const char* declared_color_output_name() { return "fsColorOut"; } inline const char* dual_source_output_name() { return "dualSourceOut"; } - } void GrGLProgram::BuildDesc(const GrDrawState& drawState, @@ -731,14 +726,10 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { } // add texture coordinates that are used to the list of vertex attr decls - SkString texCoordAttrs[GrDrawState::kMaxTexCoords]; - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - if (GrDrawState::VertexUsesTexCoordIdx(t, layout)) { - tex_attr_name(t, texCoordAttrs + t); - builder.fVSAttrs.push_back().set(kVec2f_GrSLType, - GrGLShaderVar::kAttribute_TypeModifier, - texCoordAttrs[t].c_str()); - } + if (GrDrawState::VertexUsesTexCoords(layout)) { + builder.fVSAttrs.push_back().set(kVec2f_GrSLType, + GrGLShaderVar::kAttribute_TypeModifier, + TEX_ATTR_NAME); } /////////////////////////////////////////////////////////////////////////// @@ -757,13 +748,11 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { const char* inCoords; // figure out what our input coords are - int tcIdx = GrDrawState::VertexTexCoordsForStage(s, layout); - if (tcIdx < 0) { + if (!GrDrawState::StageUsesTexCoords(layout, s)) { inCoords = builder.positionAttribute().c_str(); } else { // must have input tex coordinates if stage is enabled. - GrAssert(texCoordAttrs[tcIdx].size()); - inCoords = texCoordAttrs[tcIdx].c_str(); + inCoords = TEX_ATTR_NAME; } builder.setCurrentStage(s); @@ -853,15 +842,12 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { const char* inCoords; // figure out what our input coords are - int tcIdx = - GrDrawState::VertexTexCoordsForStage(s, layout); - if (tcIdx < 0) { + if (!GrDrawState::StageUsesTexCoords(layout, s)) { inCoords = builder.positionAttribute().c_str(); } else { // must have input tex coordinates if stage is // enabled. - GrAssert(texCoordAttrs[tcIdx].size()); - inCoords = texCoordAttrs[tcIdx].c_str(); + inCoords = TEX_ATTR_NAME; } // stages don't know how to deal with a scalar input. (Maybe they should. We @@ -945,7 +931,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { } if (!this->bindOutputsAttribsAndLinkProgram(builder, - texCoordAttrs, isColorDeclared, dualSourceOutputWritten)) { return false; @@ -959,7 +944,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { } bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder, - SkString texCoordAttrNames[], bool bindColorOut, bool bindDualSrcOut) { GL_CALL_RET(fProgramID, CreateProgram()); @@ -984,14 +968,7 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil GL_CALL(BindAttribLocation(fProgramID, PositionAttributeIdx(), builder.positionAttribute().c_str())); - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - if (texCoordAttrNames[t].size()) { - GL_CALL(BindAttribLocation(fProgramID, - TexCoordAttributeIdx(t), - texCoordAttrNames[t].c_str())); - } - } - + GL_CALL(BindAttribLocation(fProgramID, TexCoordAttributeIdx(), TEX_ATTR_NAME)); GL_CALL(BindAttribLocation(fProgramID, ColorAttributeIdx(), COL_ATTR_NAME)); GL_CALL(BindAttribLocation(fProgramID, CoverageAttributeIdx(), COV_ATTR_NAME)); GL_CALL(BindAttribLocation(fProgramID, EdgeAttributeIdx(), EDGE_ATTR_NAME)); diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index bdf5665903..2c3c973c7c 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -85,7 +85,7 @@ public: static int ColorAttributeIdx() { return 1; } static int CoverageAttributeIdx() { return 2; } static int EdgeAttributeIdx() { return 3; } - static int TexCoordAttributeIdx(int tcIdx) { return 4 + tcIdx; } + static int TexCoordAttributeIdx() { return 4; } /** * Some GL state that is relevant to programs is not stored per-program. In particular vertex @@ -227,7 +227,6 @@ private: // Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program bool bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder, - SkString texCoordAttrNames[GrDrawState::kMaxTexCoords], bool bindColorOut, bool bindDualSrcOut); diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 8ebe7a2d41..84e3b6dbfd 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -217,26 +217,26 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, int* startIndexOffset) { int newColorOffset; int newCoverageOffset; - int newTexCoordOffsets[GrDrawState::kMaxTexCoords]; + int newTexCoordOffset; int newEdgeOffset; GrVertexLayout currLayout = this->getDrawState().getVertexLayout(); - GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx(currLayout, - newTexCoordOffsets, - &newColorOffset, - &newCoverageOffset, - &newEdgeOffset); + GrGLsizei newStride = GrDrawState::VertexSizeAndOffsets(currLayout, + &newTexCoordOffset, + &newColorOffset, + &newCoverageOffset, + &newEdgeOffset); int oldColorOffset; int oldCoverageOffset; - int oldTexCoordOffsets[GrDrawState::kMaxTexCoords]; + int oldTexCoordOffset; int oldEdgeOffset; - GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout, - oldTexCoordOffsets, - &oldColorOffset, - &oldCoverageOffset, - &oldEdgeOffset); + GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsets(fHWGeometryState.fVertexLayout, + &oldTexCoordOffset, + &oldColorOffset, + &oldCoverageOffset, + &oldEdgeOffset); int extraVertexOffset; this->setBuffers(info.isIndexed(), &extraVertexOffset, startIndexOffset); @@ -254,19 +254,17 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, int* startIndexOffset) { fHWGeometryState.fVertexOffset = vertexOffset; } - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - if (newTexCoordOffsets[t] > 0) { - GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]); - int idx = GrGLProgram::TexCoordAttributeIdx(t); - if (oldTexCoordOffsets[t] <= 0) { - GL_CALL(EnableVertexAttribArray(idx)); - GL_CALL(VertexAttribPointer(idx, 2, GR_GL_FLOAT, false, newStride, texCoordOffset)); - } else if (allOffsetsChange || newTexCoordOffsets[t] != oldTexCoordOffsets[t]) { - GL_CALL(VertexAttribPointer(idx, 2, GR_GL_FLOAT, false, newStride, texCoordOffset)); - } - } else if (oldTexCoordOffsets[t] > 0) { - GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t))); + if (newTexCoordOffset > 0) { + GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffset); + int idx = GrGLProgram::TexCoordAttributeIdx(); + if (oldTexCoordOffset <= 0) { + GL_CALL(EnableVertexAttribArray(idx)); + GL_CALL(VertexAttribPointer(idx, 2, GR_GL_FLOAT, false, newStride, texCoordOffset)); + } else if (allOffsetsChange || newTexCoordOffset != oldTexCoordOffset) { + GL_CALL(VertexAttribPointer(idx, 2, GR_GL_FLOAT, false, newStride, texCoordOffset)); } + } else if (oldTexCoordOffset > 0) { + GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx())); } if (newColorOffset > 0) { |