diff options
author | 2013-01-28 20:39:48 +0000 | |
---|---|---|
committer | 2013-01-28 20:39:48 +0000 | |
commit | cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9 (patch) | |
tree | 96dacf37b1f15203df306a2427d36deaa97dded2 /src/gpu/GrDrawTarget.cpp | |
parent | 4991b8f23482afc1494fd17647421ce68de53331 (diff) |
Move vertex layout definitions from GrDrawTarget to GrDrawState.
This is the first step in revising vertex layouts so that the currently
installed GrEffects determine the current vertex layout.
https://codereview.appspot.com/7235051/
git-svn-id: http://skia.googlecode.com/svn/trunk@7423 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/GrDrawTarget.cpp')
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 498 |
1 files changed, 8 insertions, 490 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index b0bac8ae77..ff8b9daf57 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -9,7 +9,6 @@ #include "GrDrawTarget.h" -#include "GrGpuVertex.h" #include "GrRenderTarget.h" #include "GrTexture.h" #include "GrVertexBuffer.h" @@ -18,432 +17,6 @@ SK_DEFINE_INST_COUNT(GrDrawTarget) -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 GrDrawTarget.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.) - * - */ -void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks, - GrVertexLayout* texCoordMasks) { - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - stageTexCoordMasks[s] = 0; - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - stageTexCoordMasks[s] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t); - } - } - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - texCoordMasks[t] = 0; - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - texCoordMasks[t] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t); - } - } -} - -/** - * 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); - - 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; -} - -} //unnamed namespace - -size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - - size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? - sizeof(GrGpuTextVertex) : - sizeof(GrPoint); - - size_t size = vecSize; // position - size += num_tex_coords(vertexLayout) * vecSize; - if (vertexLayout & kColor_VertexLayoutBit) { - size += sizeof(GrColor); - } - if (vertexLayout & kCoverage_VertexLayoutBit) { - size += sizeof(GrColor); - } - if (vertexLayout & kEdge_VertexLayoutBit) { - size += 4 * sizeof(SkScalar); - } - return size; -} - -//////////////////////////////////////////////////////////////////////////////// - -/** - * Functions for computing offsets of various components from the layout - * bitfield. - * - * Order of vertex components: - * Position - * Tex Coord 0 - * ... - * Tex Coord GrDrawState::kMaxTexCoords-1 - * Color - * Coverage - */ - -int GrDrawTarget::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - - if (!StageUsesTexCoords(vertexLayout, stageIdx)) { - return 0; - } - int tcIdx = VertexTexCoordsForStage(stageIdx, vertexLayout); - if (tcIdx >= 0) { - - int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? - sizeof(GrGpuTextVertex) : - sizeof(GrPoint); - int offset = vecSize; // 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 += vecSize; - } - } - return offset; - } - - return -1; -} - -int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - - if (vertexLayout & kColor_VertexLayoutBit) { - int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? - sizeof(GrGpuTextVertex) : - sizeof(GrPoint); - return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos - } - return -1; -} - -int GrDrawTarget::VertexCoverageOffset(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - - if (vertexLayout & kCoverage_VertexLayoutBit) { - int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? - sizeof(GrGpuTextVertex) : - sizeof(GrPoint); - - int offset = vecSize * (num_tex_coords(vertexLayout) + 1); - if (vertexLayout & kColor_VertexLayoutBit) { - offset += sizeof(GrColor); - } - return offset; - } - return -1; -} - -int GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) { - GrAssert(check_layout(vertexLayout)); - - // edge pts are after the pos, tex coords, and color - if (vertexLayout & kEdge_VertexLayoutBit) { - int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? - sizeof(GrGpuTextVertex) : - sizeof(GrPoint); - int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos - if (vertexLayout & kColor_VertexLayoutBit) { - offset += sizeof(GrColor); - } - if (vertexLayout & kCoverage_VertexLayoutBit) { - offset += sizeof(GrColor); - } - return offset; - } - return -1; -} - -int GrDrawTarget::VertexSizeAndOffsetsByIdx( - GrVertexLayout vertexLayout, - int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords], - int* colorOffset, - int* coverageOffset, - int* edgeOffset) { - GrAssert(check_layout(vertexLayout)); - - int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? - sizeof(GrGpuTextVertex) : - sizeof(GrPoint); - int size = vecSize; // position - - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - if (gTexCoordMasks[t] & vertexLayout) { - if (NULL != texCoordOffsetsByIdx) { - texCoordOffsetsByIdx[t] = size; - } - size += vecSize; - } else { - if (NULL != texCoordOffsetsByIdx) { - texCoordOffsetsByIdx[t] = -1; - } - } - } - if (kColor_VertexLayoutBit & vertexLayout) { - if (NULL != colorOffset) { - *colorOffset = size; - } - size += sizeof(GrColor); - } else { - if (NULL != colorOffset) { - *colorOffset = -1; - } - } - if (kCoverage_VertexLayoutBit & vertexLayout) { - if (NULL != coverageOffset) { - *coverageOffset = size; - } - size += sizeof(GrColor); - } else { - if (NULL != coverageOffset) { - *coverageOffset = -1; - } - } - if (kEdge_VertexLayoutBit & vertexLayout) { - if (NULL != edgeOffset) { - *edgeOffset = size; - } - size += 4 * sizeof(SkScalar); - } else { - if (NULL != edgeOffset) { - *edgeOffset = -1; - } - } - return size; -} - -int GrDrawTarget::VertexSizeAndOffsetsByStage( - GrVertexLayout vertexLayout, - int texCoordOffsetsByStage[GrDrawState::kNumStages], - int* colorOffset, - int* coverageOffset, - int* edgeOffset) { - GrAssert(check_layout(vertexLayout)); - - int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords]; - int size = VertexSizeAndOffsetsByIdx(vertexLayout, - (NULL == texCoordOffsetsByStage) ? - NULL : - texCoordOffsetsByIdx, - 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]; - } - } - return size; -} - -//////////////////////////////////////////////////////////////////////////////// - -bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex, - GrVertexLayout vertexLayout) { - GrAssert(coordIndex < GrDrawState::kMaxTexCoords); - GrAssert(check_layout(vertexLayout)); - return !!(gTexCoordMasks[coordIndex] & vertexLayout); -} - -int GrDrawTarget::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; -} - -//////////////////////////////////////////////////////////////////////////////// - -void GrDrawTarget::VertexLayoutUnitTest() { - // Ensure that our globals mask arrays are correct - GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages]; - GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords]; - gen_mask_arrays(stageTexCoordMasks, texCoordMasks); - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]); - } - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - GrAssert(texCoordMasks[t] == gTexCoordMasks[t]); - } - - // not necessarily exhaustive - static bool run; - if (!run) { - run = true; - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - - GrVertexLayout stageMask = 0; - for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { - stageMask |= StageTexCoordVertexLayoutBit(s,t); - } - GrAssert(1 == GrDrawState::kMaxTexCoords || - !check_layout(stageMask)); - GrAssert(gStageTexCoordMasks[s] == stageMask); - GrAssert(!check_layout(stageMask)); - } - for (int t = 0; t < GrDrawState::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; - #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)); - } - } - } -} - //////////////////////////////////////////////////////////////////////////////// #define DEBUG_INVAL_BUFFER 0xdeadcafe @@ -551,10 +124,6 @@ bool GrDrawTarget::reserveIndexSpace(int indexCount, } -bool GrDrawTarget::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) { - return SkToBool(layout & gStageTexCoordMasks[stageIdx]); -} - bool GrDrawTarget::reserveVertexAndIndexSpace(GrVertexLayout vertexLayout, int vertexCount, int indexCount, @@ -824,57 +393,6 @@ bool GrDrawTarget::canTweakAlphaForCoverage() const { this->getDrawState().isCoverageDrawing(); } -bool GrDrawTarget::srcAlphaWillBeOne(GrVertexLayout layout) const { - const GrDrawState& drawState = this->getDrawState(); - - uint32_t validComponentFlags; - GrColor color; - // Check if per-vertex or constant color may have partial alpha - if (layout & kColor_VertexLayoutBit) { - validComponentFlags = 0; - } else { - validComponentFlags = GrEffect::kAll_ValidComponentFlags; - color = drawState.getColor(); - } - - // Run through the color stages - int stageCnt = drawState.getFirstCoverageStage(); - for (int s = 0; s < stageCnt; ++s) { - const GrEffectRef* effect = drawState.getStage(s).getEffect(); - if (NULL != effect) { - (*effect)->getConstantColorComponents(&color, &validComponentFlags); - } - } - - // Check if the color filter could introduce an alpha. - // We could skip the above work when this is true, but it is rare and the right fix is to make - // the color filter a GrEffect and implement getConstantColorComponents() for it. - if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) { - validComponentFlags = 0; - } - - // Check whether coverage is treated as color. If so we run through the coverage computation. - if (drawState.isCoverageDrawing()) { - GrColor coverageColor = drawState.getCoverage(); - GrColor oldColor = color; - color = 0; - for (int c = 0; c < 4; ++c) { - if (validComponentFlags & (1 << c)) { - U8CPU a = (oldColor >> (c * 8)) & 0xff; - U8CPU b = (coverageColor >> (c * 8)) & 0xff; - color |= (SkMulDiv255Round(a, b) << (c * 8)); - } - } - for (int s = drawState.getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) { - const GrEffectRef* effect = drawState.getStage(s).getEffect(); - if (NULL != effect) { - (*effect)->getConstantColorComponents(&color, &validComponentFlags); - } - } - } - return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color); -} - namespace { GrVertexLayout default_blend_opts_vertex_layout() { GrVertexLayout layout = 0; @@ -912,14 +430,14 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, *dstCoeff = kOne_GrBlendCoeff; } - bool srcAIsOne = this->srcAlphaWillBeOne(layout); + bool srcAIsOne = drawState.srcAlphaWillBeOne(layout); bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); bool covIsZero = !drawState.isCoverageDrawing() && - !(layout & kCoverage_VertexLayoutBit) && + !(layout & GrDrawState::kCoverage_VertexLayoutBit) && 0 == drawState.getCoverage(); // When coeffs are (0,1) there is no reason to draw at all, unless // stenciling is enabled. Having color writes disabled is effectively @@ -937,8 +455,8 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, // edge aa or coverage stage bool hasCoverage = forceCoverage || 0xffffffff != drawState.getCoverage() || - (layout & kCoverage_VertexLayoutBit) || - (layout & kEdge_VertexLayoutBit); + (layout & GrDrawState::kCoverage_VertexLayoutBit) || + (layout & GrDrawState::kEdge_VertexLayoutBit); for (int s = drawState.getFirstCoverageStage(); !hasCoverage && s < GrDrawState::kNumStages; ++s) { @@ -1076,7 +594,7 @@ GrVertexLayout GrDrawTarget::GetRectVertexLayout(const GrRect* srcRects[]) { for (int i = 0; i < GrDrawState::kNumStages; ++i) { int numTC = 0; if (NULL != srcRects[i]) { - layout |= StageTexCoordVertexLayoutBit(i, numTC); + layout |= GrDrawState::StageTexCoordVertexLayoutBit(i, numTC); ++numTC; } } @@ -1111,8 +629,8 @@ void GrDrawTarget::SetRectVertices(const GrRect& rect, #endif int stageOffsets[GrDrawState::kNumStages], colorOffset; - int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, - &colorOffset, NULL, NULL); + int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets, + &colorOffset, NULL, NULL); GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, @@ -1134,7 +652,7 @@ void GrDrawTarget::SetRectVertices(const GrRect& rect, } } - if (layout & kColor_VertexLayoutBit) { + if (colorOffset >= 0) { GrColor* vertCol = GrTCast<GrColor*>(GrTCast<intptr_t>(vertices) + colorOffset); |