Don't look at current vertex layout when vertex source hasn't been set

Review URL: http://codereview.appspot.com/5959047



git-svn-id: http://skia.googlecode.com/svn/trunk@3545 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-03-29 19:07:12 +00:00
parent 257fc5bd13
commit e79c815bca
6 changed files with 65 additions and 47 deletions

View File

@ -1943,10 +1943,9 @@ void GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) {
drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
drawState->setCoverage(paint.fCoverage);
#if 0 // this code is broken. canApplyCoverage incorrectly looks at the
// the vertex layout when the vertex src hasn't been set yet
if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) {
#if GR_DEBUG
if ((paint.getActiveMaskStageMask() || 0xff != paint.fCoverage) &&
!target->canApplyCoverage()) {
GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
}
#endif

View File

@ -853,9 +853,7 @@ bool GrDrawTarget::canTweakAlphaForCoverage() const {
kISC_BlendCoeff == dstCoeff;
}
bool GrDrawTarget::srcAlphaWillBeOne() const {
const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout;
bool GrDrawTarget::srcAlphaWillBeOne(GrVertexLayout layout) const {
const GrDrawState& drawState = this->getDrawState();
// Check if per-vertex or constant color may have partial alpha
@ -882,12 +880,28 @@ bool GrDrawTarget::srcAlphaWillBeOne() const {
return true;
}
namespace {
GrVertexLayout default_blend_opts_vertex_layout() {
GrVertexLayout layout = 0;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
}
return layout;
}
}
GrDrawTarget::BlendOptFlags
GrDrawTarget::getBlendOpts(bool forceCoverage,
GrBlendCoeff* srcCoeff,
GrBlendCoeff* dstCoeff) const {
const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout;
GrVertexLayout layout;
if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
layout = default_blend_opts_vertex_layout();
} else {
layout = this->getVertexLayout();
}
const GrDrawState& drawState = this->getDrawState();
GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
@ -917,7 +931,7 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
*dstCoeff = kOne_BlendCoeff;
}
bool srcAIsOne = this->srcAlphaWillBeOne();
bool srcAIsOne = this->srcAlphaWillBeOne(layout);
bool dstCoeffIsOne = kOne_BlendCoeff == *dstCoeff ||
(kSA_BlendCoeff == *dstCoeff && srcAIsOne);
bool dstCoeffIsZero = kZero_BlendCoeff == *dstCoeff ||
@ -1022,11 +1036,6 @@ bool GrDrawTarget::canApplyCoverage() const {
kNone_BlendOpt != this->getBlendOpts(true);
}
bool GrDrawTarget::drawWillReadDst() const {
return SkToBool((kDisableBlend_BlendOptFlag | kSkipDraw_BlendOptFlag) &
this->getBlendOpts());
}
////////////////////////////////////////////////////////////////////////////////
void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,

View File

@ -116,15 +116,6 @@ public:
this->drawState()->preConcatSamplerMatrices(stageMask, matrix);
}
/**
* Determines if blending will require a read of a dst given the current
* state set on the draw target
*
* @return true if the dst surface will be read at each pixel hit by the
* a draw operation.
*/
bool drawWillReadDst() const;
/**
* 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
@ -132,23 +123,33 @@ public:
* Depending on features available in the underlying 3D API this may or may
* not be possible.
*
* This function looks at the current blend on the draw target and the draw
* target's capabilities to determine whether coverage can be handled
* correctly.
* 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, the current configuration of
* the target's GrDrawState is as it will be at draw time.
* 3. If a vertex source has not yet been specified then all stages with
* non-NULL textures will be referenced by the vertex layout.
*/
bool canApplyCoverage() const;
/**
* Determines whether incorporating partial pixel coverage into the constant
* color specified by setColor or per-vertex colors will give the right
* blending result.
* blending result. If a vertex source has not yet been specified then
* the function assumes that all stages with non-NULL textures will be
* referenced by the vertex layout.
*/
bool canTweakAlphaForCoverage() const;
/**
* Given the current draw state, vertex layout, and hw support, will HW AA
* lines be used (if line primitive type is drawn)? (Note that lines are
* always 1 pixel wide)
* Given the current draw state and hw support, will HW AA lines be used
* (if line primitive type is drawn)? If a vertex source has not yet been
* specified then the function assumes that all stages with non-NULL
* textures will be referenced by the vertex layout.
*/
bool willUseHWAALines() const;
@ -925,7 +926,7 @@ protected:
GrBlendCoeff* dstCoeff = NULL) const;
// determine if src alpha is guaranteed to be one for all src pixels
bool srcAlphaWillBeOne() const;
bool srcAlphaWillBeOne(GrVertexLayout vertexLayout) const;
enum GeometrySrcType {
kNone_GeometrySrcType, //<! src has not been specified
@ -977,7 +978,7 @@ protected:
}
bool isStageEnabled(int stage) const {
return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout,
return StageWillBeUsed(stage, this->getVertexLayout(),
this->getDrawState());
}
@ -1050,10 +1051,18 @@ protected:
GrVertexLayout layout,
void* vertices);
// accessor for derived classes
// accessors for derived classes
const GeometrySrcState& getGeomSrc() const {
return fGeoSrcStateStack.back();
}
// it is prefereable to call this rather than getGeomSrc()->fVertexLayout
// because of the assert.
GrVertexLayout getVertexLayout() const {
// the vertex layout is only valid if a vertex source has been
// specified.
GrAssert(this->getGeomSrc().fVertexSrc != kNone_GeometrySrcType);
return this->getGeomSrc().fVertexLayout;
}
GrClip fClip;

