Add GrProcOptInfo class to track various output information for color and coverage stages.
BUG=skia: Review URL: https://codereview.chromium.org/719203002
This commit is contained in:
parent
bc41538985
commit
b6cbc38702
@ -122,6 +122,8 @@
|
||||
'<(skia_src_path)/gpu/GrProgramDesc.h',
|
||||
'<(skia_src_path)/gpu/GrProgramElement.cpp',
|
||||
'<(skia_src_path)/gpu/GrProcessor.cpp',
|
||||
'<(skia_src_path)/gpu/GrProcOptInfo.cpp',
|
||||
'<(skia_src_path)/gpu/GrProcOptInfo.h',
|
||||
'<(skia_src_path)/gpu/GrGpuResourceRef.cpp',
|
||||
'<(skia_src_path)/gpu/GrPlotMgr.h',
|
||||
'<(skia_src_path)/gpu/GrRecordReplaceDraw.cpp',
|
||||
|
@ -92,22 +92,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool isOpaque() const {
|
||||
return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor));
|
||||
}
|
||||
|
||||
bool isSolidWhite() const {
|
||||
return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor);
|
||||
}
|
||||
|
||||
GrColor color() const { return fColor; }
|
||||
uint8_t validFlags() const { return fValidFlags; }
|
||||
|
||||
bool willUseInputColor() const { return fWillUseInputColor; }
|
||||
void resetWillUseInputColor() { fWillUseInputColor = true; }
|
||||
|
||||
void resetNonMulStageFound() { fNonMulStageFound = false; }
|
||||
|
||||
/**
|
||||
* If isSingleComponent is true, then the flag values for r, g, b, and a must all be the
|
||||
* same. If the flags are all set then all color components must be equal.
|
||||
@ -122,6 +109,16 @@ protected:
|
||||
bool fWillUseInputColor;
|
||||
|
||||
private:
|
||||
friend class GrProcOptInfo;
|
||||
|
||||
void reset(GrColor color, GrColorComponentFlags flags, bool isSingleComponent) {
|
||||
fColor = color;
|
||||
fValidFlags = flags;
|
||||
fIsSingleComponent = isSingleComponent;
|
||||
fNonMulStageFound = false;
|
||||
fWillUseInputColor = true;
|
||||
}
|
||||
|
||||
void internalSetToTransparentBlack() {
|
||||
fValidFlags = kRGBA_GrColorComponentFlags;
|
||||
fColor = 0;
|
||||
@ -137,6 +134,19 @@ private:
|
||||
return ((fValidFlags & kA_GrColorComponentFlag) && 0 == GrColorUnpackA(fColor));
|
||||
}
|
||||
|
||||
bool isOpaque() const {
|
||||
return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor));
|
||||
}
|
||||
|
||||
bool isSolidWhite() const {
|
||||
return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor);
|
||||
}
|
||||
|
||||
bool willUseInputColor() const { return fWillUseInputColor; }
|
||||
void resetWillUseInputColor() { fWillUseInputColor = true; }
|
||||
|
||||
void resetNonMulStageFound() { fNonMulStageFound = false; }
|
||||
|
||||
SkDEBUGCODE(bool colorComponentsAllEqual() const;)
|
||||
/**
|
||||
* If alpha is valid, check that any valid R,G,B values are <= A
|
||||
|
@ -8,9 +8,9 @@
|
||||
#include "GrDrawState.h"
|
||||
|
||||
#include "GrBlend.h"
|
||||
#include "GrInvariantOutput.h"
|
||||
#include "GrOptDrawState.h"
|
||||
#include "GrPaint.h"
|
||||
#include "GrProcOptInfo.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////s
|
||||
|
||||
@ -151,6 +151,15 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
|
||||
|
||||
fHints = that.fHints;
|
||||
|
||||
fColorProcInfoValid = that.fColorProcInfoValid;
|
||||
fCoverageProcInfoValid = that.fCoverageProcInfoValid;
|
||||
if (fColorProcInfoValid) {
|
||||
fColorProcInfo = that.fColorProcInfo;
|
||||
}
|
||||
if (fCoverageProcInfoValid) {
|
||||
fCoverageProcInfo = that.fCoverageProcInfo;
|
||||
}
|
||||
|
||||
memcpy(fFixedFunctionVertexAttribIndices,
|
||||
that.fFixedFunctionVertexAttribIndices,
|
||||
sizeof(fFixedFunctionVertexAttribIndices));
|
||||
@ -184,6 +193,9 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
|
||||
fDrawFace = kBoth_DrawFace;
|
||||
|
||||
fHints = 0;
|
||||
|
||||
fColorProcInfoValid = false;
|
||||
fCoverageProcInfoValid = false;
|
||||
}
|
||||
|
||||
bool GrDrawState::setIdentityViewMatrix() {
|
||||
@ -239,6 +251,8 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
|
||||
|
||||
this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
|
||||
this->setCoverage(0xFF);
|
||||
fColorProcInfoValid = false;
|
||||
fCoverageProcInfoValid = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -336,6 +350,8 @@ void GrDrawState::internalSetVertexAttribs(const GrVertexAttrib* attribs, int co
|
||||
overlapCheck |= (mask << offsetShift);
|
||||
#endif
|
||||
}
|
||||
fColorProcInfoValid = false;
|
||||
fCoverageProcInfoValid = false;
|
||||
// Positions must be specified.
|
||||
SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
|
||||
}
|
||||
@ -355,6 +371,8 @@ void GrDrawState::setDefaultVertexAttribs() {
|
||||
0xff,
|
||||
sizeof(fFixedFunctionVertexAttribIndices));
|
||||
fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
|
||||
fColorProcInfoValid = false;
|
||||
fCoverageProcInfoValid = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -384,24 +402,8 @@ bool GrDrawState::hasSolidCoverage() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrColor color;
|
||||
GrColorComponentFlags flags;
|
||||
// Initialize to an unknown starting coverage if per-vertex coverage is specified.
|
||||
if (this->hasCoverageVertexAttribute()) {
|
||||
color = 0;
|
||||
flags = static_cast<GrColorComponentFlags>(0);
|
||||
} else {
|
||||
color = this->getCoverageColor();
|
||||
flags = kRGBA_GrColorComponentFlags;
|
||||
}
|
||||
GrInvariantOutput inout(color, flags, true);
|
||||
|
||||
// check the coverage output from the GP
|
||||
if (this->hasGeometryProcessor()) {
|
||||
fGeometryProcessor->computeInvariantOutput(&inout);
|
||||
}
|
||||
|
||||
return inout.isSolidWhite();
|
||||
this->calcCoverageInvariantOutput();
|
||||
return fCoverageProcInfo.isSolidWhite();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -419,18 +421,13 @@ GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawS
|
||||
|
||||
bool GrDrawState::willEffectReadDstColor() const {
|
||||
if (!this->isColorWriteDisabled()) {
|
||||
for (int s = 0; s < this->numColorStages(); ++s) {
|
||||
if (this->getColorStage(s).getProcessor()->willReadDstColor()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int s = 0; s < this->numCoverageStages(); ++s) {
|
||||
if (this->getCoverageStage(s).getProcessor()->willReadDstColor()) {
|
||||
this->calcColorInvariantOutput();
|
||||
if (fColorProcInfo.readsDst()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
this->calcCoverageInvariantOutput();
|
||||
return fCoverageProcInfo.readsDst();
|
||||
}
|
||||
|
||||
void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
|
||||
@ -451,6 +448,10 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
|
||||
int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
|
||||
SkASSERT(n >= 0);
|
||||
fDrawState->fCoverageStages.pop_back_n(n);
|
||||
if (m + n > 0) {
|
||||
fDrawState->fColorProcInfoValid = false;
|
||||
fDrawState->fCoverageProcInfoValid = false;
|
||||
}
|
||||
SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
|
||||
}
|
||||
fDrawState = ds;
|
||||
@ -689,60 +690,13 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
|
||||
return kNone_BlendOpt;
|
||||
}
|
||||
|
||||
|
||||
bool GrDrawState::srcAlphaWillBeOne() const {
|
||||
GrColor color;
|
||||
GrColorComponentFlags flags;
|
||||
// Check if per-vertex or constant color may have partial alpha
|
||||
if (this->hasColorVertexAttribute()) {
|
||||
if (fHints & kVertexColorsAreOpaque_Hint) {
|
||||
flags = kA_GrColorComponentFlag;
|
||||
color = 0xFF << GrColor_SHIFT_A;
|
||||
} else {
|
||||
flags = static_cast<GrColorComponentFlags>(0);
|
||||
color = 0;
|
||||
}
|
||||
} else {
|
||||
flags = kRGBA_GrColorComponentFlags;
|
||||
color = this->getColor();
|
||||
}
|
||||
GrInvariantOutput inoutColor(color, flags, false);
|
||||
|
||||
// Run through the color stages
|
||||
for (int s = 0; s < this->numColorStages(); ++s) {
|
||||
const GrProcessor* processor = this->getColorStage(s).getProcessor();
|
||||
processor->computeInvariantOutput(&inoutColor);
|
||||
}
|
||||
|
||||
// Check whether coverage is treated as color. If so we run through the coverage computation.
|
||||
this->calcColorInvariantOutput();
|
||||
if (this->isCoverageDrawing()) {
|
||||
// The shader generated for coverage drawing runs the full coverage computation and then
|
||||
// makes the shader output be the multiplication of color and coverage. We mirror that here.
|
||||
if (this->hasCoverageVertexAttribute()) {
|
||||
flags = static_cast<GrColorComponentFlags>(0);
|
||||
color = 0;
|
||||
} else {
|
||||
flags = kRGBA_GrColorComponentFlags;
|
||||
color = this->getCoverageColor();
|
||||
}
|
||||
GrInvariantOutput inoutCoverage(color, flags, true);
|
||||
|
||||
if (this->hasGeometryProcessor()) {
|
||||
fGeometryProcessor->computeInvariantOutput(&inoutCoverage);
|
||||
}
|
||||
|
||||
// Run through the coverage stages
|
||||
for (int s = 0; s < this->numCoverageStages(); ++s) {
|
||||
const GrProcessor* processor = this->getCoverageStage(s).getProcessor();
|
||||
processor->computeInvariantOutput(&inoutCoverage);
|
||||
}
|
||||
|
||||
// Since the shader will multiply coverage and color, the only way the final A==1 is if
|
||||
// coverage and color both have A==1.
|
||||
return (inoutColor.isOpaque() && inoutCoverage.isOpaque());
|
||||
this->calcCoverageInvariantOutput();
|
||||
return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
|
||||
}
|
||||
|
||||
return inoutColor.isOpaque();
|
||||
return fColorProcInfo.isOpaque();
|
||||
}
|
||||
|
||||
bool GrDrawState::willBlendWithDst() const {
|
||||
@ -767,3 +721,43 @@ bool GrDrawState::willBlendWithDst() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GrDrawState::calcColorInvariantOutput() const {
|
||||
if (!fColorProcInfoValid) {
|
||||
GrColor color;
|
||||
GrColorComponentFlags flags;
|
||||
if (this->hasColorVertexAttribute()) {
|
||||
if (fHints & kVertexColorsAreOpaque_Hint) {
|
||||
flags = kA_GrColorComponentFlag;
|
||||
color = 0xFF << GrColor_SHIFT_A;
|
||||
} else {
|
||||
flags = static_cast<GrColorComponentFlags>(0);
|
||||
color = 0;
|
||||
}
|
||||
} else {
|
||||
flags = kRGBA_GrColorComponentFlags;
|
||||
color = this->getColor();
|
||||
}
|
||||
fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(),
|
||||
color, flags, false);
|
||||
fColorProcInfoValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GrDrawState::calcCoverageInvariantOutput() const {
|
||||
if (!fCoverageProcInfoValid) {
|
||||
GrColor color;
|
||||
GrColorComponentFlags flags;
|
||||
// Check if per-vertex or constant color may have partial alpha
|
||||
if (this->hasCoverageVertexAttribute()) {
|
||||
flags = static_cast<GrColorComponentFlags>(0);
|
||||
color = 0;
|
||||
} else {
|
||||
flags = kRGBA_GrColorComponentFlags;
|
||||
color = this->getCoverageColor();
|
||||
}
|
||||
fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(),
|
||||
color, flags, true, fGeometryProcessor.get());
|
||||
fCoverageProcInfoValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "GrGeometryProcessor.h"
|
||||
#include "GrGpuResourceRef.h"
|
||||
#include "GrProcessorStage.h"
|
||||
#include "GrProcOptInfo.h"
|
||||
#include "GrRenderTarget.h"
|
||||
#include "GrStencil.h"
|
||||
#include "SkMatrix.h"
|
||||
@ -181,6 +182,7 @@ public:
|
||||
void setColor(GrColor color) {
|
||||
if (color != fColor) {
|
||||
fColor = color;
|
||||
fColorProcInfoValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,6 +214,7 @@ public:
|
||||
void setCoverage(uint8_t coverage) {
|
||||
if (coverage != fCoverage) {
|
||||
fCoverage = coverage;
|
||||
fCoverageProcInfoValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,6 +230,7 @@ public:
|
||||
SkASSERT(geometryProcessor);
|
||||
SkASSERT(!this->hasGeometryProcessor());
|
||||
fGeometryProcessor.reset(SkRef(geometryProcessor));
|
||||
fCoverageProcInfoValid = false;
|
||||
return geometryProcessor;
|
||||
}
|
||||
|
||||
@ -270,12 +274,14 @@ public:
|
||||
const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
|
||||
SkASSERT(effect);
|
||||
SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
|
||||
fColorProcInfoValid = false;
|
||||
return effect;
|
||||
}
|
||||
|
||||
const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
|
||||
SkASSERT(effect);
|
||||
SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
|
||||
fCoverageProcInfoValid = false;
|
||||
return effect;
|
||||
}
|
||||
|
||||
@ -802,6 +808,18 @@ private:
|
||||
*/
|
||||
bool srcAlphaWillBeOne() const;
|
||||
|
||||
/**
|
||||
* If fColorProcInfoValid is false, function calculates the invariant output for the color
|
||||
* stages and results are stored in fColorProcInfo.
|
||||
*/
|
||||
void calcColorInvariantOutput() const;
|
||||
|
||||
/**
|
||||
* If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
|
||||
* stages and results are stored in fCoverageProcInfo.
|
||||
*/
|
||||
void calcCoverageInvariantOutput() const;
|
||||
|
||||
void onReset(const SkMatrix* initialViewMatrix);
|
||||
|
||||
// Some of the auto restore objects assume that no effects are removed during their lifetime.
|
||||
@ -838,6 +856,11 @@ private:
|
||||
// not need to be compared in op==.
|
||||
int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
|
||||
|
||||
mutable GrProcOptInfo fColorProcInfo;
|
||||
mutable GrProcOptInfo fCoverageProcInfo;
|
||||
mutable bool fColorProcInfoValid;
|
||||
mutable bool fCoverageProcInfoValid;
|
||||
|
||||
friend class GrOptDrawState;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
|
@ -52,5 +52,6 @@ bool GrInvariantOutput::validPreMulColor() const {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // end DEBUG
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "GrDrawState.h"
|
||||
#include "GrDrawTargetCaps.h"
|
||||
#include "GrGpu.h"
|
||||
#include "GrInvariantOutput.h"
|
||||
#include "GrProcOptInfo.h"
|
||||
|
||||
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
||||
BlendOptFlags blendOptFlags,
|
||||
@ -239,23 +239,14 @@ void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds,
|
||||
color = 0;
|
||||
}
|
||||
}
|
||||
GrInvariantOutput inout(color, flags, false);
|
||||
|
||||
for (int i = 0; i < ds.numColorStages(); ++i) {
|
||||
const GrFragmentProcessor* fp = ds.getColorStage(i).getProcessor();
|
||||
fp->computeInvariantOutput(&inout);
|
||||
if (!inout.willUseInputColor()) {
|
||||
*firstColorStageIdx = i;
|
||||
descInfo->fInputColorIsUsed = false;
|
||||
}
|
||||
if (kRGBA_GrColorComponentFlags == inout.validFlags()) {
|
||||
*firstColorStageIdx = i + 1;
|
||||
fColor = inout.color();
|
||||
descInfo->fInputColorIsUsed = true;
|
||||
GrProcOptInfo poi;
|
||||
if (ds.numColorStages() > 0) {
|
||||
poi.calcWithInitialValues(&ds.getColorStage(0), ds.numColorStages(), color, flags, false);
|
||||
*firstColorStageIdx = poi.firstEffectiveStageIndex();
|
||||
descInfo->fInputColorIsUsed = poi.inputColorIsUsed();
|
||||
fColor = poi.inputColorToEffectiveStage();
|
||||
if (poi.removeVertexAttrib()) {
|
||||
*fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
|
||||
// Since we are clearing all previous color stages we are in a state where we have found
|
||||
// zero stages that don't multiply the inputColor.
|
||||
inout.resetNonMulStageFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "GrPaint.h"
|
||||
|
||||
#include "GrBlend.h"
|
||||
#include "GrInvariantOutput.h"
|
||||
#include "GrProcOptInfo.h"
|
||||
#include "effects/GrSimpleTextureEffect.h"
|
||||
|
||||
void GrPaint::addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
|
||||
@ -37,8 +37,8 @@ bool GrPaint::isOpaque() const {
|
||||
}
|
||||
|
||||
bool GrPaint::isOpaqueAndConstantColor(GrColor* color) const {
|
||||
GrColor tempColor;
|
||||
uint32_t colorComps;
|
||||
GrColor tempColor = 0;
|
||||
uint32_t colorComps = 0;
|
||||
if (this->getOpaqueAndKnownColor(&tempColor, &colorComps)) {
|
||||
if (kRGBA_GrColorComponentFlags == colorComps) {
|
||||
*color = tempColor;
|
||||
@ -52,29 +52,24 @@ bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor,
|
||||
uint32_t* solidColorKnownComponents) const {
|
||||
|
||||
// TODO: Share this implementation with GrDrawState
|
||||
|
||||
GrProcOptInfo coverageProcInfo;
|
||||
coverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(),
|
||||
0xFFFFFFFF, kRGBA_GrColorComponentFlags, true);
|
||||
|
||||
GrInvariantOutput inoutCoverage(0xFFFFFFFF,
|
||||
kRGBA_GrColorComponentFlags,
|
||||
true);
|
||||
int count = fCoverageStages.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
fCoverageStages[i].getProcessor()->computeInvariantOutput(&inoutCoverage);
|
||||
}
|
||||
if (!inoutCoverage.isSolidWhite()) {
|
||||
if (!coverageProcInfo.isSolidWhite()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrInvariantOutput inout(fColor, kRGBA_GrColorComponentFlags, false);
|
||||
count = fColorStages.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
fColorStages[i].getProcessor()->computeInvariantOutput(&inout);
|
||||
}
|
||||
GrProcOptInfo colorProcInfo;
|
||||
colorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), fColor,
|
||||
kRGBA_GrColorComponentFlags, false);
|
||||
|
||||
SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents));
|
||||
|
||||
GrBlendCoeff srcCoeff = fSrcBlendCoeff;
|
||||
GrBlendCoeff dstCoeff = fDstBlendCoeff;
|
||||
GrSimplifyBlend(&srcCoeff, &dstCoeff, inout.color(), inout.validFlags(),
|
||||
GrSimplifyBlend(&srcCoeff, &dstCoeff, colorProcInfo.color(), colorProcInfo.validFlags(),
|
||||
0, 0, 0);
|
||||
|
||||
bool opaque = kZero_GrBlendCoeff == dstCoeff && !GrBlendCoeffRefsDst(srcCoeff);
|
||||
@ -87,8 +82,8 @@ bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor,
|
||||
break;
|
||||
|
||||
case kOne_GrBlendCoeff:
|
||||
*solidColor = inout.color();
|
||||
*solidColorKnownComponents = inout.validFlags();
|
||||
*solidColor = colorProcInfo.color();
|
||||
*solidColorKnownComponents = colorProcInfo.validFlags();
|
||||
break;
|
||||
|
||||
// The src coeff should never refer to the src and if it refers to dst then opaque
|
||||
|
56
src/gpu/GrProcOptInfo.cpp
Normal file
56
src/gpu/GrProcOptInfo.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrProcOptInfo.h"
|
||||
|
||||
#include "GrGeometryProcessor.h"
|
||||
#include "GrProcessorStage.h"
|
||||
|
||||
void GrProcOptInfo::calcWithInitialValues(const GrFragmentStage* stages,
|
||||
int stageCount,
|
||||
GrColor startColor,
|
||||
GrColorComponentFlags flags,
|
||||
bool areCoverageStages,
|
||||
const GrGeometryProcessor* gp) {
|
||||
fInOut.reset(startColor, flags, areCoverageStages);
|
||||
fFirstEffectStageIndex = 0;
|
||||
fInputColorIsUsed = true;
|
||||
fInputColor = startColor;
|
||||
fRemoveVertexAttrib = false;
|
||||
fReadsDst = false;
|
||||
|
||||
if (areCoverageStages && gp) {
|
||||
gp->computeInvariantOutput(&fInOut);
|
||||
}
|
||||
|
||||
for (int i = 0; i < stageCount; ++i) {
|
||||
const GrFragmentProcessor* processor = stages[i].getProcessor();
|
||||
fInOut.resetWillUseInputColor();
|
||||
processor->computeInvariantOutput(&fInOut);
|
||||
#ifdef SK_DEBUG
|
||||
fInOut.validate();
|
||||
#endif
|
||||
if (!fInOut.willUseInputColor()) {
|
||||
fFirstEffectStageIndex = i;
|
||||
fInputColorIsUsed = false;
|
||||
fReadsDst = false; // Reset this since we don't care if previous stages read dst
|
||||
}
|
||||
if (processor->willReadDstColor()) {
|
||||
fReadsDst = true;
|
||||
}
|
||||
if (kRGBA_GrColorComponentFlags == fInOut.validFlags()) {
|
||||
fFirstEffectStageIndex = i + 1;
|
||||
fInputColor = fInOut.color();
|
||||
fInputColorIsUsed = true;
|
||||
fRemoveVertexAttrib = true;
|
||||
// Since we are clearing all previous color stages we are in a state where we have found
|
||||
// zero stages that don't multiply the inputColor.
|
||||
fInOut.resetNonMulStageFound();
|
||||
fReadsDst = false; // Reset this since we don't care if previous stages read dst
|
||||
}
|
||||
}
|
||||
}
|
85
src/gpu/GrProcOptInfo.h
Normal file
85
src/gpu/GrProcOptInfo.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrProcOptInfo_DEFINED
|
||||
#define GrProcOptInfo_DEFINED
|
||||
|
||||
#include "GrColor.h"
|
||||
#include "GrInvariantOutput.h"
|
||||
|
||||
class GrFragmentStage;
|
||||
class GrGeometryProcessor;
|
||||
|
||||
/**
|
||||
* GrProcOptInfo gathers invariant data from a set of processor stages.It is used to recognize
|
||||
* optimizations related to eliminating stages and vertex attributes that aren't necessary for a
|
||||
* draw.
|
||||
*/
|
||||
class GrProcOptInfo {
|
||||
public:
|
||||
GrProcOptInfo()
|
||||
: fInOut(0, static_cast<GrColorComponentFlags>(0), false)
|
||||
, fFirstEffectStageIndex(0)
|
||||
, fInputColorIsUsed(true)
|
||||
, fInputColor(0)
|
||||
, fRemoveVertexAttrib(false)
|
||||
, fReadsDst(false) {}
|
||||
|
||||
void calcWithInitialValues(const GrFragmentStage*, int stageCount, GrColor startColor,
|
||||
GrColorComponentFlags flags, bool areCoverageStages,
|
||||
const GrGeometryProcessor* gp = NULL);
|
||||
|
||||
bool isSolidWhite() const { return fInOut.isSolidWhite(); }
|
||||
bool isOpaque() const { return fInOut.isOpaque(); }
|
||||
|
||||
GrColor color() const { return fInOut.color(); }
|
||||
uint8_t validFlags() const { return fInOut.validFlags(); }
|
||||
|
||||
/**
|
||||
* Returns the index of the first effective color stage. If an intermediate stage doesn't read
|
||||
* its input or has a known output, then we can ignore all earlier stages since they will not
|
||||
* affect the final output. Thus the first effective stage index is the index to the first stage
|
||||
* that will have an effect on the final output.
|
||||
*
|
||||
* If stages before the firstEffectiveStageIndex are removed, corresponding values from
|
||||
* inputColorIsUsed(), inputColorToEffectiveStage(), removeVertexAttribs(), and readsDst() must
|
||||
* be used when setting up the draw to ensure correct drawing.
|
||||
*/
|
||||
int firstEffectiveStageIndex() const { return fFirstEffectStageIndex; }
|
||||
|
||||
/**
|
||||
* True if the first effective stage reads its input, false otherwise.
|
||||
*/
|
||||
bool inputColorIsUsed() const { return fInputColorIsUsed; }
|
||||
|
||||
/**
|
||||
* If input color is used and per-vertex colors are not used, this is the input color to the
|
||||
* first effective stage.
|
||||
*/
|
||||
GrColor inputColorToEffectiveStage() const { return fInputColor; }
|
||||
|
||||
/**
|
||||
* Given the set of optimizations determined by GrProcOptInfo, should the caller remove the
|
||||
* color/coverage vertex attribute that was input to the first stage.
|
||||
*/
|
||||
bool removeVertexAttrib() const { return fRemoveVertexAttrib; }
|
||||
|
||||
/**
|
||||
* Returns true if any of the stages preserved by GrProcOptInfo read the dst color.
|
||||
*/
|
||||
bool readsDst() const { return fReadsDst; }
|
||||
|
||||
private:
|
||||
GrInvariantOutput fInOut;
|
||||
int fFirstEffectStageIndex;
|
||||
bool fInputColorIsUsed;
|
||||
GrColor fInputColor;
|
||||
bool fRemoveVertexAttrib;
|
||||
bool fReadsDst;
|
||||
};
|
||||
|
||||
#endif
|
@ -130,11 +130,7 @@ bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const {
|
||||
}
|
||||
|
||||
void GrProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
|
||||
inout->resetWillUseInputColor();
|
||||
this->onComputeInvariantOutput(inout);
|
||||
#ifdef SK_DEBUG
|
||||
inout->validate();
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user