Add an opaqueness hint to GrDrawState.
Check it when deciding whether to combine draw states. R=egdaniel@google.com, robertphillips@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/446953002
This commit is contained in:
parent
6563562cb6
commit
62c447d3a5
@ -592,6 +592,9 @@ HAS_ATLAS:
|
||||
SkFixedToFloat(texture->normalizeFixedY(ty + height)),
|
||||
vertSize);
|
||||
if (useColorVerts) {
|
||||
if (0xFF == GrColorUnpackA(fPaint.getColor())) {
|
||||
fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
|
||||
}
|
||||
// color comes after position.
|
||||
GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
|
@ -1753,7 +1753,7 @@ GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint,
|
||||
fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get());
|
||||
#if GR_DEBUG_PARTIAL_COVERAGE_CHECK
|
||||
if ((paint->hasMask() || 0xff != paint->fCoverage) &&
|
||||
!fGpu->canApplyCoverage()) {
|
||||
!fDrawState->couldApplyCoverage(fGpu->caps())) {
|
||||
GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
|
||||
}
|
||||
#endif
|
||||
|
@ -421,6 +421,9 @@ HAS_ATLAS:
|
||||
SkFixedToFloat(texture->normalizeFixedY(ty + th)),
|
||||
vertSize);
|
||||
if (useColorVerts) {
|
||||
if (0xFF == GrColorUnpackA(fPaint.getColor())) {
|
||||
fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
|
||||
}
|
||||
// color comes after position.
|
||||
GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "GrDrawState.h"
|
||||
#include "GrPaint.h"
|
||||
#include "GrDrawTargetCaps.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////s
|
||||
|
||||
@ -34,7 +35,7 @@ bool GrDrawState::State::HaveCompatibleState(const State& a, const State& b,
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////s
|
||||
GrDrawState::CombinedState GrDrawState::CombineIfPossible(
|
||||
const GrDrawState& a, const GrDrawState& b) {
|
||||
const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) {
|
||||
|
||||
bool usingVertexColors = a.hasColorVertexAttribute();
|
||||
if (!usingVertexColors && a.fColor != b.fColor) {
|
||||
@ -65,10 +66,35 @@ GrDrawState::CombinedState GrDrawState::CombineIfPossible(
|
||||
if (!State::HaveCompatibleState(a.fState, b.fState, explicitLocalCoords)) {
|
||||
return kIncompatible_CombinedState;
|
||||
}
|
||||
|
||||
if (usingVertexColors) {
|
||||
// If one is opaque and the other is not then the combined state is not opaque. Moreover,
|
||||
// if the opaqueness affects the ability to get color/coverage blending correct then we
|
||||
// don't combine the draw states.
|
||||
bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints);
|
||||
bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints);
|
||||
if (aIsOpaque != bIsOpaque) {
|
||||
const GrDrawState* opaque;
|
||||
const GrDrawState* nonOpaque;
|
||||
if (aIsOpaque) {
|
||||
opaque = &a;
|
||||
nonOpaque = &b;
|
||||
} else {
|
||||
opaque = &b;
|
||||
nonOpaque = &a;
|
||||
}
|
||||
if (!opaque->hasSolidCoverage() && opaque->couldApplyCoverage(caps)) {
|
||||
SkASSERT(!nonOpaque->hasSolidCoverage());
|
||||
if (!nonOpaque->couldApplyCoverage(caps)) {
|
||||
return kIncompatible_CombinedState;
|
||||
}
|
||||
}
|
||||
return aIsOpaque ? kB_CombinedState : kA_CombinedState;
|
||||
}
|
||||
}
|
||||
return kAOrB_CombinedState;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////s
|
||||
|
||||
GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
|
||||
@ -102,6 +128,7 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
|
||||
fBlendOptFlags = that.fBlendOptFlags;
|
||||
|
||||
fState = that.fState;
|
||||
fHints = that.fHints;
|
||||
|
||||
memcpy(fFixedFunctionVertexAttribIndices,
|
||||
that.fFixedFunctionVertexAttribIndices,
|
||||
@ -129,6 +156,8 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
|
||||
fCoverage = 0xffffffff;
|
||||
fDrawFace = kBoth_DrawFace;
|
||||
|
||||
fHints = 0;
|
||||
|
||||
this->invalidateBlendOptFlags();
|
||||
}
|
||||
|
||||
@ -172,6 +201,7 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
|
||||
fDrawFace = kBoth_DrawFace;
|
||||
fStencilSettings.setDisabled();
|
||||
this->resetStateFlags();
|
||||
fHints = 0;
|
||||
|
||||
// Enable the clip bit
|
||||
this->enableState(GrDrawState::kClip_StateBit);
|
||||
@ -326,13 +356,33 @@ bool GrDrawState::willEffectReadDstColor() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
|
||||
if (caps.dualSourceBlendingSupport()) {
|
||||
return true;
|
||||
}
|
||||
// we can correctly apply coverage if a) we have dual source blending
|
||||
// or b) one of our blend optimizations applies
|
||||
// or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
|
||||
GrBlendCoeff srcCoeff;
|
||||
GrBlendCoeff dstCoeff;
|
||||
GrDrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff);
|
||||
return GrDrawState::kNone_BlendOpt != flag ||
|
||||
(this->willEffectReadDstColor() &&
|
||||
kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
|
||||
}
|
||||
|
||||
bool GrDrawState::srcAlphaWillBeOne() const {
|
||||
uint32_t validComponentFlags;
|
||||
GrColor color;
|
||||
// Check if per-vertex or constant color may have partial alpha
|
||||
if (this->hasColorVertexAttribute()) {
|
||||
validComponentFlags = 0;
|
||||
color = 0; // not strictly necessary but we get false alarms from tools about uninit.
|
||||
if (fHints & kVertexColorsAreOpaque_Hint) {
|
||||
validComponentFlags = kA_GrColorComponentFlag;
|
||||
color = 0xFF << GrColor_SHIFT_A;
|
||||
} else {
|
||||
validComponentFlags = 0;
|
||||
color = 0; // not strictly necessary but we get false alarms from tools about uninit.
|
||||
}
|
||||
} else {
|
||||
validComponentFlags = kRGBA_GrColorComponentFlags;
|
||||
color = this->getColor();
|
||||
@ -455,13 +505,10 @@ GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage,
|
||||
bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
|
||||
(kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
|
||||
|
||||
bool covIsZero = !this->isCoverageDrawing() &&
|
||||
!this->hasCoverageVertexAttribute() &&
|
||||
0 == this->getCoverageColor();
|
||||
// When coeffs are (0,1) there is no reason to draw at all, unless
|
||||
// stenciling is enabled. Having color writes disabled is effectively
|
||||
// (0,1). The same applies when coverage is known to be 0.
|
||||
if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
|
||||
// (0,1).
|
||||
if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) {
|
||||
if (this->getStencil().doesWrite()) {
|
||||
return kEmitCoverage_BlendOptFlag;
|
||||
} else {
|
||||
@ -469,11 +516,7 @@ GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage,
|
||||
}
|
||||
}
|
||||
|
||||
// check for coverage due to constant coverage, per-vertex coverage, or coverage stage
|
||||
bool hasCoverage = forceCoverage ||
|
||||
0xffffffff != this->getCoverageColor() ||
|
||||
this->hasCoverageVertexAttribute() ||
|
||||
this->numCoverageStages() > 0;
|
||||
bool hasCoverage = forceCoverage || !this->hasSolidCoverage();
|
||||
|
||||
// if we don't have coverage we can check whether the dst
|
||||
// has to read at all. If not, we'll disable blending.
|
||||
|
@ -8,21 +8,18 @@
|
||||
#ifndef GrDrawState_DEFINED
|
||||
#define GrDrawState_DEFINED
|
||||
|
||||
#include "GrBackendEffectFactory.h"
|
||||
#include "GrBlend.h"
|
||||
#include "GrColor.h"
|
||||
#include "GrEffectStage.h"
|
||||
#include "GrPaint.h"
|
||||
#include "GrRenderTarget.h"
|
||||
#include "GrStencil.h"
|
||||
#include "GrTemplates.h"
|
||||
#include "GrTexture.h"
|
||||
#include "GrTypesPriv.h"
|
||||
#include "effects/GrSimpleTextureEffect.h"
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkTypes.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class GrDrawTargetCaps;
|
||||
class GrPaint;
|
||||
class GrRenderTarget;
|
||||
class GrTexture;
|
||||
|
||||
class GrDrawState : public SkRefCnt {
|
||||
public:
|
||||
@ -161,6 +158,18 @@ public:
|
||||
*/
|
||||
bool hasSolidCoverage() const;
|
||||
|
||||
/**
|
||||
* Depending on features available in the underlying 3D API and the color blend mode requested
|
||||
* it may or may not be possible to correctly blend with fractional pixel coverage generated by
|
||||
* the fragment shader.
|
||||
*
|
||||
* This function considers the current draw state and the draw target's capabilities to
|
||||
* determine whether coverage can be handled correctly. This function assumes that the caller
|
||||
* intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
|
||||
* attribute, or a coverage effect) but may not have specified it yet.
|
||||
*/
|
||||
bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -185,9 +194,7 @@ public:
|
||||
*
|
||||
* @param alpha The alpha value to set as the color.
|
||||
*/
|
||||
void setAlpha(uint8_t a) {
|
||||
this->setColor((a << 24) | (a << 16) | (a << 8) | a);
|
||||
}
|
||||
void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
|
||||
|
||||
/// @}
|
||||
|
||||
@ -205,13 +212,9 @@ public:
|
||||
this->invalidateBlendOptFlags();
|
||||
}
|
||||
|
||||
uint8_t getCoverage() const {
|
||||
return GrColorUnpackR(fCoverage);
|
||||
}
|
||||
uint8_t getCoverage() const { return GrColorUnpackR(fCoverage); }
|
||||
|
||||
GrColor getCoverageColor() const {
|
||||
return fCoverage;
|
||||
}
|
||||
GrColor getCoverageColor() const { return fCoverage; }
|
||||
|
||||
/// @}
|
||||
|
||||
@ -561,9 +564,7 @@ public:
|
||||
*
|
||||
* @param target The render target to set.
|
||||
*/
|
||||
void setRenderTarget(GrRenderTarget* target) {
|
||||
fRenderTarget.reset(SkSafeRef(target));
|
||||
}
|
||||
void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
|
||||
|
||||
/**
|
||||
* Retrieves the currently set render-target.
|
||||
@ -722,29 +723,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool isDitherState() const {
|
||||
return 0 != (fFlagBits & kDither_StateBit);
|
||||
}
|
||||
bool isStateFlagEnabled(uint32_t stateBit) const { return 0 != (stateBit & fFlagBits); }
|
||||
|
||||
bool isHWAntialiasState() const {
|
||||
return 0 != (fFlagBits & kHWAntialias_StateBit);
|
||||
}
|
||||
|
||||
bool isClipState() const {
|
||||
return 0 != (fFlagBits & kClip_StateBit);
|
||||
}
|
||||
|
||||
bool isColorWriteDisabled() const {
|
||||
return 0 != (fFlagBits & kNoColorWrites_StateBit);
|
||||
}
|
||||
|
||||
bool isCoverageDrawing() const {
|
||||
return 0 != (fFlagBits & kCoverageDrawing_StateBit);
|
||||
}
|
||||
|
||||
bool isStateFlagEnabled(uint32_t stateBit) const {
|
||||
return 0 != (stateBit & fFlagBits);
|
||||
}
|
||||
bool isDitherState() const { return 0 != (fFlagBits & kDither_StateBit); }
|
||||
bool isHWAntialiasState() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
|
||||
bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
|
||||
bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
|
||||
bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
|
||||
|
||||
/// @}
|
||||
|
||||
@ -778,6 +763,17 @@ public:
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// @name Hints
|
||||
/// Hints that when provided can enable optimizations.
|
||||
////
|
||||
|
||||
enum Hints { kVertexColorsAreOpaque_Hint = 0x1, };
|
||||
|
||||
void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Return type for CombineIfPossible. */
|
||||
@ -796,7 +792,8 @@ public:
|
||||
a single GrDrawState. This is used to avoid storing redundant GrDrawStates and to determine
|
||||
if draws can be batched. The return value indicates whether combining is possible and, if
|
||||
so, which of the two inputs should be used. */
|
||||
static CombinedState CombineIfPossible(const GrDrawState& a, const GrDrawState& b);
|
||||
static CombinedState CombineIfPossible(const GrDrawState& a, const GrDrawState& b,
|
||||
const GrDrawTargetCaps& caps);
|
||||
|
||||
GrDrawState& operator= (const GrDrawState& that);
|
||||
|
||||
@ -804,8 +801,8 @@ private:
|
||||
void onReset(const SkMatrix* initialViewMatrix);
|
||||
|
||||
BlendOptFlags calcBlendOpts(bool forceCoverage = false,
|
||||
GrBlendCoeff* srcCoeff = NULL,
|
||||
GrBlendCoeff* dstCoeff = NULL) const;
|
||||
GrBlendCoeff* srcCoeff = NULL,
|
||||
GrBlendCoeff* dstCoeff = NULL) const;
|
||||
|
||||
// These fields are roughly sorted by decreasing likelihood of being different in op==
|
||||
SkAutoTUnref<GrRenderTarget> fRenderTarget;
|
||||
@ -820,10 +817,12 @@ private:
|
||||
DrawFace fDrawFace;
|
||||
|
||||
State fState;
|
||||
|
||||
uint32_t fHints;
|
||||
|
||||
mutable GrBlendCoeff fOptSrcBlend;
|
||||
mutable GrBlendCoeff fOptDstBlend;
|
||||
mutable BlendOptFlags fBlendOptFlags;
|
||||
mutable GrBlendCoeff fOptSrcBlend;
|
||||
mutable GrBlendCoeff fOptDstBlend;
|
||||
mutable BlendOptFlags fBlendOptFlags;
|
||||
|
||||
// This is simply a different representation of info in fVertexAttribs and thus does
|
||||
// not need to be compared in op==.
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "GrDrawTargetCaps.h"
|
||||
#include "GrPath.h"
|
||||
#include "GrRenderTarget.h"
|
||||
#include "GrTemplates.h"
|
||||
#include "GrTexture.h"
|
||||
#include "GrVertexBuffer.h"
|
||||
|
||||
@ -613,21 +614,6 @@ void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrDrawTarget::canApplyCoverage() const {
|
||||
// we can correctly apply coverage if a) we have dual source blending
|
||||
// or b) one of our blend optimizations applies
|
||||
// or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
|
||||
GrBlendCoeff srcCoeff;
|
||||
GrBlendCoeff dstCoeff;
|
||||
GrDrawState::BlendOptFlags flag = this->getDrawState().getBlendOpts(true, &srcCoeff, &dstCoeff);
|
||||
return this->caps()->dualSourceBlendingSupport() ||
|
||||
GrDrawState::kNone_BlendOpt != flag ||
|
||||
(this->getDrawState().willEffectReadDstColor() &&
|
||||
kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
|
||||
int instanceCount,
|
||||
int verticesPerInstance,
|
||||
|
@ -84,32 +84,13 @@ public:
|
||||
*/
|
||||
GrDrawState* drawState() { return fDrawState; }
|
||||
|
||||
/**
|
||||
* Color alpha and coverage are two inputs to the drawing pipeline. For some
|
||||
* blend modes it is safe to fold the coverage into constant or per-vertex
|
||||
* color alpha value. For other blend modes they must be handled separately.
|
||||
* Depending on features available in the underlying 3D API this may or may
|
||||
* not be possible.
|
||||
*
|
||||
* This function considers the current draw state and the draw target's
|
||||
* capabilities to determine whether coverage can be handled correctly. The
|
||||
* following assumptions are made:
|
||||
* 1. The caller intends to somehow specify coverage. This can be
|
||||
* specified either by enabling a coverage stage on the GrDrawState or
|
||||
* via the vertex layout.
|
||||
* 2. Other than enabling coverage stages or enabling coverage in the
|
||||
* layout, the current configuration of the target's GrDrawState is as
|
||||
* it will be at draw time.
|
||||
*/
|
||||
bool canApplyCoverage() const;
|
||||
|
||||
/** When we're using coverage AA but the blend is incompatible (given gpu
|
||||
* limitations) we should disable AA. */
|
||||
bool shouldDisableCoverageAAForBlend() {
|
||||
bool shouldDisableCoverageAAForBlend() const {
|
||||
// Enable below if we should draw with AA even when it produces
|
||||
// incorrect blending.
|
||||
// return false;
|
||||
return !this->canApplyCoverage();
|
||||
return !this->getDrawState().couldApplyCoverage(*this->caps());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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},
|
||||
};
|
||||
|
||||
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);
|
||||
} else {
|
||||
drawState->setVertexAttribs<kRectPosUVAttribs>(1);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
/** 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.
|
||||
|
||||
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<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);
|
||||
|
Loading…
Reference in New Issue
Block a user