Revert "Revert "Create GrXferProcessor while doing GrProcessorSet analysis.""
This reverts commit 5dac9b3b5bf7e9c06c207cb92e257535c7d9ec95.
Bug: skia:
Change-Id: I3db2ec6776eb10c1f863b3992a2c8048c54b130f
Reviewed-on: https://skia-review.googlesource.com/12620
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index 8bdf6b6..9361764 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -9,9 +9,9 @@
#include "GrAppliedClip.h"
#include "GrCaps.h"
#include "GrXferProcessor.h"
+#include "effects/GrPorterDuffXferProcessor.h"
-GrProcessorSet::GrProcessorSet(GrPaint&& paint) {
- fXPFactory = paint.fXPFactory;
+GrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) {
fFlags = 0;
if (paint.numColorFragmentProcessors() <= kMaxColorProcessors) {
fColorFragmentProcessorCnt = paint.numColorFragmentProcessors();
@@ -40,27 +40,22 @@
GrProcessorSet::~GrProcessorSet() {
for (int i = fFragmentProcessorOffset; i < fFragmentProcessors.count(); ++i) {
- if (this->isPendingExecution()) {
+ if (this->isFinalized()) {
fFragmentProcessors[i]->completedExecution();
} else {
fFragmentProcessors[i]->unref();
}
}
-}
-
-void GrProcessorSet::makePendingExecution() {
- SkASSERT(!(kPendingExecution_Flag & fFlags));
- fFlags |= kPendingExecution_Flag;
- for (int i = fFragmentProcessorOffset; i < fFragmentProcessors.count(); ++i) {
- fFragmentProcessors[i]->addPendingExecution();
- fFragmentProcessors[i]->unref();
+ if (this->isFinalized() && this->xferProcessor()) {
+ this->xferProcessor()->completedExecution();
}
}
bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
+ SkASSERT(this->isFinalized());
+ SkASSERT(that.isFinalized());
int fpCount = this->numFragmentProcessors();
- if (((fFlags ^ that.fFlags) & ~kPendingExecution_Flag) ||
- fpCount != that.numFragmentProcessors() ||
+ if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) || fpCount != that.numFragmentProcessors() ||
fColorFragmentProcessorCnt != that.fColorFragmentProcessorCnt) {
return false;
}
@@ -72,34 +67,43 @@
return false;
}
}
- if (fXPFactory != that.fXPFactory) {
- return false;
+ // Most of the time both of these are null
+ if (!this->xferProcessor() && !that.xferProcessor()) {
+ return true;
}
- return true;
+ const GrXferProcessor& thisXP = this->xferProcessor()
+ ? *this->xferProcessor()
+ : GrPorterDuffXPFactory::SimpleSrcOverXP();
+ const GrXferProcessor& thatXP = that.xferProcessor()
+ ? *that.xferProcessor()
+ : GrPorterDuffXPFactory::SimpleSrcOverXP();
+ return thisXP.isEqual(thatXP);
}
-//////////////////////////////////////////////////////////////////////////////
+GrProcessorSet::Analysis GrProcessorSet::finalize(const GrProcessorAnalysisColor& colorInput,
+ const GrProcessorAnalysisCoverage coverageInput,
+ const GrAppliedClip* clip, bool isMixedSamples,
+ const GrCaps& caps, GrColor* overrideInputColor) {
+ SkASSERT(!this->isFinalized());
+ SkASSERT(!fFragmentProcessorOffset);
-void GrProcessorSet::Analysis::internalInit(const GrProcessorAnalysisColor& colorInput,
- const GrProcessorAnalysisCoverage coverageInput,
- const GrProcessorSet& processors,
- const GrFragmentProcessor* clipFP,
- const GrCaps& caps) {
- GrColorFragmentProcessorAnalysis colorInfo(colorInput);
- fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
- fValidInputColor = colorInput.isConstant(&fInputColor);
+ GrProcessorSet::Analysis analysis;
- const GrFragmentProcessor* const* fps =
- processors.fFragmentProcessors.get() + processors.fFragmentProcessorOffset;
- colorInfo.analyzeProcessors(fps, processors.fColorFragmentProcessorCnt);
- fCompatibleWithCoverageAsAlpha &= colorInfo.allProcessorsCompatibleWithCoverageAsAlpha();
- fps += processors.fColorFragmentProcessorCnt;
- int n = processors.numCoverageFragmentProcessors();
+ const GrFragmentProcessor* clipFP = clip ? clip->clipCoverageFragmentProcessor() : nullptr;
+ GrColorFragmentProcessorAnalysis colorAnalysis(colorInput);
+ analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
+
+ const GrFragmentProcessor* const* fps = fFragmentProcessors.get() + fFragmentProcessorOffset;
+ colorAnalysis.analyzeProcessors(fps, fColorFragmentProcessorCnt);
+ analysis.fCompatibleWithCoverageAsAlpha &=
+ colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha();
+ fps += fColorFragmentProcessorCnt;
+ int n = this->numCoverageFragmentProcessors();
bool hasCoverageFP = n > 0;
bool coverageUsesLocalCoords = false;
for (int i = 0; i < n; ++i) {
if (!fps[i]->compatibleWithCoverageAsAlpha()) {
- fCompatibleWithCoverageAsAlpha = false;
+ analysis.fCompatibleWithCoverageAsAlpha = false;
// Other than tests that exercise atypical behavior we expect all coverage FPs to be
// compatible with the coverage-as-alpha optimization.
GrCapsDebugf(&caps, "Coverage FP is not compatible with coverage as alpha.\n");
@@ -108,21 +112,14 @@
}
if (clipFP) {
- fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
+ analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
coverageUsesLocalCoords |= clipFP->usesLocalCoords();
hasCoverageFP = true;
}
- fInitialColorProcessorsToEliminate = colorInfo.initialProcessorsToEliminate(&fInputColor);
- fValidInputColor |= SkToBool(fInitialColorProcessorsToEliminate);
-
- GrProcessorAnalysisColor outputColor = colorInfo.outputColor();
- if (outputColor.isConstant(&fKnownOutputColor)) {
- fOutputColorType = static_cast<unsigned>(ColorType::kConstant);
- } else if (outputColor.isOpaque()) {
- fOutputColorType = static_cast<unsigned>(ColorType::kOpaque);
- } else {
- fOutputColorType = static_cast<unsigned>(ColorType::kUnknown);
- }
+ int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor);
+ analysis.fInputColorType = static_cast<Analysis::PackedInputColorType>(
+ colorFPsToEliminate ? Analysis::kOverridden_InputColorType
+ : Analysis::kOriginal_InputColorType);
GrProcessorAnalysisCoverage outputCoverage;
if (GrProcessorAnalysisCoverage::kLCD == coverageInput) {
@@ -132,82 +129,51 @@
} else {
outputCoverage = GrProcessorAnalysisCoverage::kNone;
}
- fOutputCoverageType = static_cast<unsigned>(outputCoverage);
GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties(
- processors.fXPFactory, colorInfo.outputColor(), outputCoverage, caps);
- if (!processors.numCoverageFragmentProcessors() &&
+ this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, caps);
+ if (!this->numCoverageFragmentProcessors() &&
GrProcessorAnalysisCoverage::kNone == coverageInput) {
- fCanCombineOverlappedStencilAndCover = SkToBool(
+ analysis.fCanCombineOverlappedStencilAndCover = SkToBool(
props & GrXPFactory::AnalysisProperties::kCanCombineOverlappedStencilAndCover);
} else {
// If we have non-clipping coverage processors we don't try to merge stencil steps as its
// unclear whether it will be correct. We don't expect this to happen in practice.
- fCanCombineOverlappedStencilAndCover = false;
+ analysis.fCanCombineOverlappedStencilAndCover = false;
}
- fRequiresDstTexture = SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture);
- fIgnoresInputColor = SkToBool(props & GrXPFactory::AnalysisProperties::kIgnoresInputColor);
- fCompatibleWithCoverageAsAlpha &=
+ analysis.fRequiresDstTexture =
+ SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture);
+ analysis.fCompatibleWithCoverageAsAlpha &=
SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithAlphaAsCoverage);
- fRequiresBarrierBetweenOverlappingDraws = SkToBool(
+ analysis.fRequiresBarrierBetweenOverlappingDraws = SkToBool(
props & GrXPFactory::AnalysisProperties::kRequiresBarrierBetweenOverlappingDraws);
if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) {
- fInitialColorProcessorsToEliminate = processors.numColorFragmentProcessors();
- // If the output of the last color stage is known then the kIgnoresInputColor optimization
- // may depend upon it being the input to the xp.
- if (!outputColor.isConstant(&fInputColor)) {
- // Otherwise, the only property the XP factory could have relied upon to compute
- // kIgnoresInputColor is opaqueness.
- fInputColor = GrColor_WHITE;
- }
- fValidInputColor = true;
- fUsesLocalCoords = coverageUsesLocalCoords;
+ colorFPsToEliminate = this->numColorFragmentProcessors();
+ analysis.fInputColorType =
+ static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType);
+ analysis.fUsesLocalCoords = coverageUsesLocalCoords;
} else {
- fUsesLocalCoords = coverageUsesLocalCoords | colorInfo.usesLocalCoords();
+ analysis.fUsesLocalCoords = coverageUsesLocalCoords | colorAnalysis.usesLocalCoords();
}
-}
-
-void GrProcessorSet::Analysis::init(const GrProcessorAnalysisColor& colorInput,
- const GrProcessorAnalysisCoverage coverageInput,
- const GrProcessorSet& processors,
- const GrAppliedClip* appliedClip,
- const GrCaps& caps) {
- const GrFragmentProcessor* clipFP =
- appliedClip ? appliedClip->clipCoverageFragmentProcessor() : nullptr;
- this->internalInit(colorInput, coverageInput, processors, clipFP, caps);
- fIsInitializedWithProcessorSet = true;
-}
-
-GrProcessorSet::Analysis::Analysis(const GrProcessorAnalysisColor& colorInput,
- const GrProcessorAnalysisCoverage coverageInput,
- const GrXPFactory* factory,
- const GrCaps& caps)
- : Analysis() {
- GrPaint paint;
- paint.setXPFactory(factory);
- this->internalInit(colorInput, coverageInput, GrProcessorSet(std::move(paint)), nullptr, caps);
-}
-
-void GrProcessorSet::analyzeAndEliminateFragmentProcessors(
- Analysis* analysis,
- const GrProcessorAnalysisColor& colorInput,
- const GrProcessorAnalysisCoverage coverageInput,
- const GrAppliedClip* clip,
- const GrCaps& caps) {
- analysis->init(colorInput, coverageInput, *this, clip, caps);
- if (analysis->fInitialColorProcessorsToEliminate > 0) {
- for (unsigned i = 0; i < analysis->fInitialColorProcessorsToEliminate; ++i) {
- if (this->isPendingExecution()) {
- fFragmentProcessors[i + fFragmentProcessorOffset]->completedExecution();
- } else {
- fFragmentProcessors[i + fFragmentProcessorOffset]->unref();
- }
- fFragmentProcessors[i + fFragmentProcessorOffset] = nullptr;
- }
- fFragmentProcessorOffset += analysis->fInitialColorProcessorsToEliminate;
- fColorFragmentProcessorCnt -= analysis->fInitialColorProcessorsToEliminate;
- SkASSERT(fFragmentProcessorOffset + fColorFragmentProcessorCnt <=
- fFragmentProcessors.count());
- analysis->fInitialColorProcessorsToEliminate = 0;
+ for (int i = 0; i < colorFPsToEliminate; ++i) {
+ fFragmentProcessors[i]->unref();
+ fFragmentProcessors[i] = nullptr;
}
+ for (int i = colorFPsToEliminate; i < fFragmentProcessors.count(); ++i) {
+ fFragmentProcessors[i]->addPendingExecution();
+ fFragmentProcessors[i]->unref();
+ }
+ fFragmentProcessorOffset = colorFPsToEliminate;
+ fColorFragmentProcessorCnt -= colorFPsToEliminate;
+
+ auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(),
+ outputCoverage, isMixedSamples, caps);
+ fXP.fProcessor = xp.get();
+ if (fXP.fProcessor) {
+ fXP.fProcessor->addPendingExecution();
+ }
+ fFlags |= kFinalized_Flag;
+
+ analysis.fIsInitialized = true;
+ return analysis;
}