Add xp optimization for RGB coverage.

This is needed since clearColorStages is being changed to ignore color input. For RGB coverage,
we want to clear all the color stages (since we know the final output color), but we don't want
to ignore the color input since it is needed.

In future we will change this so the XP stores the color internally and thus can tell the GP to
simiply ignore color.

BUG=skia:

Review URL: https://codereview.chromium.org/791933006
This commit is contained in:
egdaniel 2014-12-15 12:38:53 -08:00 committed by Commit bot
parent 5bcbe91304
commit 54160f3286
3 changed files with 40 additions and 32 deletions

View File

@ -65,10 +65,14 @@ public:
* Clear coverage stages, remove coverage vertex attribs, and use input coverage
*/
kClearCoverageStages_OptFlag = 0x4,
/**
* Clear color stages and override input color to that returned by getOptimizations
*/
kOverrideColor_OptFlag = 0x8,
/**
* Set CoverageDrawing_StateBit
*/
kSetCoverageDrawing_OptFlag = 0x8,
kSetCoverageDrawing_OptFlag = 0x10,
};
GR_DECL_BITFIELD_OPS_FRIENDS(OptFlags);
@ -76,10 +80,11 @@ public:
/**
* Determines which optimizations (as described by the ptFlags above) can be performed by
* the draw with this xfer processor. If this function is called, the xfer processor may change
* its state to reflected the given blend optimizations. It will also set the output parameters,
* color and coverage, to specific values if it decides to remove all color or coverage stages.
* its state to reflected the given blend optimizations. If the XP needs to see a specific input
* color to blend correctly, it will set the OverrideColor flag and the output parameter
* overrideColor will be the required value that should be passed into the XP.
* A caller who calls this function on a XP is required to honor the returned OptFlags
* and color/coverage values for its draw.
* and color values for its draw.
*/
// TODO: remove need for isCoverageDrawing once coverageDrawing is its own XP.
// TODO: remove need for colorWriteDisabled once colorWriteDisabled is its own XP.
@ -88,8 +93,8 @@ public:
bool isCoverageDrawing,
bool colorWriteDisabled,
bool doesStencilWrite,
GrColor* color,
uint8_t* coverage,
GrColor* overrideColor,
uint8_t* overrideCoverage,
const GrDrawTargetCaps& caps) = 0;
struct BlendInfo {

View File

@ -157,7 +157,8 @@ void GrOptDrawState::adjustProgramFromOptimizations(const GrDrawState& ds,
fDescInfo.fReadsDst = false;
fDescInfo.fReadsFragPosition = false;
if (flags & GrXferProcessor::kClearColorStages_OptFlag) {
if (flags & GrXferProcessor::kClearColorStages_OptFlag ||
flags & GrXferProcessor::kOverrideColor_OptFlag) {
fDescInfo.fInputColorIsUsed = true;
*firstColorStageIdx = ds.numColorStages();
fDescInfo.fHasVertexColor = false;

View File

@ -121,16 +121,28 @@ GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
bool isCoverageDrawing,
bool colorWriteDisabled,
bool doesStencilWrite,
GrColor* color, uint8_t* coverage,
GrColor* overrideColor,
uint8_t* overrideCoverage,
const GrDrawTargetCaps& caps) {
GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI,
coveragePOI,
isCoverageDrawing,
colorWriteDisabled,
doesStencilWrite,
color,
coverage);
GrXferProcessor::OptFlags optFlags;
// Optimizations when doing RGB Coverage
if (coveragePOI.isFourChannelOutput()) {
// We want to force our primary output to be alpha * Coverage, where alpha is the alpha
// value of the blend the constant. We should already have valid blend coeff's if we are at
// a point where we have RGB coverage. We don't need any color stages since the known color
// output is already baked into the blendConstant.
uint8_t alpha = GrColorUnpackA(fBlendConstant);
*overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
optFlags = GrXferProcessor::kOverrideColor_OptFlag;
} else {
optFlags = this->internalGetOptimizations(colorPOI,
coveragePOI,
isCoverageDrawing,
colorWriteDisabled,
doesStencilWrite,
overrideColor,
overrideCoverage);
}
this->calcOutputTypes(optFlags, caps, isCoverageDrawing || coveragePOI.isSolidWhite(),
colorPOI.readsDst() || coveragePOI.readsDst());
return optFlags;
@ -172,7 +184,8 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
bool isCoverageDrawing,
bool colorWriteDisabled,
bool doesStencilWrite,
GrColor* color, uint8_t* coverage) {
GrColor* overrideColor,
uint8_t* overrideCoverage) {
if (colorWriteDisabled) {
fSrcBlend = kZero_GrBlendCoeff;
fDstBlend = kOne_GrBlendCoeff;
@ -193,23 +206,12 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend ||
(kISA_GrBlendCoeff == fDstBlend && srcAIsOne);
// Optimizations when doing RGB Coverage
if (coveragePOI.isFourChannelOutput()) {
// We want to force our primary output to be alpha * Coverage, where alpha is the alpha
// value of the blend the constant. We should already have valid blend coeff's if we are at
// a point where we have RGB coverage. We don't need any color stages since the known color
// output is already baked into the blendConstant.
uint8_t alpha = GrColorUnpackA(fBlendConstant);
*color = GrColorPackRGBA(alpha, alpha, alpha, alpha);
return GrXferProcessor::kClearColorStages_OptFlag;
}
// 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).
if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) {
if (doesStencilWrite) {
*color = 0xffffffff;
*overrideColor = 0xffffffff;
return GrXferProcessor::kClearColorStages_OptFlag |
GrXferProcessor::kSetCoverageDrawing_OptFlag;
} else {
@ -232,8 +234,8 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
// or blend, just write transparent black into the dst.
fSrcBlend = kOne_GrBlendCoeff;
fDstBlend = kZero_GrBlendCoeff;
*color = 0;
*coverage = 0xff;
*overrideColor = 0;
*overrideCoverage = 0xff;
return GrXferProcessor::kClearColorStages_OptFlag |
GrXferProcessor::kClearCoverageStages_OptFlag;
}
@ -253,7 +255,7 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
// the dst coeff is effectively zero so blend works out to:
// (c)(0)D + (1-c)D = (1-c)D.
fDstBlend = kISA_GrBlendCoeff;
*color = 0xffffffff;
*overrideColor = 0xffffffff;
return GrXferProcessor::kClearColorStages_OptFlag |
GrXferProcessor::kSetCoverageDrawing_OptFlag;
} else if (srcAIsOne) {