Resubmit r7899 and r7901.
git-svn-id: http://skia.googlecode.com/svn/trunk@7929 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 3925bd9..6b00913 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -57,270 +57,150 @@
* they were just a series of immediate->memory moves.)
*
*/
-void gen_tex_coord_mask(GrVertexLayout* texCoordMask) {
+void gen_tex_coord_mask(GrAttribBindings* texCoordMask) {
*texCoordMask = 0;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- *texCoordMask |= GrDrawState::StageTexCoordVertexLayoutBit(s);
+ *texCoordMask |= GrDrawState::ExplicitTexCoordAttribBindingsBit(s);
}
}
-const GrVertexLayout kTexCoordMask = (1 << GrDrawState::kNumStages)-1;
-
-inline int num_tex_coords(GrVertexLayout layout) {
- return (kTexCoordMask & layout) ? 1 : 0;
-}
+const GrAttribBindings kTexCoord_AttribBindingsMask = (1 << GrDrawState::kNumStages)-1;
} //unnamed namespace
-static const size_t kVec2Size = sizeof(GrPoint);
+const size_t GrDrawState::kVertexAttribSizes[kGrVertexAttribTypeCount] = {
+ sizeof(float), // kFloat_GrVertexAttribType
+ 2*sizeof(float), // kVec2_GrVertexAttribType
+ 3*sizeof(float), // kVec3_GrVertexAttribType
+ 4*sizeof(float), // kVec4_GrVertexAttribType
+ 4*sizeof(char) // kCVec4_GrVertexAttribType
+};
-size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) {
- size_t size = kVec2Size; // position
- size += num_tex_coords(vertexLayout) * kVec2Size;
- if (vertexLayout & kColor_VertexLayoutBit) {
- size += sizeof(GrColor);
- }
- if (vertexLayout & kCoverage_VertexLayoutBit) {
- size += sizeof(GrColor);
- }
- if (vertexLayout & kEdge_VertexLayoutBit) {
- size += 4 * sizeof(SkScalar);
+static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
+ // this works as long as we're 4 byte-aligned
+#if GR_DEBUG
+ uint32_t overlapCheck = 0;
+#endif
+ GrAssert(count <= GrDrawState::kAttribIndexCount);
+ size_t size = 0;
+ for (int index = 0; index < count; ++index) {
+ size_t attribSize = GrDrawState::kVertexAttribSizes[attribs[index].fType];
+ size += attribSize;
+#if GR_DEBUG
+ size_t dwordCount = attribSize >> 2;
+ uint32_t mask = (1 << dwordCount)-1;
+ size_t offsetShift = attribs[index].fOffset >> 2;
+ GrAssert(!(overlapCheck & (mask << offsetShift)));
+ overlapCheck |= (mask << offsetShift);
+#endif
}
return size;
}
+size_t GrDrawState::getVertexSize() const {
+ return vertex_size(fVertexAttribs.begin(), fVertexAttribs.count());
+}
+
+const GrAttribBindings GrDrawState::kAttribIndexMasks[kAttribIndexCount] = {
+ 0, // position is not reflected in the bindings
+ kColor_AttribBindingsBit,
+ kCoverage_AttribBindingsBit,
+ kEdge_AttribBindingsBit,
+ kTexCoord_AttribBindingsMask
+};
+
////////////////////////////////////////////////////////////////////////////////
-/**
- * Functions for computing offsets of various components from the layout
- * bitfield.
- *
- * Order of vertex components:
- * Position
- * Tex Coord
- * Color
- * Coverage
- */
-
-int GrDrawState::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) {
- if (!StageUsesTexCoords(vertexLayout, stageIdx)) {
- return 0;
+void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
+ GrAssert(count <= GrDrawState::kAttribIndexCount);
+ fVertexAttribs.reset();
+ for (int index = 0; index < count; ++index) {
+ fVertexAttribs.push_back(attribs[index]);
}
-
- return kVec2Size;
-}
-
-int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) {
- if (vertexLayout & kColor_VertexLayoutBit) {
- return kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
- }
- return -1;
-}
-
-int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) {
- if (vertexLayout & kCoverage_VertexLayoutBit) {
- int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1);
- if (vertexLayout & kColor_VertexLayoutBit) {
- offset += sizeof(GrColor);
- }
- return offset;
- }
- return -1;
-}
-
-int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) {
- // edge pts are after the pos, tex coords, and color
- if (vertexLayout & kEdge_VertexLayoutBit) {
- int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
- if (vertexLayout & kColor_VertexLayoutBit) {
- offset += sizeof(GrColor);
- }
- if (vertexLayout & kCoverage_VertexLayoutBit) {
- offset += sizeof(GrColor);
- }
- return offset;
- }
- return -1;
-}
-
-int GrDrawState::VertexSizeAndOffsets(
- GrVertexLayout vertexLayout,
- int* texCoordOffset,
- int* colorOffset,
- int* coverageOffset,
- int* edgeOffset) {
- int size = kVec2Size; // position
-
- if (kTexCoordMask & vertexLayout) {
- if (NULL != texCoordOffset) {
- *texCoordOffset = size;
- }
- size += kVec2Size;
- } else {
- if (NULL != texCoordOffset) {
- *texCoordOffset = -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) {
-
- int texCoordOffset;
- int size = VertexSizeAndOffsets(vertexLayout,
- &texCoordOffset,
- colorOffset,
- coverageOffset,
- edgeOffset);
- if (NULL != texCoordOffsetsByStage) {
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- texCoordOffsetsByStage[s] = StageUsesTexCoords(vertexLayout, s) ?
- texCoordOffset : 0;
- }
- }
- return size;
}
////////////////////////////////////////////////////////////////////////////////
-bool GrDrawState::VertexUsesTexCoords(GrVertexLayout vertexLayout) {
- return SkToBool(kTexCoordMask & vertexLayout);
+void GrDrawState::setDefaultVertexAttribs() {
+ fVertexAttribs.reset();
+ fVertexAttribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, 0));
+
+ fCommon.fAttribBindings = kDefault_AttribBindings;
+
+ fAttribIndices[kPosition_AttribIndex] = 0;
}
////////////////////////////////////////////////////////////////////////////////
-void GrDrawState::VertexLayoutUnitTest() {
+bool GrDrawState::AttributesBindExplicitTexCoords(GrAttribBindings attribBindings) {
+ return SkToBool(kTexCoord_AttribBindingsMask & attribBindings);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDrawState::VertexAttributesUnitTest() {
// Ensure that our tex coord mask is correct
- GrVertexLayout texCoordMask;
+ GrAttribBindings texCoordMask;
gen_tex_coord_mask(&texCoordMask);
- GrAssert(texCoordMask == kTexCoordMask);
+ GrAssert(texCoordMask == kTexCoord_AttribBindingsMask);
// not necessarily exhaustive
static bool run;
if (!run) {
run = true;
- GrVertexLayout tcMask = 0;
- GrAssert(!VertexUsesTexCoords(0));
+
+ GrVertexAttribArray<6> attribs;
+ GrAssert(0 == vertex_size(attribs.begin(), attribs.count()));
+
+ attribs.push_back(GrVertexAttrib(kFloat_GrVertexAttribType, 0));
+ GrAssert(sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
+ attribs[0].fType = kVec2f_GrVertexAttribType;
+ GrAssert(2*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
+ attribs[0].fType = kVec3f_GrVertexAttribType;
+ GrAssert(3*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
+ attribs[0].fType = kVec4f_GrVertexAttribType;
+ GrAssert(4*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
+ attribs[0].fType = kVec4ub_GrVertexAttribType;
+ GrAssert(4*sizeof(char) == vertex_size(attribs.begin(), attribs.count()));
+
+ attribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, attribs[0].fOffset + 4*sizeof(char)));
+ GrAssert(4*sizeof(char) + 2*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
+ attribs.push_back(GrVertexAttrib(kVec3f_GrVertexAttribType, attribs[1].fOffset + 2*sizeof(float)));
+ GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) ==
+ vertex_size(attribs.begin(), attribs.count()));
+ attribs.push_back(GrVertexAttrib(kFloat_GrVertexAttribType, attribs[2].fOffset + 3*sizeof(float)));
+ GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) ==
+ vertex_size(attribs.begin(), attribs.count()));
+ attribs.push_back(GrVertexAttrib(kVec4f_GrVertexAttribType, attribs[3].fOffset + sizeof(float)));
+ GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) + 4*sizeof(float) ==
+ vertex_size(attribs.begin(), attribs.count()));
+
+ GrAttribBindings tcMask = 0;
+ GrAssert(!AttributesBindExplicitTexCoords(0));
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- tcMask |= StageTexCoordVertexLayoutBit(s);
- GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
- GrAssert(VertexUsesTexCoords(tcMask));
- GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
- GrAssert(StageUsesTexCoords(tcMask, s));
+ tcMask |= ExplicitTexCoordAttribBindingsBit(s);
+ GrAssert(AttributesBindExplicitTexCoords(tcMask));
+ GrAssert(StageBindsExplicitTexCoords(tcMask, s));
for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
- GrAssert(!StageUsesTexCoords(tcMask, s2));
-
- #if GR_DEBUG
- GrVertexLayout posAsTex = tcMask;
- #endif
- GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
- GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
- GrAssert(!StageUsesTexCoords(posAsTex, s2));
- GrAssert(-1 == VertexEdgeOffset(posAsTex));
+ GrAssert(!StageBindsExplicitTexCoords(tcMask, s2));
}
- GrAssert(-1 == VertexEdgeOffset(tcMask));
- GrAssert(-1 == VertexColorOffset(tcMask));
- GrAssert(-1 == VertexCoverageOffset(tcMask));
- #if GR_DEBUG
- GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
- #endif
- GrAssert(-1 == VertexCoverageOffset(withColor));
- GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
- GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
- #if GR_DEBUG
- GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
- #endif
- GrAssert(-1 == VertexColorOffset(withEdge));
- GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
- GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
- #if GR_DEBUG
- GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
- #endif
- GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
- GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
- GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
- #if GR_DEBUG
- GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
- #endif
- GrAssert(-1 == VertexColorOffset(withCoverage));
- GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
- GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
- #if GR_DEBUG
- GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
- kColor_VertexLayoutBit;
- #endif
- GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
- GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
- GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
}
- GrAssert(kTexCoordMask == tcMask);
-
- int stageOffsets[GrDrawState::kNumStages];
- int colorOffset;
- int edgeOffset;
- int coverageOffset;
- int size;
- size = VertexSizeAndOffsetsByStage(tcMask,
- stageOffsets, &colorOffset,
- &coverageOffset, &edgeOffset);
- GrAssert(2*sizeof(GrPoint) == size);
- GrAssert(-1 == colorOffset);
- GrAssert(-1 == coverageOffset);
- GrAssert(-1 == edgeOffset);
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- GrAssert(sizeof(GrPoint) == stageOffsets[s]);
- GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
- }
+ GrAssert(kTexCoord_AttribBindingsMask == tcMask);
}
}
////////////////////////////////////////////////////////////////////////////////
-bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
- return SkToBool(layout & StageTexCoordVertexLayoutBit(stageIdx));
+bool GrDrawState::StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx) {
+ return SkToBool(bindings & ExplicitTexCoordAttribBindingsBit(stageIdx));
}
-bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const {
+bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const {
uint32_t validComponentFlags;
GrColor color;
// Check if per-vertex or constant color may have partial alpha
- if (layout & kColor_VertexLayoutBit) {
+ if (bindings & kColor_AttribBindingsBit) {
validComponentFlags = 0;
color = 0; // not strictly necessary but we get false alarms from tools about uninit.
} else {
@@ -366,7 +246,7 @@
return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
}
-bool GrDrawState::hasSolidCoverage(GrVertexLayout layout) const {
+bool GrDrawState::hasSolidCoverage(GrAttribBindings bindings) const {
// If we're drawing coverage directly then coverage is effectively treated as color.
if (this->isCoverageDrawing()) {
return true;
@@ -375,7 +255,7 @@
GrColor coverage;
uint32_t validComponentFlags;
// Initialize to an unknown starting coverage if per-vertex coverage is specified.
- if (layout & kCoverage_VertexLayoutBit) {
+ if (bindings & kCoverage_AttribBindingsBit) {
validComponentFlags = 0;
} else {
coverage = fCommon.fCoverage;
@@ -417,7 +297,7 @@
GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
GrBlendCoeff* srcCoeff,
GrBlendCoeff* dstCoeff) const {
- GrVertexLayout layout = this->getVertexLayout();
+ GrAttribBindings bindings = this->getAttribBindings();
GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
if (NULL == srcCoeff) {
@@ -435,14 +315,14 @@
*dstCoeff = kOne_GrBlendCoeff;
}
- bool srcAIsOne = this->srcAlphaWillBeOne(layout);
+ bool srcAIsOne = this->srcAlphaWillBeOne(bindings);
bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
(kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
(kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
bool covIsZero = !this->isCoverageDrawing() &&
- !(layout & GrDrawState::kCoverage_VertexLayoutBit) &&
+ !(bindings & GrDrawState::kCoverage_AttribBindingsBit) &&
0 == this->getCoverage();
// When coeffs are (0,1) there is no reason to draw at all, unless
// stenciling is enabled. Having color writes disabled is effectively
@@ -460,8 +340,8 @@
// edge aa or coverage stage
bool hasCoverage = forceCoverage ||
0xffffffff != this->getCoverage() ||
- (layout & GrDrawState::kCoverage_VertexLayoutBit) ||
- (layout & GrDrawState::kEdge_VertexLayoutBit);
+ (bindings & GrDrawState::kCoverage_AttribBindingsBit) ||
+ (bindings & GrDrawState::kEdge_AttribBindingsBit);
for (int s = this->getFirstCoverageStage();
!hasCoverage && s < GrDrawState::kNumStages;
++s) {