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; }
int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout, int texCoordOffsetsByStage[kNumStages], int* colorOffset, int* coverageOffset, int* edgeOffset) { GrAssert(check_layout(vertexLayout)); int texCoordOffsetsByIdx[kMaxTexCoords]; int size = VertexSizeAndOffsetsByIdx(vertexLayout, (NULL == texCoordOffsetsByStage) ? NULL : texCoordOffsetsByIdx, colorOffset, coverageOffset, edgeOffset); if (NULL != texCoordOffsetsByStage) { for (int s = 0; s < kNumStages; ++s) { int tcIdx; if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) { texCoordOffsetsByStage[s] = 0; } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) { texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx]; } else { texCoordOffsetsByStage[s] = -1; } } } return size; }
// This method fills int the four vertices for drawing 'rect'. // matrix - is applied to each vertex // srcRects - provide the uvs for each vertex // srcMatrices - are applied to the corresponding 'srcRect' // color - vertex color (replicated in each vertex) // layout - specifies which uvs and/or color are present // vertices - storage for the resulting vertices // Note: the color parameter will only be used when kColor_VertexLayoutBit // is present in 'layout' void GrDrawTarget::SetRectVertices(const GrRect& rect, const SkMatrix* matrix, const GrRect* srcRects[], const SkMatrix* srcMatrices[], GrColor color, GrVertexLayout layout, void* vertices) { #if GR_DEBUG // check that the layout and srcRects agree for (int i = 0; i < GrDrawState::kNumStages; ++i) { if (VertexTexCoordsForStage(i, layout) >= 0) { GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]); } else { GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]); } } #endif int stageOffsets[GrDrawState::kNumStages], colorOffset; int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset, NULL, NULL); GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize); if (NULL != matrix) { matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4); } for (int i = 0; i < GrDrawState::kNumStages; ++i) { if (stageOffsets[i] > 0) { GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) + stageOffsets[i]); coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, srcRects[i]->fRight, srcRects[i]->fBottom, vsize); if (NULL != srcMatrices && NULL != srcMatrices[i]) { srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); } } } if (layout & kColor_VertexLayoutBit) { GrColor* vertCol = GrTCast<GrColor*>(GrTCast<intptr_t>(vertices) + colorOffset); for (int i = 0; i < 4; ++i) { *vertCol = color; vertCol = (GrColor*) ((intptr_t) vertCol + vsize); } } }
int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) { GrAssert(check_layout(vertexLayout)); if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) { return 0; } int tcIdx = VertexTexCoordsForStage(stage, 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; }
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)); } } } }
void GrDrawTarget::VertexLayoutUnitTest() { // not necessarily exhaustive static bool run; if (!run) { run = true; for (int s = 0; s < kNumStages; ++s) { GrAssert(!VertexUsesStage(s, 0)); GrAssert(-1 == VertexStageCoordOffset(s, 0)); GrVertexLayout stageMask = 0; for (int t = 0; t < kMaxTexCoords; ++t) { stageMask |= StageTexCoordVertexLayoutBit(s,t); } GrAssert(1 == kMaxTexCoords || !check_layout(stageMask)); GrAssert(stage_tex_coord_mask(s) == stageMask); stageMask |= StagePosAsTexCoordVertexLayoutBit(s); GrAssert(stage_mask(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 < kNumStages; ++s) { tcMask |= StageTexCoordVertexLayoutBit(s,t); GrAssert(VertexUsesStage(s, tcMask)); 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 < kNumStages; ++s2) { GrAssert(-1 == VertexStageCoordOffset(s2, tcMask)); GrAssert(!VertexUsesStage(s2, tcMask)); GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask)); #if GR_DEBUG GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2); #endif GrAssert(0 == VertexStageCoordOffset(s2, posAsTex)); GrAssert(VertexUsesStage(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(tex_coord_idx_mask(t) == tcMask); GrAssert(check_layout(tcMask)); int stageOffsets[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 < kNumStages; ++s) { GrAssert(VertexUsesStage(s, tcMask)); GrAssert(sizeof(GrPoint) == stageOffsets[s]); GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); } } } }