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
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
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;
*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 ||
kNone_BlendOpt != this->getBlendOpts(true);
}
-bool GrDrawTarget::drawWillReadDst() const {
- return SkToBool((kDisableBlend_BlendOptFlag | kSkipDraw_BlendOptFlag) &
- this->getBlendOpts());
-}
-
////////////////////////////////////////////////////////////////////////////////
void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
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
* 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;
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
}
bool isStageEnabled(int stage) const {
- return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout,
+ return StageWillBeUsed(stage, this->getVertexLayout(),
this->getDrawState());
}
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;
#if GR_DEBUG
bool success =
#endif
- fVertexPool->appendVertices(this->getGeomSrc().fVertexLayout,
+ fVertexPool->appendVertices(this->getVertexLayout(),
vertexCount,
vertexArray,
&geomPoolState.fPoolVertexBuffer,
this->pushState();
}
- draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+ draw.fVertexLayout = this->getVertexLayout();
switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
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;
this->pushState();
}
- draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+ draw.fVertexLayout = this->getVertexLayout();
switch (this->getGeomSrc().fVertexSrc) {
case kBuffer_GeometrySrcType:
draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
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;
#if GR_DEBUG
bool success =
#endif
- fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
+ fVertexPool.appendVertices(this->getVertexLayout(),
vertexCount,
vertexArray,
&poolState.fPoolVertexBuffer,
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);
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);
int newTexCoordOffsets[GrDrawState::kMaxTexCoords];
int newEdgeOffset;
+ GrVertexLayout currLayout = this->getVertexLayout();
+
GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
- this->getGeomSrc().fVertexLayout,
+ currLayout,
newTexCoordOffsets,
&newColorOffset,
&newCoverageOffset,
GrGLenum scalarType;
bool texCoordNorm;
- if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
+ if (currLayout & kTextFormat_VertexLayoutBit) {
scalarType = GrGLTextType;
texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
} else {
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();
GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
}
- fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
+ fHWGeometryState.fVertexLayout = currLayout;
fHWGeometryState.fArrayPtrsDirty = false;
}
// 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;