aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar jvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-28 20:39:48 +0000
committerGravatar jvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-28 20:39:48 +0000
commitcc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9 (patch)
tree96dacf37b1f15203df306a2427d36deaa97dded2 /src/gpu
parent4991b8f23482afc1494fd17647421ce68de53331 (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')
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp2
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.cpp4
-rw-r--r--src/gpu/GrAARectRenderer.cpp8
-rw-r--r--src/gpu/GrBufferAllocPool.cpp8
-rw-r--r--src/gpu/GrContext.cpp12
-rw-r--r--src/gpu/GrDrawState.cpp485
-rw-r--r--src/gpu/GrDrawState.h270
-rw-r--r--src/gpu/GrDrawTarget.cpp498
-rw-r--r--src/gpu/GrDrawTarget.h259
-rw-r--r--src/gpu/GrGpu.cpp4
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp18
-rw-r--r--src/gpu/GrTextContext.cpp4
-rw-r--r--src/gpu/gl/GrGLProgram.cpp8
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp24
-rw-r--r--src/gpu/gr_unittests.cpp2
15 files changed, 807 insertions, 799 deletions
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 4efc43a0db..930d8a2f76 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -454,7 +454,7 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
const SkMatrix* vm = &adcd.getOriginalMatrix();
GrVertexLayout layout = 0;
- layout |= GrDrawTarget::kEdge_VertexLayoutBit;
+ layout |= GrDrawState::kEdge_VertexLayoutBit;
// We use the fact that SkPath::transform path does subdivision based on
// perspective. Otherwise, we apply the view matrix when copying to the
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index df7aca8984..c229f661dd 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -502,7 +502,7 @@ bool GrAAHairLinePathRenderer::createGeom(
target->getClip()->getConservativeBounds(drawState.getRenderTarget(),
&devClipBounds);
- GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
+ GrVertexLayout layout = GrDrawState::kEdge_VertexLayoutBit;
SkMatrix viewM = drawState.getViewMatrix();
PREALLOC_PTARRAY(128) lines;
@@ -514,7 +514,7 @@ bool GrAAHairLinePathRenderer::createGeom(
*lineCnt = lines.count() / 2;
int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt;
- GrAssert(sizeof(Vertex) == GrDrawTarget::VertexSize(layout));
+ GrAssert(sizeof(Vertex) == GrDrawState::VertexSize(layout));
if (!arg->set(target, layout, vertCnt, 0)) {
return false;
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index b9d17f8802..b23ed9ab4b 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -16,9 +16,9 @@ namespace {
static GrVertexLayout aa_rect_layout(bool useCoverage) {
GrVertexLayout layout = 0;
if (useCoverage) {
- layout |= GrDrawTarget::kCoverage_VertexLayoutBit;
+ layout |= GrDrawState::kCoverage_VertexLayoutBit;
} else {
- layout |= GrDrawTarget::kColor_VertexLayoutBit;
+ layout |= GrDrawState::kColor_VertexLayoutBit;
}
return layout;
}
@@ -127,7 +127,7 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu,
bool useVertexCoverage) {
GrVertexLayout layout = aa_rect_layout(useVertexCoverage);
- size_t vsize = GrDrawTarget::VertexSize(layout);
+ size_t vsize = GrDrawState::VertexSize(layout);
GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0);
if (!geo.succeeded()) {
@@ -196,7 +196,7 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu,
return;
}
GrVertexLayout layout = aa_rect_layout(useVertexCoverage);
- size_t vsize = GrDrawTarget::VertexSize(layout);
+ size_t vsize = GrDrawState::VertexSize(layout);
GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0);
if (!geo.succeeded()) {
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index 66b74e4295..831c430891 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -382,7 +382,7 @@ void* GrVertexBufferAllocPool::makeSpace(GrVertexLayout layout,
GrAssert(NULL != buffer);
GrAssert(NULL != startVertex);
- size_t vSize = GrDrawTarget::VertexSize(layout);
+ size_t vSize = GrDrawState::VertexSize(layout);
size_t offset = 0; // assign to suppress warning
const GrGeometryBuffer* geomBuffer = NULL; // assign to suppress warning
void* ptr = INHERITED::makeSpace(vSize * vertexCount,
@@ -405,7 +405,7 @@ bool GrVertexBufferAllocPool::appendVertices(GrVertexLayout layout,
if (NULL != space) {
memcpy(space,
vertices,
- GrDrawTarget::VertexSize(layout) * vertexCount);
+ GrDrawState::VertexSize(layout) * vertexCount);
return true;
} else {
return false;
@@ -414,11 +414,11 @@ bool GrVertexBufferAllocPool::appendVertices(GrVertexLayout layout,
int GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const {
return INHERITED::preallocatedBufferSize() /
- GrDrawTarget::VertexSize(layout);
+ GrDrawState::VertexSize(layout);
}
int GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const {
- return currentBufferItems(GrDrawTarget::VertexSize(layout));
+ return currentBufferItems(GrDrawState::VertexSize(layout));
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index fdeb15cf1d..41029f4103 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -309,7 +309,7 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params);
- static const GrVertexLayout layout = GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+ static const GrVertexLayout layout = GrDrawState::StageTexCoordVertexLayoutBit(0,0);
GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
if (arg.succeeded()) {
@@ -875,12 +875,12 @@ void GrContext::drawVertices(const GrPaint& paint,
GrVertexLayout layout = 0;
if (NULL != texCoords) {
- layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0);
+ layout |= GrDrawState::StageTexCoordVertexLayoutBit(0, 0);
}
if (NULL != colors) {
- layout |= GrDrawTarget::kColor_VertexLayoutBit;
+ layout |= GrDrawState::kColor_VertexLayoutBit;
}
- int vertexSize = GrDrawTarget::VertexSize(layout);
+ int vertexSize = GrDrawState::VertexSize(layout);
if (sizeof(GrPoint) != vertexSize) {
if (!geo.set(target, layout, vertexCount, 0)) {
@@ -889,7 +889,7 @@ void GrContext::drawVertices(const GrPaint& paint,
}
int texOffsets[GrDrawState::kMaxTexCoords];
int colorOffset;
- GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+ GrDrawState::VertexSizeAndOffsetsByIdx(layout,
texOffsets,
&colorOffset,
NULL,
@@ -1005,7 +1005,7 @@ void GrContext::internalDrawOval(const GrPaint& paint,
return;
}
- GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
+ GrVertexLayout layout = GrDrawState::kEdge_VertexLayoutBit;
GrAssert(sizeof(CircleVertex) == GrDrawTarget::VertexSize(layout));
GrDrawTarget::AutoReleaseGeometry geo(target, layout, 4, 0);
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 2d5c7aa68f..6079272246 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -7,6 +7,7 @@
#include "GrDrawState.h"
+#include "GrGpuVertex.h"
#include "GrPaint.h"
void GrDrawState::setFromPaint(const GrPaint& paint) {
@@ -47,6 +48,490 @@ 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.)
+ *
+ */
+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] |= 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);
+ }
+ }
+}
+
+/**
+ * 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 GrDrawState::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 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 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 GrDrawState::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 GrDrawState::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 GrDrawState::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 GrDrawState::VertexSizeAndOffsetsByIdx(
+ GrVertexLayout vertexLayout,
+ int texCoordOffsetsByIdx[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 < 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 GrDrawState::VertexSizeAndOffsetsByStage(
+ GrVertexLayout vertexLayout,
+ int texCoordOffsetsByStage[GrDrawState::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 < GrDrawState::kNumStages; ++s) {
+ int tcIdx = VertexTexCoordsForStage(s, vertexLayout);
+ texCoordOffsetsByStage[s] =
+ tcIdx < 0 ? 0 : texCoordOffsetsByIdx[tcIdx];
+ }
+ }
+ return size;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+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;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+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]);
+ }
+
+ // 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 < 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;
+ #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));
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
+ return SkToBool(layout & gStageTexCoordMasks[stageIdx]);
+}
+
+bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const {
+
+ 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 = this->getColor();
+ }
+
+ // Run through the color stages
+ int stageCnt = getFirstCoverageStage();
+ for (int s = 0; s < stageCnt; ++s) {
+ const GrEffectRef* effect = this->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 != this->getColorFilterMode()) {
+ validComponentFlags = 0;
+ }
+
+ // Check whether coverage is treated as color. If so we run through the coverage computation.
+ if (this->isCoverageDrawing()) {
+ GrColor coverageColor = this->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 = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
+ const GrEffectRef* effect = this->getStage(s).getEffect();
+ if (NULL != effect) {
+ (*effect)->getConstantColorComponents(&color, &validComponentFlags);
+ }
+ }
+ }
+ return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
void GrDrawState::AutoViewMatrixRestore::restore() {
if (NULL != fDrawState) {
fDrawState->setViewMatrix(fViewMatrix);
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index e70c38f154..dc3fdfe6a5 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -10,14 +10,15 @@
#include "GrBackendEffectFactory.h"
#include "GrColor.h"
-#include "SkMatrix.h"
-#include "GrRefCnt.h"
#include "GrEffectStage.h"
+#include "GrRefCnt.h"
+#include "GrRenderTarget.h"
#include "GrStencil.h"
+#include "GrTemplates.h"
#include "GrTexture.h"
-#include "GrRenderTarget.h"
#include "effects/GrSimpleTextureEffect.h"
+#include "SkMatrix.h"
#include "SkXfermode.h"
class GrPaint;
@@ -103,6 +104,269 @@ public:
void setFromPaint(const GrPaint& paint);
///////////////////////////////////////////////////////////////////////////
+ /// @name Vertex Format
+ ////
+
+ /**
+ * 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.
+ *
+ * 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]).
+ */
+
+ /**
+ * 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) {
+ GrAssert(stageIdx < kNumStages);
+ GrAssert(texCoordIdx < kMaxTexCoords);
+ return 1 << (stageIdx + (texCoordIdx * kNumStages));
+ }
+
+ static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
+
+private:
+ // non-stage bits start at this index.
+ static const int STAGE_BIT_CNT = kNumStages * kMaxTexCoords;
+public:
+
+ /**
+ * Additional Bits that can be specified in GrVertexLayout.
+ */
+ enum VertexLayoutBits {
+ /* vertices have colors (GrColor) */
+ kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
+ /* vertices have coverage (GrColor)
+ */
+ kCoverage_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
+ /* Use text vertices. (Pos and tex coords may be a different type for
+ * text [GrGpuTextVertex vs GrPoint].)
+ */
+ kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 2),
+
+ /* Each vertex specificies an edge. Distance to the edge is used to
+ * compute a coverage. See GrDrawState::setVertexEdgeType().
+ */
+ kEdge_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 3),
+ // for below assert
+ kDummyVertexLayoutBit,
+ kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
+ };
+ // make sure we haven't exceeded the number of bits in GrVertexLayout.
+ GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Helpers for picking apart vertex layouts
+
+ /**
+ * Helper function to compute the size of a vertex from a vertex layout
+ * @return size of a single vertex.
+ */
+ 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.
+ */
+ static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
+
+ /**
+ * Helper function to compute the offset of the color in a vertex
+ * @return offset of color in vertex layout or -1 if the
+ * layout has no color.
+ */
+ static int VertexColorOffset(GrVertexLayout vertexLayout);
+
+ /**
+ * Helper function to compute the offset of the coverage in a vertex
+ * @return offset of coverage in vertex layout or -1 if the
+ * layout has no coverage.
+ */
+ static int VertexCoverageOffset(GrVertexLayout vertexLayout);
+
+ /**
+ * Helper function to compute the offset of the edge pts in a vertex
+ * @return offset of edge in vertex layout or -1 if the
+ * layout has no edge.
+ */
+ static int VertexEdgeOffset(GrVertexLayout vertexLayout);
+
+ /**
+ * Helper function to determine if vertex layout contains explicit texture
+ * coordinates of some index.
+ *
+ * @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.
+ */
+ static bool VertexUsesTexCoordIdx(int coordIndex,
+ 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.)
+ *
+ * @param vertexLayout the layout to query
+ * @param texCoordOffsetsByIdx after return it is the offset of each
+ * tex coord index in the vertex or -1 if
+ * index isn'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)
+ * @param coverageOffset after return it is the offset of the
+ * coverage field in each vertex, or -1 if
+ * there aren't per-vertex coeverages.
+ * (optional)
+ * @param edgeOffset after return it is the offset of the
+ * edge eq field in each vertex, or -1 if
+ * there aren't per-vertex edge equations.
+ * (optional)
+ * @return size of a single vertex
+ */
+ static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
+ int texCoordOffsetsByIdx[kMaxTexCoords],
+ int *colorOffset,
+ int *coverageOffset,
+ int* edgeOffset);
+
+ /**
+ * Helper function to compute the size of each vertex and the offsets of
+ * texture coordinates and color. Determines tex coord offsets by stage
+ * rather than by index. (Each stage can be mapped to any t.c. index
+ * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
+ * tex coords then that stage's offset will be 0 (positions are always at 0).
+ *
+ * @param vertexLayout the layout to query
+ * @param texCoordOffsetsByStage after return it is the offset of each
+ * tex coord index in the vertex or -1 if
+ * index isn'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)
+ * @param coverageOffset after return it is the offset of the
+ * coverage field in each vertex, or -1 if
+ * there aren't per-vertex coeverages.
+ * (optional)
+ * @param edgeOffset after return it is the offset of the
+ * edge eq field in each vertex, or -1 if
+ * there aren't per-vertex edge equations.
+ * (optional)
+ * @return size of a single vertex
+ */
+ static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
+ int texCoordOffsetsByStage[kNumStages],
+ int* colorOffset,
+ int* coverageOffset,
+ int* edgeOffset);
+
+ // determine if src alpha is guaranteed to be one for all src pixels
+ bool srcAlphaWillBeOne(GrVertexLayout vertexLayout) const;
+
+ /**
+ * Accessing positions, texture coords, or colors, of a vertex within an
+ * array is a hassle involving casts and simple math. These helpers exist
+ * to keep GrDrawTarget clients' code a bit nicer looking.
+ */
+
+ /**
+ * Gets a pointer to a GrPoint of a vertex's position or texture
+ * coordinate.
+ * @param vertices the vetex array
+ * @param vertexIndex the index of the vertex in the array
+ * @param vertexSize the size of each vertex in the array
+ * @param offset the offset in bytes of the vertex component.
+ * Defaults to zero (corresponding to vertex position)
+ * @return pointer to the vertex component as a GrPoint
+ */
+ static GrPoint* GetVertexPoint(void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset = 0) {
+ intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<GrPoint*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+ static const GrPoint* GetVertexPoint(const void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset = 0) {
+ intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<const GrPoint*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+
+ /**
+ * Gets a pointer to a GrColor inside a vertex within a vertex array.
+ * @param vertices the vetex array
+ * @param vertexIndex the index of the vertex in the array
+ * @param vertexSize the size of each vertex in the array
+ * @param offset the offset in bytes of the vertex color
+ * @return pointer to the vertex component as a GrColor
+ */
+ static GrColor* GetVertexColor(void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset) {
+ intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<GrColor*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+ static const GrColor* GetVertexColor(const void* vertices,
+ int vertexIndex,
+ int vertexSize,
+ int offset) {
+ const intptr_t start = GrTCast<intptr_t>(vertices);
+ return GrTCast<const GrColor*>(start + offset +
+ vertexIndex * vertexSize);
+ }
+
+ static void VertexLayoutUnitTest();
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
/// @name Color
////
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);
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 544cfc3533..74d820b7f7 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -16,7 +16,6 @@
#include "GrIndexBuffer.h"
#include "SkMatrix.h"
#include "GrRefCnt.h"
-#include "GrTemplates.h"
#include "SkClipStack.h"
#include "SkPath.h"
@@ -170,76 +169,6 @@ public:
bool willUseHWAALines() const;
/**
- * 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.
- *
- * 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]).
- */
-
- /**
- * 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) {
- GrAssert(stageIdx < GrDrawState::kNumStages);
- GrAssert(texCoordIdx < GrDrawState::kMaxTexCoords);
- return 1 << (stageIdx + (texCoordIdx * GrDrawState::kNumStages));
- }
-
- static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
-
-private:
- // non-stage bits start at this index.
- static const int STAGE_BIT_CNT = GrDrawState::kNumStages *
- GrDrawState::kMaxTexCoords;
-public:
-
- /**
- * Additional Bits that can be specified in GrVertexLayout.
- */
- enum VertexLayoutBits {
- /* vertices have colors (GrColor) */
- kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
- /* vertices have coverage (GrColor)
- */
- kCoverage_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
- /* Use text vertices. (Pos and tex coords may be a different type for
- * text [GrGpuTextVertex vs GrPoint].)
- */
- kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 2),
-
- /* Each vertex specificies an edge. Distance to the edge is used to
- * compute a coverage. See GrDrawState::setVertexEdgeType().
- */
- kEdge_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 3),
- // for below assert
- kDummyVertexLayoutBit,
- kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
- };
- // make sure we haven't exceeded the number of bits in GrVertexLayout.
- GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
-
- /**
* There are three types of "sources" of geometry (vertices and indices) for
* draw calls made on the target. When performing an indexed draw, the
* indices and vertices can use different source types. Once a source is
@@ -671,191 +600,6 @@ public:
GrDrawTarget* fTarget;
};
- ////////////////////////////////////////////////////////////////////////////
- // Helpers for picking apart vertex layouts
-
- /**
- * Helper function to compute the size of a vertex from a vertex layout
- * @return size of a single vertex.
- */
- 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.
- */
- static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
-
- /**
- * Helper function to compute the offset of the color in a vertex
- * @return offset of color in vertex layout or -1 if the
- * layout has no color.
- */
- static int VertexColorOffset(GrVertexLayout vertexLayout);
-
- /**
- * Helper function to compute the offset of the coverage in a vertex
- * @return offset of coverage in vertex layout or -1 if the
- * layout has no coverage.
- */
- static int VertexCoverageOffset(GrVertexLayout vertexLayout);
-
- /**
- * Helper function to compute the offset of the edge pts in a vertex
- * @return offset of edge in vertex layout or -1 if the
- * layout has no edge.
- */
- static int VertexEdgeOffset(GrVertexLayout vertexLayout);
-
- /**
- * Helper function to determine if vertex layout contains explicit texture
- * coordinates of some index.
- *
- * @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.
- */
- static bool VertexUsesTexCoordIdx(int coordIndex,
- 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.)
- *
- * @param vertexLayout the layout to query
- * @param texCoordOffsetsByIdx after return it is the offset of each
- * tex coord index in the vertex or -1 if
- * index isn'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)
- * @param coverageOffset after return it is the offset of the
- * coverage field in each vertex, or -1 if
- * there aren't per-vertex coeverages.
- * (optional)
- * @param edgeOffset after return it is the offset of the
- * edge eq field in each vertex, or -1 if
- * there aren't per-vertex edge equations.
- * (optional)
- * @return size of a single vertex
- */
- static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
- int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords],
- int *colorOffset,
- int *coverageOffset,
- int* edgeOffset);
-
- /**
- * Helper function to compute the size of each vertex and the offsets of
- * texture coordinates and color. Determines tex coord offsets by stage
- * rather than by index. (Each stage can be mapped to any t.c. index
- * by StageTexCoordVertexLayoutBit.) If a stage uses positions for
- * tex coords then that stage's offset will be 0 (positions are always at 0).
- *
- * @param vertexLayout the layout to query
- * @param texCoordOffsetsByStage after return it is the offset of each
- * tex coord index in the vertex or -1 if
- * index isn'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)
- * @param coverageOffset after return it is the offset of the
- * coverage field in each vertex, or -1 if
- * there aren't per-vertex coeverages.
- * (optional)
- * @param edgeOffset after return it is the offset of the
- * edge eq field in each vertex, or -1 if
- * there aren't per-vertex edge equations.
- * (optional)
- * @return size of a single vertex
- */
- static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
- int texCoordOffsetsByStage[GrDrawState::kNumStages],
- int* colorOffset,
- int* coverageOffset,
- int* edgeOffset);
-
- /**
- * Accessing positions, texture coords, or colors, of a vertex within an
- * array is a hassle involving casts and simple math. These helpers exist
- * to keep GrDrawTarget clients' code a bit nicer looking.
- */
-
- /**
- * Gets a pointer to a GrPoint of a vertex's position or texture
- * coordinate.
- * @param vertices the vetex array
- * @param vertexIndex the index of the vertex in the array
- * @param vertexSize the size of each vertex in the array
- * @param offset the offset in bytes of the vertex component.
- * Defaults to zero (corresponding to vertex position)
- * @return pointer to the vertex component as a GrPoint
- */
- static GrPoint* GetVertexPoint(void* vertices,
- int vertexIndex,
- int vertexSize,
- int offset = 0) {
- intptr_t start = GrTCast<intptr_t>(vertices);
- return GrTCast<GrPoint*>(start + offset +
- vertexIndex * vertexSize);
- }
- static const GrPoint* GetVertexPoint(const void* vertices,
- int vertexIndex,
- int vertexSize,
- int offset = 0) {
- intptr_t start = GrTCast<intptr_t>(vertices);
- return GrTCast<const GrPoint*>(start + offset +
- vertexIndex * vertexSize);
- }
-
- /**
- * Gets a pointer to a GrColor inside a vertex within a vertex array.
- * @param vertices the vetex array
- * @param vertexIndex the index of the vertex in the array
- * @param vertexSize the size of each vertex in the array
- * @param offset the offset in bytes of the vertex color
- * @return pointer to the vertex component as a GrColor
- */
- static GrColor* GetVertexColor(void* vertices,
- int vertexIndex,
- int vertexSize,
- int offset) {
- intptr_t start = GrTCast<intptr_t>(vertices);
- return GrTCast<GrColor*>(start + offset +
- vertexIndex * vertexSize);
- }
- static const GrColor* GetVertexColor(const void* vertices,
- int vertexIndex,
- int vertexSize,
- int offset) {
- const intptr_t start = GrTCast<intptr_t>(vertices);
- return GrTCast<const GrColor*>(start + offset +
- vertexIndex * vertexSize);
- }
-
- static void VertexLayoutUnitTest();
-
protected:
/**
@@ -906,9 +650,6 @@ protected:
GrBlendCoeff* srcCoeff = NULL,
GrBlendCoeff* dstCoeff = NULL) const;
- // determine if src alpha is guaranteed to be one for all src pixels
- bool srcAlphaWillBeOne(GrVertexLayout vertexLayout) const;
-
enum GeometrySrcType {
kNone_GeometrySrcType, //<! src has not been specified
kReserved_GeometrySrcType, //<! src was set using reserve*Space
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index d2a8852ee1..b32c56aaf6 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -498,7 +498,7 @@ bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) {
void GrGpu::releaseReservedVertexSpace() {
const GeometrySrcState& geoSrc = this->getGeomSrc();
GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
- size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+ size_t bytes = geoSrc.fVertexCount * GrDrawState::VertexSize(geoSrc.fVertexLayout);
fVertexPool->putBack(bytes);
--fVertexPoolUseCnt;
}
@@ -544,7 +544,7 @@ void GrGpu::releaseVertexArray() {
// if vertex source was array, we stowed data in the pool
const GeometrySrcState& geoSrc = this->getGeomSrc();
GrAssert(kArray_GeometrySrcType == geoSrc.fVertexSrc);
- size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+ size_t bytes = geoSrc.fVertexCount * GrDrawState::VertexSize(geoSrc.fVertexLayout);
fVertexPool->putBack(bytes);
--fVertexPoolUseCnt;
}
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index aceff2e064..7e83589443 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -118,7 +118,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
}
if (batchAcrossColors) {
- layout |= kColor_VertexLayoutBit;
+ layout |= GrDrawState::kColor_VertexLayoutBit;
}
AutoReleaseGeometry geo(this, layout, 4, 0);
@@ -193,10 +193,10 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
if (target->height() <= devClipRect.fBottom) {
devClipRect.fBottom = SK_ScalarMax;
}
- int stride = VertexSize(layout);
+ int stride = GrDrawState::VertexSize(layout);
bool insideClip = true;
for (int v = 0; v < 4; ++v) {
- const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
+ const GrPoint& p = *GrDrawState::GetVertexPoint(geo.vertices(), v, stride);
if (!devClipRect.contains(p)) {
insideClip = false;
break;
@@ -215,7 +215,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
fCurrQuad < fMaxQuads &&
layout == fLastRectVertexLayout) {
- int vsize = VertexSize(layout);
+ int vsize = GrDrawState::VertexSize(layout);
Draw& lastDraw = fDraws.back();
@@ -335,7 +335,7 @@ void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
// update the amount of reserved data actually referenced in draws
size_t vertexBytes = instanceCount * verticesPerInstance *
- VertexSize(draw->fVertexLayout);
+ GrDrawState::VertexSize(draw->fVertexLayout);
poolState.fUsedPoolVertexBytes =
GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
@@ -411,7 +411,7 @@ void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
case kReserved_GeometrySrcType: // fallthrough
case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(draw->fVertexLayout);
+ GrDrawState::VertexSize(draw->fVertexLayout);
poolState.fUsedPoolVertexBytes =
GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
draw->fVertexBuffer = poolState.fPoolVertexBuffer;
@@ -474,7 +474,7 @@ void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
case kReserved_GeometrySrcType: // fallthrough
case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
- VertexSize(draw->fVertexLayout);
+ GrDrawState::VertexSize(draw->fVertexLayout);
poolState.fUsedPoolVertexBytes =
GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
draw->fVertexBuffer = poolState.fPoolVertexBuffer;
@@ -759,7 +759,7 @@ void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
// provided by the vertex buffer pool. At each draw we tracked the largest
// offset into the pool's pointer that was referenced. Now we return to the
// pool any portion at the tail of the allocation that no draw referenced.
- size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
+ size_t reservedVertexBytes = GrDrawState::VertexSize(geoSrc.fVertexLayout) *
geoSrc.fVertexCount;
fVertexPool.putBack(reservedVertexBytes -
poolState.fUsedPoolVertexBytes);
@@ -852,7 +852,7 @@ void GrInOrderDrawBuffer::geometrySourceWillPop(
if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
kArray_GeometrySrcType == restoredState.fVertexSrc) {
poolState.fUsedPoolVertexBytes =
- VertexSize(restoredState.fVertexLayout) *
+ GrDrawState::VertexSize(restoredState.fVertexLayout) *
restoredState.fVertexCount;
}
if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index beb3f91f6b..206f4ca3fb 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -95,8 +95,8 @@ GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint(
fMaxVertices = 0;
fVertexLayout =
- GrDrawTarget::kTextFormat_VertexLayoutBit |
- GrDrawTarget::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0);
+ GrDrawState::kTextFormat_VertexLayoutBit |
+ GrDrawState::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0);
}
GrTextContext::~GrTextContext() {
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index e6daa9ca4e..2aa723619b 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -225,7 +225,7 @@ void add_color_filter(SkString* fsCode, const char * outputVar,
bool GrGLProgram::genEdgeCoverage(SkString* coverageVar,
GrGLShaderBuilder* builder) const {
- if (fDesc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit) {
+ if (fDesc.fVertexLayout & GrDrawState::kEdge_VertexLayoutBit) {
const char *vsName, *fsName;
builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName);
builder->fVSAttrs.push_back().set(kVec4f_GrSLType,
@@ -587,7 +587,7 @@ 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 (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
+ if (GrDrawState::VertexUsesTexCoordIdx(t, layout)) {
tex_attr_name(t, texCoordAttrs + t);
builder.fVSAttrs.push_back().set(kVec2f_GrSLType,
GrGLShaderVar::kAttribute_TypeModifier,
@@ -611,7 +611,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
const char* inCoords;
// figure out what our input coords are
- int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout);
+ int tcIdx = GrDrawState::VertexTexCoordsForStage(s, layout);
if (tcIdx < 0) {
inCoords = builder.positionAttribute().c_str();
} else {
@@ -708,7 +708,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
const char* inCoords;
// figure out what our input coords are
int tcIdx =
- GrDrawTarget::VertexTexCoordsForStage(s, layout);
+ GrDrawState::VertexTexCoordsForStage(s, layout);
if (tcIdx < 0) {
inCoords = builder.positionAttribute().c_str();
} else {
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index b8d5f08088..d1a60fab2c 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -165,7 +165,7 @@ void GrGpuGL::flushColor(GrColor color) {
const ProgramDesc& desc = fCurrentProgram->getDesc();
const GrDrawState& drawState = this->getDrawState();
- if (this->getVertexLayout() & kColor_VertexLayoutBit) {
+ if (this->getVertexLayout() & GrDrawState::kColor_VertexLayoutBit) {
// color will be specified per-vertex as an attribute
// invalidate the const vertex attrib color
fHWConstAttribColor = GrColor_ILLEGAL;
@@ -214,7 +214,7 @@ void GrGpuGL::flushCoverage(GrColor coverage) {
// const GrDrawState& drawState = this->getDrawState();
- if (this->getVertexLayout() & kCoverage_VertexLayoutBit) {
+ if (this->getVertexLayout() & GrDrawState::kCoverage_VertexLayoutBit) {
// coverage will be specified per-vertex as an attribute
// invalidate the const vertex attrib coverage
fHWConstAttribCoverage = GrColor_ILLEGAL;
@@ -352,7 +352,7 @@ void GrGpuGL::setupGeometry(int* startVertex,
GrVertexLayout currLayout = this->getVertexLayout();
- GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
+ GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx(
currLayout,
newTexCoordOffsets,
&newColorOffset,
@@ -363,7 +363,7 @@ void GrGpuGL::setupGeometry(int* startVertex,
int oldTexCoordOffsets[GrDrawState::kMaxTexCoords];
int oldEdgeOffset;
- GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
+ GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx(
fHWGeometryState.fVertexLayout,
oldTexCoordOffsets,
&oldColorOffset,
@@ -377,7 +377,7 @@ void GrGpuGL::setupGeometry(int* startVertex,
GrGLenum scalarType;
bool texCoordNorm;
- if (currLayout & kTextFormat_VertexLayoutBit) {
+ if (currLayout & GrDrawState::kTextFormat_VertexLayoutBit) {
scalarType = TEXT_COORDS_GL_TYPE;
texCoordNorm = SkToBool(TEXT_COORDS_ARE_NORMALIZED);
} else {
@@ -401,7 +401,7 @@ void GrGpuGL::setupGeometry(int* startVertex,
// or the type/normalization changed based on text vs nontext type coords.
bool posAndTexChange = allOffsetsChange ||
(((TEXT_COORDS_GL_TYPE != GR_GL_FLOAT) || TEXT_COORDS_ARE_NORMALIZED) &&
- (kTextFormat_VertexLayoutBit &
+ (GrDrawState::kTextFormat_VertexLayoutBit &
(fHWGeometryState.fVertexLayout ^ currLayout)));
if (posAndTexChange) {
@@ -503,14 +503,14 @@ void GrGpuGL::buildProgram(bool isPoints,
desc->fEmitsPointSize = isPoints;
bool requiresAttributeColors = !skipColor &&
- SkToBool(desc->fVertexLayout & kColor_VertexLayoutBit);
+ SkToBool(desc->fVertexLayout & GrDrawState::kColor_VertexLayoutBit);
bool requiresAttributeCoverage = !skipCoverage &&
- SkToBool(desc->fVertexLayout & kCoverage_VertexLayoutBit);
+ SkToBool(desc->fVertexLayout & GrDrawState::kCoverage_VertexLayoutBit);
// fColorInput/fCoverageInput records how colors are specified for the.
// program. So we strip the bits from the layout to avoid false negatives
// when searching for an existing program in the cache.
- desc->fVertexLayout &= ~(kColor_VertexLayoutBit | kCoverage_VertexLayoutBit);
+ desc->fVertexLayout &= ~(GrDrawState::kColor_VertexLayoutBit | GrDrawState::kCoverage_VertexLayoutBit);
desc->fColorFilterXfermode = skipColor ?
SkXfermode::kDst_Mode :
@@ -519,7 +519,7 @@ void GrGpuGL::buildProgram(bool isPoints,
// no reason to do edge aa or look at per-vertex coverage if coverage is
// ignored
if (skipCoverage) {
- desc->fVertexLayout &= ~(kEdge_VertexLayoutBit | kCoverage_VertexLayoutBit);
+ desc->fVertexLayout &= ~(GrDrawState::kEdge_VertexLayoutBit | GrDrawState::kCoverage_VertexLayoutBit);
}
bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
@@ -549,7 +549,7 @@ void GrGpuGL::buildProgram(bool isPoints,
int lastEnabledStage = -1;
- if (!skipCoverage && (desc->fVertexLayout &GrDrawTarget::kEdge_VertexLayoutBit)) {
+ if (!skipCoverage && (desc->fVertexLayout &GrDrawState::kEdge_VertexLayoutBit)) {
desc->fVertexEdgeType = drawState.getVertexEdgeType();
desc->fDiscardIfOutsideEdge = drawState.getStencil().doesWrite();
} else {
@@ -592,7 +592,7 @@ void GrGpuGL::buildProgram(bool isPoints,
// other coverage inputs
if (!hasCoverage) {
hasCoverage = requiresAttributeCoverage ||
- (desc->fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit);
+ (desc->fVertexLayout & GrDrawState::kEdge_VertexLayoutBit);
}
if (hasCoverage) {
diff --git a/src/gpu/gr_unittests.cpp b/src/gpu/gr_unittests.cpp
index 7a3a25115c..7f5c7e9cff 100644
--- a/src/gpu/gr_unittests.cpp
+++ b/src/gpu/gr_unittests.cpp
@@ -75,5 +75,5 @@ void gr_run_unittests() {
test_bsearch();
test_binHashKey();
GrRedBlackTree<int>::UnitTest();
- GrDrawTarget::VertexLayoutUnitTest();
+ GrDrawState::VertexLayoutUnitTest();
}