Rolling back r8466.
Not reviewed.
git-svn-id: http://skia.googlecode.com/svn/trunk@8467 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 2f96c15..d16efa8 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -23,6 +23,11 @@
#include "SkMatrix.h"
#include "SkXfermode.h"
+/**
+ * Type used to describe how attributes bind to program usage
+ */
+typedef int GrAttribBindings;
+
class GrDrawState : public GrRefCnt {
public:
SK_DECLARE_INST_COUNT(GrDrawState)
@@ -40,8 +45,8 @@
* coverage rather than as input to the src/dst color blend step.
*
* The input color to the first enabled color-stage is either the constant color or interpolated
- * per-vertex colors. The input to the first coverage stage is either a constant coverage
- * (usually full-coverage) or interpolated per-vertex coverage.
+ * per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
+ * either a constant coverage (usually full-coverage) or interpolated per-vertex coverage.
*
* See the documentation of kCoverageDrawing_StateBit for information about disabling the
* the color / coverage distinction.
@@ -57,6 +62,9 @@
};
GrDrawState() {
+#if GR_DEBUG
+ VertexAttributesUnitTest();
+#endif
this->reset();
}
@@ -107,72 +115,53 @@
////
enum {
- kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
+ kVertexAttribCnt = 6,
};
/**
- * The format of vertices is represented as an array of GrVertexAttribs, with each representing
- * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
- * GrTypesPriv.h).
+ * The format of vertices is represented as an array of vertex attribute
+ * pair, with each pair representing the type of the attribute and the
+ * offset in the vertex structure (see GrVertexAttrib, above).
*
- * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when
- * setEffect is called.
+ * This will only set up the vertex geometry. To bind the attributes in
+ * the shaders, attribute indices and attribute bindings need to be set
+ * as well.
*/
/**
* Sets vertex attributes for next draw.
*
* @param attribs the array of vertex attributes to set.
- * @param count the number of attributes being set, limited to kMaxVertexAttribCnt.
+ * @param count the number of attributes being set.
+ * limited to a count of kVertexAttribCnt.
*/
void setVertexAttribs(const GrVertexAttrib attribs[], int count);
- const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVertexAttribs.begin(); }
- int getVertexAttribCount() const { return fCommon.fVertexAttribs.count(); }
+ const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
+ int getVertexAttribCount() const { return fVertexAttribs.count(); }
size_t getVertexSize() const;
/**
- * Sets default vertex attributes for next draw. The default is a single attribute:
- * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
+ * Sets default vertex attributes for next draw.
+ *
+ * This will also set default vertex attribute indices and bindings
*/
void setDefaultVertexAttribs();
- /**
- * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
- * binding does not appear in the current attribs. These bindings should appear only once in
- * the attrib array.
- */
-
- int positionAttributeIndex() const {
- return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
- }
- int localCoordAttributeIndex() const {
- return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
- }
- int colorVertexAttributeIndex() const {
- return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
- }
- int coverageVertexAttributeIndex() const {
- return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
- }
-
- bool hasLocalCoordAttribute() const {
- return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
- }
- bool hasColorVertexAttribute() const {
- return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
- }
- bool hasCoverageVertexAttribute() const {
- return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
- }
-
bool validateVertexAttribs() const;
+ ////////////////////////////////////////////////////////////////////////////
+ // Helpers for picking apart vertex attributes
+
+ // helper array to let us check the expected so we know what bound attrib indices
+ // we care about
+ static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
+
/**
- * Accessing positions, local 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.
+ * 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.
*/
/**
@@ -229,15 +218,110 @@
/// @}
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Attribute Bindings
+ ////
+
+ /**
+ * The vertex data used by the current program is represented as a bitfield
+ * of flags. Programs always use positions and may also use texture
+ * coordinates, per-vertex colors, per-vertex coverage and edge data. The
+ * local coords accessible by effects may either come from positions or
+ * be specified explicitly.
+ */
+
+ /**
+ * Additional Bits that can be specified in GrAttribBindings.
+ */
+ enum AttribBindingsBits {
+ /** explicit local coords are provided (instead of using pre-view-matrix positions) */
+ kLocalCoords_AttribBindingsBit = 0x1,
+ /* program uses colors (GrColor) */
+ kColor_AttribBindingsBit = 0x2,
+ /* program uses coverage (GrColor)
+ */
+ kCoverage_AttribBindingsBit = 0x4,
+ // for below assert
+ kDummyAttribBindingsBit,
+ kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
+ };
+ // make sure we haven't exceeded the number of bits in GrAttribBindings.
+ GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribBindings)));
+
+ enum AttribBindings {
+ kDefault_AttribBindings = 0
+ };
+
+ /**
+ * Sets attribute bindings for next draw.
+ *
+ * @param bindings the attribute bindings to set.
+ */
+ void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; }
+
+ GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Helpers for picking apart attribute bindings
+
/**
* Determines whether src alpha is guaranteed to be one for all src pixels
*/
- bool srcAlphaWillBeOne() const;
+ bool srcAlphaWillBeOne(GrAttribBindings) const;
/**
* Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
*/
- bool hasSolidCoverage() const;
+ bool hasSolidCoverage(GrAttribBindings) const;
+
+ static void VertexAttributesUnitTest();
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Vertex Attribute Indices
+ ////
+
+ /**
+ * Vertex attribute indices map the data set in the vertex attribute array
+ * to the bindings specified in the attribute bindings. Each binding type
+ * has an associated index in the attribute array. This index is used to
+ * look up the vertex attribute data from the array, and potentially as the
+ * attribute index if we're binding attributes in GL.
+ *
+ * Indices which do not have active attribute bindings will be ignored.
+ */
+
+ enum AttribIndex {
+ kPosition_AttribIndex = 0,
+ kColor_AttribIndex,
+ kCoverage_AttribIndex,
+ kLocalCoords_AttribIndex,
+
+ kLast_AttribIndex = kLocalCoords_AttribIndex
+ };
+ static const int kAttribIndexCount = kLast_AttribIndex + 1;
+
+ // these are used when vertex color and coverage isn't set
+ enum {
+ kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt,
+ kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1,
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Helpers to set attribute indices. These should match the index in the
+ // current attribute index array.
+
+ /**
+ * Sets index for next draw. This is used to look up the offset
+ * from the current vertex attribute array and to bind the attributes.
+ *
+ * @param index the attribute index we're setting
+ * @param value the value of the index
+ */
+ void setAttribIndex(AttribIndex index, int value) { fAttribIndices[index] = value; }
+
+ int getAttribIndex(AttribIndex index) const { return fAttribIndices[index]; }
/// @}
@@ -984,6 +1068,15 @@
if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
return false;
}
+ if (fVertexAttribs != s.fVertexAttribs) {
+ return false;
+ }
+ for (int i = 0; i < kAttribIndexCount; ++i) {
+ if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
+ fAttribIndices[i] != s.fAttribIndices[i]) {
+ return false;
+ }
+ }
for (int i = 0; i < kNumStages; i++) {
bool enabled = this->isStageEnabled(i);
if (enabled != s.isStageEnabled(i)) {
@@ -1000,6 +1093,10 @@
GrDrawState& operator= (const GrDrawState& s) {
this->setRenderTarget(s.fRenderTarget.get());
fCommon = s.fCommon;
+ fVertexAttribs = s.fVertexAttribs;
+ for (int i = 0; i < kAttribIndexCount; i++) {
+ fAttribIndices[i] = s.fAttribIndices[i];
+ }
for (int i = 0; i < kNumStages; i++) {
if (s.isStageEnabled(i)) {
this->fStages[i] = s.fStages[i];
@@ -1013,44 +1110,33 @@
/** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
struct CommonState {
// These fields are roughly sorted by decreasing likelihood of being different in op==
- GrColor fColor;
- SkMatrix fViewMatrix;
- GrBlendCoeff fSrcBlend;
- GrBlendCoeff fDstBlend;
- GrColor fBlendConstant;
- uint32_t fFlagBits;
- GrVertexAttribArray<kMaxVertexAttribCnt> fVertexAttribs;
- GrStencilSettings fStencilSettings;
- int fFirstCoverageStage;
- GrColor fCoverage;
- SkXfermode::Mode fColorFilterMode;
- GrColor fColorFilterColor;
- DrawFace fDrawFace;
-
- // This is simply a different representation of info in fVertexAttribs and thus does
- // not need to be compared in op==.
- int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
-
- GR_STATIC_ASSERT(kGrVertexAttribBindingCnt <= 8*sizeof(uint32_t));
-
+ GrColor fColor;
+ GrAttribBindings fAttribBindings;
+ SkMatrix fViewMatrix;
+ GrBlendCoeff fSrcBlend;
+ GrBlendCoeff fDstBlend;
+ GrColor fBlendConstant;
+ uint32_t fFlagBits;
+ GrStencilSettings fStencilSettings;
+ int fFirstCoverageStage;
+ GrColor fCoverage;
+ SkXfermode::Mode fColorFilterMode;
+ GrColor fColorFilterColor;
+ DrawFace fDrawFace;
bool operator== (const CommonState& other) const {
- bool result = fColor == other.fColor &&
- fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
- fSrcBlend == other.fSrcBlend &&
- fDstBlend == other.fDstBlend &&
- fBlendConstant == other.fBlendConstant &&
- fFlagBits == other.fFlagBits &&
- fVertexAttribs == other.fVertexAttribs &&
- fStencilSettings == other.fStencilSettings &&
- fFirstCoverageStage == other.fFirstCoverageStage &&
- fCoverage == other.fCoverage &&
- fColorFilterMode == other.fColorFilterMode &&
- fColorFilterColor == other.fColorFilterColor &&
- fDrawFace == other.fDrawFace;
- GrAssert(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices,
- other.fFixedFunctionVertexAttribIndices,
- sizeof(fFixedFunctionVertexAttribIndices)));
- return result;
+ return fColor == other.fColor &&
+ fAttribBindings == other.fAttribBindings &&
+ fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
+ fSrcBlend == other.fSrcBlend &&
+ fDstBlend == other.fDstBlend &&
+ fBlendConstant == other.fBlendConstant &&
+ fFlagBits == other.fFlagBits &&
+ fStencilSettings == other.fStencilSettings &&
+ fFirstCoverageStage == other.fFirstCoverageStage &&
+ fCoverage == other.fCoverage &&
+ fColorFilterMode == other.fColorFilterMode &&
+ fColorFilterColor == other.fColorFilterColor &&
+ fDrawFace == other.fDrawFace;
}
bool operator!= (const CommonState& other) const { return !(*this == other); }
};
@@ -1083,6 +1169,10 @@
// TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
fRenderTarget = drawState.fRenderTarget.get();
SkSafeRef(fRenderTarget);
+ fVertexAttribs = drawState.fVertexAttribs;
+ for (int i = 0; i < kAttribIndexCount; i++) {
+ fAttribIndices[i] = drawState.fAttribIndices[i];
+ }
// Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
// ref gets fully unref'ed it will cause the underlying effect to unref its resources
// and recycle them to the cache (if no one else is holding a ref to the resources).
@@ -1096,6 +1186,10 @@
GrAssert(fInitialized);
drawState->fCommon = fCommon;
drawState->setRenderTarget(fRenderTarget);
+ drawState->fVertexAttribs = fVertexAttribs;
+ for (int i = 0; i < kAttribIndexCount; i++) {
+ drawState->fAttribIndices[i] = fAttribIndices[i];
+ }
for (int i = 0; i < kNumStages; ++i) {
fStages[i].restoreTo(&drawState->fStages[i]);
}
@@ -1105,6 +1199,16 @@
if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
return false;
}
+ for (int i = 0; i < kAttribIndexCount; ++i) {
+ if ((i == kPosition_AttribIndex ||
+ state.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
+ fAttribIndices[i] != state.fAttribIndices[i]) {
+ return false;
+ }
+ }
+ if (fVertexAttribs != state.fVertexAttribs) {
+ return false;
+ }
for (int i = 0; i < kNumStages; ++i) {
if (!fStages[i].isEqual(state.fStages[i])) {
return false;
@@ -1116,15 +1220,22 @@
private:
GrRenderTarget* fRenderTarget;
CommonState fCommon;
+ int fAttribIndices[kAttribIndexCount];
+ GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
GrEffectStage::DeferredStage fStages[kNumStages];
GR_DEBUGCODE(bool fInitialized;)
};
private:
+ // helper array to let us check the current bindings so we know what bound attrib indices
+ // we care about
+ static const GrAttribBindings kAttribIndexMasks[kAttribIndexCount];
SkAutoTUnref<GrRenderTarget> fRenderTarget;
CommonState fCommon;
+ int fAttribIndices[kAttribIndexCount];
+ GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
GrEffectStage fStages[kNumStages];
typedef GrRefCnt INHERITED;