View File

@ -911,7 +911,7 @@ void GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
#if GR_DEBUG
bool success =
#endif
fVertexPool->appendVertices(this->getGeomSrc().fVertexLayout,
fVertexPool->appendVertices(this->getVertexLayout(),
vertexCount,
vertexArray,
&geomPoolState.fPoolVertexBuffer,

View File

@ -356,7 +356,7 @@ void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
this->pushState();
}
draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
draw.fVertexLayout = this->getVertexLayout();
switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
@ -364,7 +364,7 @@ void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
case kReserved_GeometrySrcType: // fallthrough
case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
VertexSize(this->getGeomSrc().fVertexLayout);
VertexSize(draw.fVertexLayout);
poolState.fUsedPoolVertexBytes =
GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
draw.fVertexBuffer = poolState.fPoolVertexBuffer;
@ -423,7 +423,7 @@ void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
this->pushState();
}
draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
draw.fVertexLayout = this->getVertexLayout();
switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
@ -431,7 +431,7 @@ void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
case kReserved_GeometrySrcType: // fallthrough
case kArray_GeometrySrcType: {
size_t vertexBytes = (vertexCount + startVertex) *
VertexSize(this->getGeomSrc().fVertexLayout);
VertexSize(draw.fVertexLayout);
poolState.fUsedPoolVertexBytes =
GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
draw.fVertexBuffer = poolState.fPoolVertexBuffer;
@ -706,7 +706,7 @@ void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
#if GR_DEBUG
bool success =
#endif
fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
fVertexPool.appendVertices(this->getVertexLayout(),
vertexCount,
vertexArray,
&poolState.fPoolVertexBuffer,

View File

@ -661,7 +661,7 @@ void GrGpuGLShaders::flushColor(GrColor color) {
const ProgramDesc& desc = fCurrentProgram.getDesc();
const GrDrawState& drawState = this->getDrawState();
if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
if (this->getVertexLayout() & kColor_VertexLayoutBit) {
// color will be specified per-vertex as an attribute
// invalidate the const vertex attrib color
fHWDrawState.setColor(GrColor_ILLEGAL);
@ -711,7 +711,7 @@ void GrGpuGLShaders::flushCoverage(GrColor coverage) {
const GrDrawState& drawState = this->getDrawState();
if (this->getGeomSrc().fVertexLayout & kCoverage_VertexLayoutBit) {
if (this->getVertexLayout() & kCoverage_VertexLayoutBit) {
// coverage will be specified per-vertex as an attribute
// invalidate the const vertex attrib coverage
fHWDrawState.setCoverage4(GrColor_ILLEGAL);
@ -833,8 +833,10 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
int newTexCoordOffsets[GrDrawState::kMaxTexCoords];
int newEdgeOffset;
GrVertexLayout currLayout = this->getVertexLayout();
GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
this->getGeomSrc().fVertexLayout,
currLayout,
newTexCoordOffsets,
&newColorOffset,
&newCoverageOffset,
@ -858,7 +860,7 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
GrGLenum scalarType;
bool texCoordNorm;
if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
if (currLayout & kTextFormat_VertexLayoutBit) {
scalarType = GrGLTextType;
texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
} else {
@ -882,8 +884,7 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
bool posAndTexChange = allOffsetsChange ||
(((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
(kTextFormat_VertexLayoutBit &
(fHWGeometryState.fVertexLayout ^
this->getGeomSrc().fVertexLayout)));
(fHWGeometryState.fVertexLayout ^ currLayout)));
if (posAndTexChange) {
int idx = GrGLProgram::PositionAttributeIdx();
@ -955,7 +956,7 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
}
fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
fHWGeometryState.fVertexLayout = currLayout;
fHWGeometryState.fArrayPtrsDirty = false;
}
@ -979,7 +980,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
// to a canonical value to avoid duplicate programs with different keys.
// Must initialize all fields or cache will have false negatives!
desc.fVertexLayout = this->getGeomSrc().fVertexLayout;
desc.fVertexLayout = this->getVertexLayout();
desc.fEmitsPointSize = kPoints_PrimitiveType == type;