aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrDrawState.h
diff options
context:
space:
mode:
authorGravatar jvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-01 18:21:22 +0000
committerGravatar jvanverth@google.com <jvanverth@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-01 18:21:22 +0000
commit9b855c7c95ce9fff7a447e4a6bdf8a469c1f3097 (patch)
treea97672e09387e62ddec1deca227f024806820222 /src/gpu/GrDrawState.h
parentdf8114d84616f8a85a5064f8deef2cca083193f8 (diff)
Resubmit r7899 and r7901.
git-svn-id: http://skia.googlecode.com/svn/trunk@7929 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/GrDrawState.h')
-rw-r--r--src/gpu/GrDrawState.h448
1 files changed, 260 insertions, 188 deletions
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 05492a73ae..53c575d3af 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -23,6 +23,41 @@
class GrPaint;
+/**
+ * Types used to describe format of vertices in arrays
+ */
+enum GrVertexAttribType {
+ kFloat_GrVertexAttribType = 0,
+ kVec2f_GrVertexAttribType,
+ kVec3f_GrVertexAttribType,
+ kVec4f_GrVertexAttribType,
+ kVec4ub_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors
+
+ kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
+};
+static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
+
+struct GrVertexAttrib {
+ GrVertexAttrib() {}
+ GrVertexAttrib(GrVertexAttribType type, size_t offset) :
+ fType(type), fOffset(offset) {}
+ bool operator==(const GrVertexAttrib& other) const {
+ return fType == other.fType && fOffset == other.fOffset;
+ };
+ bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
+
+ GrVertexAttribType fType;
+ size_t fOffset;
+};
+
+template <int N>
+class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
+
+/**
+ * Type used to describe how attributes bind to program usage
+ */
+typedef int GrAttribBindings;
+
class GrDrawState : public GrRefCnt {
public:
SK_DECLARE_INST_COUNT(GrDrawState)
@@ -32,7 +67,7 @@ public:
* GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
* output from the previous enabled stage and a position. The position is either derived from
* the interpolated vertex positions or explicit per-vertex coords, depending upon the
- * GrVertexLayout used to draw.
+ * GrAttribBindings used to draw.
*
* The stages are divided into two sets, color-computing and coverage-computing. The final color
* stage produces the final pixel color. The coverage-computing stages function exactly as the
@@ -40,7 +75,7 @@ public:
* 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, depending upon GrVertexLayout. The input to the first coverage stage is
+ * per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
* either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or
* edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a
* GrEffect).
@@ -59,7 +94,7 @@ public:
GrDrawState() {
#if GR_DEBUG
- VertexLayoutUnitTest();
+ VertexAttributesUnitTest();
#endif
this->reset();
}
@@ -82,8 +117,9 @@ public:
fRenderTarget.reset(NULL);
+ this->setDefaultVertexAttribs();
+
fCommon.fColor = 0xffffffff;
- fCommon.fVertexLayout = kDefault_VertexLayout;
fCommon.fViewMatrix.reset();
fCommon.fSrcBlend = kOne_GrBlendCoeff;
fCommon.fDstBlend = kZero_GrBlendCoeff;
@@ -107,193 +143,50 @@ public:
void setFromPaint(const GrPaint& paint);
///////////////////////////////////////////////////////////////////////////
- /// @name Vertex Layout
+ /// @name Vertex Attributes
////
- /**
- * 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 texture coordinates, per-vertex colors,
- * and per-vertex coverage. Each stage can use any 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.
- *
- * The order in memory is always (position, texture coords, color, coverage)
- * with any unused fields omitted.
- */
-
- /**
- * Generates a bit indicating that a texture stage uses texture coordinates
- *
- * @param stageIdx the stage that will use texture coordinates.
- *
- * @return the bit to add to a GrVertexLayout bitfield.
- */
- static int StageTexCoordVertexLayoutBit(int stageIdx) {
- GrAssert(stageIdx < kNumStages);
- return (1 << stageIdx);
- }
-
- static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
-
-private:
- // non-stage bits start at this index.
- static const int STAGE_BIT_CNT = kNumStages;
-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),
- /* Each vertex specificies an edge. Distance to the edge is used to
- * compute a coverage. See GrDrawState::setVertexEdgeType().
- */
- kEdge_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 2),
- // 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)));
-
- enum VertexLayout {
- kDefault_VertexLayout = 0
+ enum {
+ kVertexAttribCnt = 6,
};
- /**
- * Sets vertex layout for next draw.
+ /**
+ * 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).
*
- * @param layout the vertex layout to set.
+ * 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.
*/
- void setVertexLayout(GrVertexLayout layout) { fCommon.fVertexLayout = layout; }
-
- GrVertexLayout getVertexLayout() const { return fCommon.fVertexLayout; }
- size_t getVertexSize() const { return VertexSize(fCommon.fVertexLayout); }
-
-
- ////////////////////////////////////////////////////////////////////////////
- // 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 to compute the offset of texture coordinates in a vertex
- * @return offset of texture coordinates in vertex layout or 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.
- *
- * @param vertexLayout layout to query
+ * Sets vertex attributes for next draw.
*
- * @return true if vertex specifies texture coordinates,
- * false otherwise.
+ * @param attribs the array of vertex attributes to set.
+ * @param count the number of attributes being set.
+ * limited to a count of kVertexAttribCnt.
*/
- static bool VertexUsesTexCoords(GrVertexLayout vertexLayout);
+ void setVertexAttribs(const GrVertexAttrib attribs[], int count);
- /**
- * Helper function to compute the size of each vertex and the offsets of
- * texture coordinates and color.
- *
- * @param vertexLayout the layout to query
- * @param texCoordOffset after return it is the offset of the
- * tex coord index in the vertex or -1 if
- * tex coords aren'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 VertexSizeAndOffsets(GrVertexLayout vertexLayout,
- int *texCoordOffset,
- int *colorOffset,
- int *coverageOffset,
- int* edgeOffset);
+ const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
+ int getVertexAttribCount() const { return fVertexAttribs.count(); }
+
+ size_t getVertexSize() const;
/**
- * 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).
+ * Sets default vertex attributes for next draw.
*
- * @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
+ * This will also set default vertex attribute indices and bindings
*/
- static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
- int texCoordOffsetsByStage[kNumStages],
- int* colorOffset,
- int* coverageOffset,
- int* edgeOffset);
+ void setDefaultVertexAttribs();
- /**
- * Determines whether src alpha is guaranteed to be one for all src pixels
- */
- bool srcAlphaWillBeOne(GrVertexLayout) const;
+ ////////////////////////////////////////////////////////////////////////////
+ // Helpers for picking apart vertex attributes
- /**
- * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
- */
- bool hasSolidCoverage(GrVertexLayout) const;
+ // 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, texture coords, or colors, of a vertex within an
@@ -304,7 +197,7 @@ public:
/**
* Gets a pointer to a GrPoint of a vertex's position or texture
* coordinate.
- * @param vertices the vetex array
+ * @param vertices the vertex 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.
@@ -353,7 +246,140 @@ public:
vertexIndex * vertexSize);
}
- static void VertexLayoutUnitTest();
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @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. Each
+ * stage can use the explicit texture coordinates as its input texture
+ * coordinates or it may use the positions as texture coordinates.
+ */
+
+ /**
+ * Generates a bit indicating that a texture stage uses texture coordinates
+ *
+ * @param stageIdx the stage that will use texture coordinates.
+ *
+ * @return the bit to add to a GrAttribBindings bitfield.
+ */
+ static int ExplicitTexCoordAttribBindingsBit(int stageIdx) {
+ GrAssert(stageIdx < kNumStages);
+ return (1 << stageIdx);
+ }
+
+ static bool StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx);
+
+ /**
+ * Additional Bits that can be specified in GrAttribBindings.
+ */
+ enum AttribBindingsBits {
+ /* program uses colors (GrColor) */
+ kColor_AttribBindingsBit = 1 << (kNumStages + 0),
+ /* program uses coverage (GrColor)
+ */
+ kCoverage_AttribBindingsBit = 1 << (kNumStages + 1),
+ /* program uses edge data. Distance to the edge is used to
+ * compute a coverage. See GrDrawState::setVertexEdgeType().
+ */
+ kEdge_AttribBindingsBit = 1 << (kNumStages + 2),
+ // 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
+
+ /**
+ * Helper function to determine if program uses explicit texture
+ * coordinates.
+ *
+ * @param bindings attribute bindings to query
+ *
+ * @return true if program uses texture coordinates,
+ * false otherwise.
+ */
+ static bool AttributesBindExplicitTexCoords(GrAttribBindings bindings);
+
+ /**
+ * Determines whether src alpha is guaranteed to be one for all src pixels
+ */
+ bool srcAlphaWillBeOne(GrAttribBindings) const;
+
+ /**
+ * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
+ */
+ 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,
+ kEdge_AttribIndex,
+ kTexCoord_AttribIndex,
+
+ kLast_AttribIndex = kTexCoord_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]; }
/// @}
@@ -1004,7 +1030,7 @@ public:
/**
* Determines the interpretation per-vertex edge data when the
- * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
+ * kEdge_AttribBindingsBit is set (see GrDrawTarget). When per-vertex edges
* are not specified the value of this setting has no effect.
*/
void setVertexEdgeType(VertexEdgeType type) {
@@ -1159,13 +1185,25 @@ public:
return (NULL != fStages[s].getEffect());
}
- // Most stages are usually not used, so conditionals here
- // reduce the expected number of bytes touched by 50%.
bool operator ==(const GrDrawState& s) const {
if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
return false;
}
-
+ if (fVertexAttribs.count() != s.fVertexAttribs.count()) {
+ return false;
+ }
+ for (int i = 0; i < fVertexAttribs.count(); ++i) {
+ if (fVertexAttribs[i] != s.fVertexAttribs[i]) {
+ return false;
+ }
+ }
+ for (int i = 0; i < kAttribIndexCount; ++i) {
+ if ((i == kPosition_AttribIndex ||
+ s.fCommon.fAttribBindings & kAttribIndexMasks[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)) {
@@ -1182,6 +1220,10 @@ public:
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];
@@ -1196,7 +1238,7 @@ private:
struct CommonState {
// These fields are roughly sorted by decreasing likelihood of being different in op==
GrColor fColor;
- GrVertexLayout fVertexLayout;
+ GrAttribBindings fAttribBindings;
SkMatrix fViewMatrix;
GrBlendCoeff fSrcBlend;
GrBlendCoeff fDstBlend;
@@ -1211,7 +1253,7 @@ private:
DrawFace fDrawFace;
bool operator== (const CommonState& other) const {
return fColor == other.fColor &&
- fVertexLayout == other.fVertexLayout &&
+ fAttribBindings == other.fAttribBindings &&
fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
fSrcBlend == other.fSrcBlend &&
fDstBlend == other.fDstBlend &&
@@ -1256,6 +1298,10 @@ public:
// 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).
@@ -1269,6 +1315,10 @@ public:
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]);
}
@@ -1278,6 +1328,20 @@ public:
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.count() != state.fVertexAttribs.count()) {
+ return false;
+ }
+ for (int i = 0; i < fVertexAttribs.count(); ++i)
+ if (fVertexAttribs[i] != state.fVertexAttribs[i]) {
+ return false;
+ }
for (int i = 0; i < kNumStages; ++i) {
if (!fStages[i].isEqual(state.fStages[i])) {
return false;
@@ -1287,17 +1351,25 @@ public:
}
private:
- GrRenderTarget* fRenderTarget;
- CommonState fCommon;
- GrEffectStage::DeferredStage fStages[kNumStages];
+ GrRenderTarget* fRenderTarget;
+ CommonState fCommon;
+ int fAttribIndices[kAttribIndexCount];
+ GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
+ GrEffectStage::DeferredStage fStages[kNumStages];
GR_DEBUGCODE(bool fInitialized;)
};
private:
- SkAutoTUnref<GrRenderTarget> fRenderTarget;
- CommonState fCommon;
- GrEffectStage fStages[kNumStages];
+ // 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;
};