Index: src/gpu/GrInOrderDrawBuffer.cpp |
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp |
index 954437c933cc915bbc8fa359c7feaf63397bbba9..6d0bbd11c0c023e2ce4c12c93aefe2b9636cd1d0 100644 |
--- a/src/gpu/GrInOrderDrawBuffer.cpp |
+++ b/src/gpu/GrInOrderDrawBuffer.cpp |
@@ -78,63 +78,44 @@ void get_vertex_bounds(const void* vertices, |
namespace { |
-extern const GrVertexAttrib kRectPosColorUVAttribs[] = { |
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, |
- {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding}, |
- {kVec2f_GrVertexAttribType, sizeof(SkPoint)+sizeof(GrColor), |
- kLocalCoord_GrVertexAttribBinding}, |
+extern const GrVertexAttrib kRectAttribs[] = { |
+ {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, |
+ {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding}, |
+ {kVec2f_GrVertexAttribType, sizeof(SkPoint)+sizeof(GrColor), kLocalCoord_GrVertexAttribBinding}, |
}; |
+} |
-extern const GrVertexAttrib kRectPosUVAttribs[] = { |
- {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, |
- {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding}, |
-}; |
+/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we |
+ have explicit local coords and sometimes not. We *could* always provide explicit local coords |
+ and just duplicate the positions when the caller hasn't provided a local coord rect, but we |
+ haven't seen a use case which frequently switches between local rect and no local rect draws. |
+ |
+ The color param is used to determine whether the opaque hint can be set on the draw state. |
+ The caller must populate the vertex colors itself. |
-static void set_vertex_attributes(GrDrawState* drawState, |
- bool hasColor, bool hasUVs, |
- int* colorOffset, int* localOffset) { |
- *colorOffset = -1; |
- *localOffset = -1; |
- |
- // Using per-vertex colors allows batching across colors. (A lot of rects in a row differing |
- // only in color is a common occurrence in tables). However, having per-vertex colors disables |
- // blending optimizations because we don't know if the color will be solid or not. These |
- // optimizations help determine whether coverage and color can be blended correctly when |
- // dual-source blending isn't available. This comes into play when there is coverage. If colors |
- // were a stage it could take a hint that every vertex's color will be opaque. |
- if (hasColor && hasUVs) { |
- *colorOffset = sizeof(SkPoint); |
- *localOffset = sizeof(SkPoint) + sizeof(GrColor); |
- drawState->setVertexAttribs<kRectPosColorUVAttribs>(3); |
- } else if (hasColor) { |
- *colorOffset = sizeof(SkPoint); |
- drawState->setVertexAttribs<kRectPosColorUVAttribs>(2); |
- } else if (hasUVs) { |
- *localOffset = sizeof(SkPoint); |
- drawState->setVertexAttribs<kRectPosUVAttribs>(2); |
+ The vertex attrib order is always pos, color, [local coords]. |
+ */ |
+static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, GrColor color) { |
+ if (hasLocalCoords) { |
+ drawState->setVertexAttribs<kRectAttribs>(3); |
} else { |
- drawState->setVertexAttribs<kRectPosUVAttribs>(1); |
+ drawState->setVertexAttribs<kRectAttribs>(2); |
+ } |
+ if (0xFF == GrColorUnpackA(color)) { |
+ drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); |
} |
} |
-}; |
- |
enum { |
kTraceCmdBit = 0x80, |
kCmdMask = 0x7f, |
}; |
-static uint8_t add_trace_bit(uint8_t cmd) { |
- return cmd | kTraceCmdBit; |
-} |
+static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } |
-static uint8_t strip_trace_bit(uint8_t cmd) { |
- return cmd & kCmdMask; |
-} |
+static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } |
-static bool cmd_has_trace_marker(uint8_t cmd) { |
- return SkToBool(cmd & kTraceCmdBit); |
-} |
+static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); } |
void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect, |
const SkRect* localRect, |
@@ -143,11 +124,7 @@ void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect, |
GrColor color = drawState->getColor(); |
- int colorOffset, localOffset; |
- set_vertex_attributes(drawState, |
- this->caps()->dualSourceBlendingSupport() || drawState->hasSolidCoverage(), |
- NULL != localRect, |
- &colorOffset, &localOffset); |
+ set_vertex_attributes(drawState, NULL != localRect, color); |
AutoReleaseGeometry geo(this, 4, 0); |
if (!geo.succeeded()) { |
@@ -176,22 +153,22 @@ void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect, |
// unnecessary clipping in our onDraw(). |
get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds); |
- if (localOffset >= 0) { |
- SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + localOffset); |
+ if (NULL != localRect) { |
+ static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); |
+ SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset); |
coords->setRectFan(localRect->fLeft, localRect->fTop, |
localRect->fRight, localRect->fBottom, |
- vsize); |
+ vsize); |
if (NULL != localMatrix) { |
localMatrix->mapPointsWithStride(coords, vsize, 4); |
} |
} |
- if (colorOffset >= 0) { |
- GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + colorOffset); |
- for (int i = 0; i < 4; ++i) { |
- *vertColor = color; |
- vertColor = (GrColor*) ((intptr_t) vertColor + vsize); |
- } |
+ static const int kColorOffset = sizeof(SkPoint); |
+ GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + kColorOffset); |
+ for (int i = 0; i < 4; ++i) { |
+ *vertColor = color; |
+ vertColor = (GrColor*) ((intptr_t) vertColor + vsize); |
} |
this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); |
@@ -909,7 +886,7 @@ void GrInOrderDrawBuffer::recordStateIfNecessary() { |
} |
const GrDrawState& curr = this->getDrawState(); |
GrDrawState& prev = fStates.back(); |
- switch (GrDrawState::CombineIfPossible(prev, curr)) { |
+ switch (GrDrawState::CombineIfPossible(prev, curr, *this->caps())) { |
case GrDrawState::kIncompatible_CombinedState: |
fStates.push_back() = this->getDrawState(); |
this->addToCmdBuffer(kSetState_Cmd); |