aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-04-07 15:37:58 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-04-08 00:46:14 +0000
commit0ae0e23696f2ef08503040f8c02765eb58b26ddf (patch)
tree4213b333c45314df8fd0a7bda1891b99bcdcb053
parent44320dda9495b9cf8ff8a5ea4f9d9522edeabef6 (diff)
Create GrXferProcessor while doing GrProcessorSet analysis.
Bug: skia: Change-Id: I62a628f9c0536ffb05c8f9d0c9ded5657f93b48e Reviewed-on: https://skia-review.googlesource.com/11482 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
-rw-r--r--src/gpu/GrPipeline.cpp13
-rw-r--r--src/gpu/GrPipeline.h4
-rw-r--r--src/gpu/GrPipelineBuilder.h12
-rw-r--r--src/gpu/GrProcessorSet.cpp186
-rw-r--r--src/gpu/GrProcessorSet.h169
-rw-r--r--src/gpu/GrRenderTargetContext.cpp15
-rw-r--r--src/gpu/instanced/InstancedRendering.cpp31
-rw-r--r--src/gpu/instanced/InstancedRendering.h1
-rw-r--r--src/gpu/ops/GrDrawOp.h3
-rw-r--r--src/gpu/ops/GrDrawPathOp.cpp19
-rw-r--r--src/gpu/ops/GrDrawPathOp.h45
-rw-r--r--src/gpu/ops/GrMeshDrawOp.h24
-rw-r--r--src/gpu/ops/GrStencilAndCoverPathRenderer.cpp3
-rw-r--r--src/gpu/text/GrStencilAndCoverTextContext.cpp13
-rw-r--r--src/gpu/text/GrStencilAndCoverTextContext.h2
-rw-r--r--tests/GpuSampleLocationsTest.cpp18
-rw-r--r--tests/GrPorterDuffTest.cpp20
17 files changed, 241 insertions, 337 deletions
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 759f97ce2c..d1f5931d9a 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -20,6 +20,8 @@
void GrPipeline::init(const InitArgs& args) {
SkASSERT(args.fRenderTarget);
+ SkASSERT(args.fProcessors);
+ SkASSERT(args.fProcessors->isFinalized());
fRenderTarget.reset(args.fRenderTarget);
@@ -48,17 +50,8 @@ void GrPipeline::init(const InitArgs& args) {
fDrawFace = static_cast<int16_t>(args.fDrawFace);
- bool isHWAA = kHWAntialias_Flag & args.fFlags;
+ fXferProcessor.reset(args.fProcessors->xferProcessor());
- // Create XferProcessor from DS's XPFactory
- {
- bool hasMixedSamples =
- args.fRenderTarget->isMixedSampled() && (isHWAA || this->isStencilEnabled());
- sk_sp<GrXferProcessor> xferProcessor =
- GrXPFactory::MakeXferProcessor(args.fProcessors->xpFactory(), args.fXPInputColor,
- args.fXPInputCoverage, hasMixedSamples, *args.fCaps);
- fXferProcessor.reset(xferProcessor.get());
- }
if (args.fDstTexture.texture()) {
fDstTexture.reset(args.fDstTexture.texture());
fDstTextureOffset = args.fDstTexture.offset();
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index 02a14af889..a2a332fc36 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -56,9 +56,7 @@ public:
struct InitArgs {
uint32_t fFlags = 0;
GrDrawFace fDrawFace = GrDrawFace::kBoth;
- const GrProcessorSet* fProcessors = nullptr;
- GrProcessorAnalysisColor fXPInputColor;
- GrProcessorAnalysisCoverage fXPInputCoverage = GrProcessorAnalysisCoverage::kNone;
+ const GrProcessorSet* fProcessors = nullptr; // Must be finalized
const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
const GrAppliedClip* fAppliedClip = nullptr;
GrRenderTarget* fRenderTarget = nullptr;
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index 94e07e6cd8..78aead0f89 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -63,12 +63,12 @@ public:
const GrProcessorSet& processors() const { return fProcessors; }
- void analyzeAndEliminateFragmentProcessors(GrProcessorSet::Analysis* analysis,
- const GrProcessorAnalysisColor& colorInput,
- const GrProcessorAnalysisCoverage coverageInput,
- const GrAppliedClip* clip, const GrCaps& caps) {
- fProcessors.analyzeAndEliminateFragmentProcessors(analysis, colorInput, coverageInput, clip,
- caps);
+ GrProcessorSet::Analysis finalizeProcessors(const GrProcessorAnalysisColor& colorInput,
+ const GrProcessorAnalysisCoverage coverageInput,
+ const GrAppliedClip* clip, bool isMixedSamples,
+ const GrCaps& caps, GrColor* overrideColor) {
+ return fProcessors.finalize(colorInput, coverageInput, clip, isMixedSamples, caps,
+ overrideColor);
}
/// @}
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index 8bdf6b63d1..93617649a3 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(GrPaint&& paint) {
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 @@ bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
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);
}
-//////////////////////////////////////////////////////////////////////////////
-
-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);
-
- const GrFragmentProcessor* const* fps =
- processors.fFragmentProcessors.get() + processors.fFragmentProcessorOffset;
- colorInfo.analyzeProcessors(fps, processors.fColorFragmentProcessorCnt);
- fCompatibleWithCoverageAsAlpha &= colorInfo.allProcessorsCompatibleWithCoverageAsAlpha();
- fps += processors.fColorFragmentProcessorCnt;
- int n = processors.numCoverageFragmentProcessors();
+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);
+
+ GrProcessorSet::Analysis analysis;
+
+ 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 @@ void GrProcessorSet::Analysis::internalInit(const GrProcessorAnalysisColor& colo
}
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 @@ void GrProcessorSet::Analysis::internalInit(const GrProcessorAnalysisColor& colo
} 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;
}
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 39ba0137b8..289ca1bcae 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -14,6 +14,7 @@
#include "SkTemplates.h"
class GrAppliedClip;
+class GrXferProcessor;
class GrXPFactory;
class GrProcessorSet : private SkNoncopyable {
@@ -22,14 +23,6 @@ public:
~GrProcessorSet();
- /**
- * If an op is recorded with this processor set then this must be called to ensure pending
- * reads and writes are propagated to resources referred to by the processors. Otherwise,
- * data hazards may occur.
- */
- void makePendingExecution();
- bool isPendingExecution() const { return SkToBool(kPendingExecution_Flag & fFlags); }
-
int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
int numCoverageFragmentProcessors() const {
return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
@@ -46,7 +39,10 @@ public:
return fFragmentProcessors[idx + fColorFragmentProcessorCnt + fFragmentProcessorOffset];
}
- const GrXPFactory* xpFactory() const { return fXPFactory; }
+ const GrXferProcessor* xferProcessor() const {
+ SkASSERT(this->isFinalized());
+ return fXP.fProcessor;
+ }
bool usesDistanceVectorField() const { return SkToBool(fFlags & kUseDistanceVectorField_Flag); }
bool disableOutputConversionToSRGB() const {
@@ -54,74 +50,20 @@ public:
}
bool allowSRGBInputs() const { return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
+ /** Comparisons are only legal on finalized processor sets. */
bool operator==(const GrProcessorSet& that) const;
bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
/**
- * This is used to track analysis of color and coverage values through the processors.
+ * This is used to report results of processor analysis when a processor set is finalized (see
+ * below).
*/
class Analysis {
public:
- /**
- * This constructor allows an op to record its initial color in an Analysis member and then
- * then run analysis later when the analysis inputs are available. If the analysis produces
- * color fragment processor elimination then the input color is replaced by the expected
- * input to the first non-eliminated processor. Otherwise, the original input color is
- * preserved. The only reason to use this is to save space on the op by not separately
- * storing the initial color.
- */
- explicit Analysis(GrColor initialColor) : Analysis() {
- fInputColor = initialColor;
- fValidInputColor = true;
- }
-
- Analysis()
- : fIsInitializedWithProcessorSet(false)
- , fCompatibleWithCoverageAsAlpha(true)
- , fValidInputColor(false)
- , fRequiresDstTexture(false)
- , fCanCombineOverlappedStencilAndCover(true)
- , fIgnoresInputColor(false)
- , fRequiresBarrierBetweenOverlappingDraws(false)
- , fOutputCoverageType(static_cast<unsigned>(GrProcessorAnalysisCoverage::kNone))
- , fOutputColorType(static_cast<unsigned>(ColorType::kUnknown))
- , fInitialColorProcessorsToEliminate(0) {}
-
- // This version is used by a unit test that assumes no clip and no fragment processors.
- Analysis(const GrProcessorAnalysisColor&, GrProcessorAnalysisCoverage, const GrXPFactory*,
- const GrCaps&);
-
- void init(const GrProcessorAnalysisColor&, GrProcessorAnalysisCoverage,
- const GrProcessorSet&, const GrAppliedClip*, const GrCaps&);
-
- bool isInitializedWithProcessorSet() const { return fIsInitializedWithProcessorSet; }
-
- /**
- * If the return is greater than or equal to zero then 'newInputColor' should be used as the
- * input color to the GrPipeline derived from this processor set, replacing the GrDrawOp's
- * initial color. If the return is less than zero then newInputColor has not been
- * modified and no modification need be made to the pipeline's input color by the op.
- */
- int getInputColorOverrideAndColorProcessorEliminationCount(GrColor* newInputColor) const {
- if (fValidInputColor) {
- *newInputColor = fInputColor;
- return fInitialColorProcessorsToEliminate;
- }
- SkASSERT(!fInitialColorProcessorsToEliminate);
- return -1;
- }
-
- /**
- * Valid if initialProcessorsToEliminate returns true or this analysis was initialized with
- * a known color via constructor or init(). If color fragment processors are eliminated then
- * this returns the expected input to the first non-eliminated processors. Otherwise it is
- * the color passed to the constructor or init().
- */
- GrColor inputColor() const {
- SkASSERT(fValidInputColor);
- return fInputColor;
- }
+ Analysis(const Analysis&) = default;
+ Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
+ bool isInitialized() const { return fIsInitialized; }
bool usesLocalCoords() const { return fUsesLocalCoords; }
bool requiresDstTexture() const { return fRequiresDstTexture; }
bool canCombineOverlappedStencilAndCover() const {
@@ -131,60 +73,54 @@ public:
return fRequiresBarrierBetweenOverlappingDraws;
}
bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
- bool isInputColorIgnored() const { return fIgnoresInputColor; }
- GrProcessorAnalysisCoverage outputCoverage() const {
- return static_cast<GrProcessorAnalysisCoverage>(fOutputCoverageType);
- }
- GrProcessorAnalysisColor outputColor() const {
- switch (this->outputColorType()) {
- case ColorType::kConstant:
- return fKnownOutputColor;
- case ColorType::kOpaque:
- return GrProcessorAnalysisColor::Opaque::kYes;
- case ColorType::kUnknown:
- return GrProcessorAnalysisColor::Opaque::kNo;
- }
- SkFAIL("Unexpected color type");
- return GrProcessorAnalysisColor::Opaque::kNo;
+
+ bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
+ bool inputColorIsOverridden() const {
+ return fInputColorType == kOverridden_InputColorType;
}
private:
- enum class ColorType : unsigned { kUnknown, kConstant, kOpaque };
+ enum InputColorType : uint32_t {
+ kOriginal_InputColorType,
+ kOverridden_InputColorType,
+ kIgnored_InputColorType
+ };
- ColorType outputColorType() const { return static_cast<ColorType>(fOutputColorType); }
+ // MSVS 2015 won't pack different underlying types
+ using PackedBool = uint32_t;
+ using PackedInputColorType = uint32_t;
- void internalInit(const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage,
- const GrProcessorSet&, const GrFragmentProcessor* clipFP, const GrCaps&);
-
- // MSVS 2015 won't pack a bool with an unsigned.
- using PackedBool = unsigned;
-
- PackedBool fIsInitializedWithProcessorSet : 1;
PackedBool fUsesLocalCoords : 1;
PackedBool fCompatibleWithCoverageAsAlpha : 1;
- PackedBool fValidInputColor : 1;
PackedBool fRequiresDstTexture : 1;
PackedBool fCanCombineOverlappedStencilAndCover : 1;
- // These could be removed if we created the XP from the XPFactory when doing analysis.
- PackedBool fIgnoresInputColor : 1;
PackedBool fRequiresBarrierBetweenOverlappingDraws : 1;
- unsigned fOutputCoverageType : 2;
- unsigned fOutputColorType : 2;
-
- unsigned fInitialColorProcessorsToEliminate : 32 - 12;
-
- GrColor fInputColor;
- // This could be removed if we created the XP from the XPFactory when doing analysis.
- GrColor fKnownOutputColor;
+ PackedBool fIsInitialized : 1;
+ PackedInputColorType fInputColorType : 2;
friend class GrProcessorSet;
};
- GR_STATIC_ASSERT(sizeof(Analysis) == 2 * sizeof(GrColor) + sizeof(uint32_t));
+ GR_STATIC_ASSERT(sizeof(Analysis) == sizeof(uint32_t));
- void analyzeAndEliminateFragmentProcessors(Analysis*,
- const GrProcessorAnalysisColor& colorInput,
- const GrProcessorAnalysisCoverage coverageInput,
- const GrAppliedClip*, const GrCaps&);
+ /**
+ * This analyzes the processors given an op's input color and coverage as well as a clip. The
+ * state of the processor set may change to an equivalent but more optimal set of processors.
+ * This new state requires that the caller respect the returned 'inputColorOverride'. This is
+ * indicated by the returned Analysis's inputColorIsOverriden(). 'inputColorOverride' will not
+ * be written if the analysis does not override the input color.
+ *
+ * This must be called before the processor set is used to construct a GrPipeline and may only
+ * be called once.
+ *
+ * This also puts the processors in "pending execution" state and must be called when an op
+ * that owns a processor set is recorded to ensure pending and writes are propagated to
+ * resources referred to by the processors. Otherwise, data hazards may occur.
+ */
+ Analysis finalize(const GrProcessorAnalysisColor& colorInput,
+ const GrProcessorAnalysisCoverage coverageInput, const GrAppliedClip*,
+ bool isMixedSamples, const GrCaps&, GrColor* inputColorOverride);
+
+ bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
private:
// This absurdly large limit allows Analysis and this to pack fields together.
@@ -194,11 +130,22 @@ private:
kUseDistanceVectorField_Flag = 0x1,
kDisableOutputConversionToSRGB_Flag = 0x2,
kAllowSRGBInputs_Flag = 0x4,
- kPendingExecution_Flag = 0x8
+ kFinalized_Flag = 0x8
+ };
+
+ union XP {
+ XP(const GrXPFactory* factory) : fFactory(factory) {}
+ const GrXPFactory* fFactory;
+ const GrXferProcessor* fProcessor;
};
- const GrXPFactory* fXPFactory = nullptr;
+ const GrXPFactory* xpFactory() const {
+ SkASSERT(!this->isFinalized());
+ return fXP.fFactory;
+ }
+
SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors;
+ XP fXP;
uint8_t fColorFragmentProcessorCnt;
uint8_t fFragmentProcessorOffset = 0;
uint8_t fFlags;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index a4b77310d0..b0a1b6d4af 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1688,30 +1688,33 @@ uint32_t GrRenderTargetContext::addLegacyMeshDrawOp(GrPipelineBuilder&& pipeline
}
GrResourceProvider* resourceProvider = fContext->resourceProvider();
- if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
+ bool usesStencil = pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip();
+ if (usesStencil) {
if (!resourceProvider->attachStencilAttachment(this->accessRenderTarget())) {
SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
return SK_InvalidUniqueID;
}
}
- GrProcessorSet::Analysis analysis;
- op->analyzeProcessors(&analysis, &pipelineBuilder, &appliedClip, *this->caps());
+ bool isMixedSamples = fRenderTargetProxy->isMixedSampled() &&
+ (pipelineBuilder.isHWAntialias() || usesStencil);
+
+ GrColor overrideColor;
+ GrProcessorSet::Analysis analysis = op->analyzeUpdateAndRecordProcessors(
+ &pipelineBuilder, &appliedClip, isMixedSamples, *this->caps(), &overrideColor);
GrPipeline::InitArgs args;
pipelineBuilder.getPipelineInitArgs(&args);
args.fAppliedClip = &appliedClip;
args.fRenderTarget = rt;
args.fCaps = this->caps();
- args.fXPInputColor = analysis.outputColor();
- args.fXPInputCoverage = analysis.outputCoverage();
if (analysis.requiresDstTexture()) {
if (!this->setupDstTexture(fRenderTargetProxy.get(), clip, bounds, &args.fDstTexture)) {
return SK_InvalidUniqueID;
}
}
- op->initPipeline(args, analysis);
+ op->initPipeline(args, analysis, overrideColor);
// TODO: We need to add pipeline dependencies on textures, etc before recording this op.
op->setClippedBounds(bounds);
return this->getOpList()->addOp(std::move(op), this);
diff --git a/src/gpu/instanced/InstancedRendering.cpp b/src/gpu/instanced/InstancedRendering.cpp
index 9b6e576f8f..9d17a82fc1 100644
--- a/src/gpu/instanced/InstancedRendering.cpp
+++ b/src/gpu/instanced/InstancedRendering.cpp
@@ -332,17 +332,19 @@ void InstancedRendering::Op::appendParamsTexel(SkScalar x, SkScalar y, SkScalar
}
bool InstancedRendering::Op::xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) {
- GrProcessorSet::Analysis analysis;
+ SkASSERT(State::kRecordingDraws == fInstancedRendering->fState);
GrProcessorAnalysisCoverage coverageInput;
+ bool isMixedSamples = false;
if (GrAAType::kCoverage == fInfo.aaType() ||
(GrAAType::kNone == fInfo.aaType() && !fInfo.isSimpleRects() && fInfo.fCannotDiscard)) {
coverageInput = GrProcessorAnalysisCoverage::kSingleChannel;
} else {
coverageInput = GrProcessorAnalysisCoverage::kNone;
+ isMixedSamples = GrAAType::kMixedSamples == fInfo.aaType();
}
- fProcessors.analyzeAndEliminateFragmentProcessors(&analysis, this->getSingleInstance().fColor,
- coverageInput, clip, caps);
- fAnalysisColor = analysis.outputColor();
+ GrProcessorSet::Analysis analysis =
+ fProcessors.finalize(this->getSingleInstance().fColor, coverageInput, clip,
+ isMixedSamples, caps, &this->getSingleDraw().fInstance.fColor);
Draw& draw = this->getSingleDraw(); // This will assert if we have > 1 command.
SkASSERT(draw.fGeometry.isEmpty());
@@ -363,11 +365,6 @@ bool InstancedRendering::Op::xpRequiresDstTexture(const GrCaps& caps, const GrAp
fInstancedRendering->fParams.push_back_n(fParams.count(), fParams.begin());
}
- GrColor overrideColor;
- if (analysis.getInputColorOverrideAndColorProcessorEliminationCount(&overrideColor) >= 0) {
- SkASSERT(State::kRecordingDraws == fInstancedRendering->fState);
- this->getSingleDraw().fInstance.fColor = overrideColor;
- }
fInfo.fCannotTweakAlphaForCoverage = !analysis.isCompatibleWithCoverageAsAlpha();
fInfo.fUsesLocalCoords = analysis.usesLocalCoords();
@@ -378,7 +375,6 @@ bool InstancedRendering::Op::xpRequiresDstTexture(const GrCaps& caps, const GrAp
void InstancedRendering::Op::wasRecorded() {
SkASSERT(!fIsTracked);
fInstancedRendering->fTrackedOps.addToTail(this);
- fProcessors.makePendingExecution();
fIsTracked = true;
}
@@ -413,7 +409,6 @@ bool InstancedRendering::Op::onCombineIfPossible(GrOp* other, const GrCaps& caps
this->joinBounds(*that);
fInfo = combinedInfo;
fPixelLoad += that->fPixelLoad;
- fAnalysisColor = GrProcessorAnalysisColor::Combine(fAnalysisColor, that->fAnalysisColor);
// Adopt the other op's draws.
fNumDraws += that->fNumDraws;
fNumChangesInGeometry += that->fNumChangesInGeometry;
@@ -470,21 +465,9 @@ void InstancedRendering::Op::onExecute(GrOpFlushState* state) {
state->gpu()->handleDirtyContext();
- const GrAppliedClip* clip = state->drawOpArgs().fAppliedClip;
- GrProcessorAnalysisCoverage coverage;
- if (GrAAType::kCoverage == fInfo.aaType() ||
- (clip && clip->clipCoverageFragmentProcessor()) ||
- (GrAAType::kNone == fInfo.aaType() && !fInfo.isSimpleRects() && fInfo.fCannotDiscard)) {
- coverage = GrProcessorAnalysisCoverage::kSingleChannel;
- } else {
- coverage = GrProcessorAnalysisCoverage::kNone;
- }
-
GrPipeline pipeline;
GrPipeline::InitArgs args;
- args.fXPInputColor = fAnalysisColor;
- args.fXPInputCoverage = coverage;
- args.fAppliedClip = clip;
+ args.fAppliedClip = state->drawOpArgs().fAppliedClip;
args.fCaps = &state->caps();
args.fProcessors = &fProcessors;
args.fFlags = GrAATypeIsHW(fInfo.aaType()) ? GrPipeline::kHWAntialias_Flag : 0;
diff --git a/src/gpu/instanced/InstancedRendering.h b/src/gpu/instanced/InstancedRendering.h
index 3ec8214afc..a8b9530228 100644
--- a/src/gpu/instanced/InstancedRendering.h
+++ b/src/gpu/instanced/InstancedRendering.h
@@ -151,7 +151,6 @@ protected:
OpInfo fInfo;
SkScalar fPixelLoad;
GrProcessorSet fProcessors;
- GrProcessorAnalysisColor fAnalysisColor;
SkSTArray<5, ParamsTexel, true> fParams;
bool fIsTracked : 1;
bool fRequiresBarrierOnOverlap : 1;
diff --git a/src/gpu/ops/GrDrawOp.h b/src/gpu/ops/GrDrawOp.h
index 0458370bcd..dbdd9d87a0 100644
--- a/src/gpu/ops/GrDrawOp.h
+++ b/src/gpu/ops/GrDrawOp.h
@@ -76,7 +76,8 @@ public:
* This is called after the GrAppliedClip has been computed and just prior to recording the op
* or combining it with a previously recorded op. It is used to determine whether a copy of the
* destination (or destination texture itself) needs to be provided to the xp when this op
- * executes.
+ * executes. This is guaranteed to be called before an op is recorded. However, this is also
+ * called on ops that are not recorded because they combine with a previously recorded op.
*/
virtual bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) = 0;
diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp
index 1c68fdf8a1..3632787e06 100644
--- a/src/gpu/ops/GrDrawPathOp.cpp
+++ b/src/gpu/ops/GrDrawPathOp.cpp
@@ -12,13 +12,15 @@
#include "SkTemplates.h"
GrDrawPathOpBase::GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
- GrPathRendering::FillType fill, GrAA aa)
+ GrPathRendering::FillType fill, GrAAType aaType)
: INHERITED(classID)
, fViewMatrix(viewMatrix)
+ , fInputColor(paint.getColor())
, fProcessorSet(std::move(paint))
- , fAnalysis(paint.getColor())
, fFillType(fill)
- , fAA(aa) {}
+ , fAAType(aaType) {
+ SkASSERT(fAAType != GrAAType::kCoverage);
+}
SkString GrDrawPathOp::dumpInfo() const {
SkString string;
@@ -38,16 +40,13 @@ void GrDrawPathOpBase::initPipeline(const GrOpFlushState& state, GrPipeline* pip
0xffff>()
};
GrPipeline::InitArgs args;
- auto analysis = this->processorAnalysis();
args.fProcessors = &this->processors();
- args.fFlags = GrAA::kYes == fAA ? GrPipeline::kHWAntialias_Flag : 0;
+ args.fFlags = GrAATypeIsHW(fAAType) ? GrPipeline::kHWAntialias_Flag : 0;
args.fUserStencil = &kCoverPass;
args.fAppliedClip = state.drawOpArgs().fAppliedClip;
args.fRenderTarget = state.drawOpArgs().fRenderTarget;
args.fCaps = &state.caps();
args.fDstTexture = state.drawOpArgs().fDstTexture;
- args.fXPInputColor = analysis.outputColor();
- args.fXPInputCoverage = analysis.outputCoverage();
return pipeline->init(args);
}
@@ -90,9 +89,9 @@ SkString GrDrawPathRangeOp::dumpInfo() const {
GrDrawPathRangeOp::GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
SkScalar y, GrPaint&& paint, GrPathRendering::FillType fill,
- GrAA aa, GrPathRange* range, const InstanceData* instanceData,
- const SkRect& bounds)
- : INHERITED(ClassID(), viewMatrix, std::move(paint), fill, aa)
+ GrAAType aaType, GrPathRange* range,
+ const InstanceData* instanceData, const SkRect& bounds)
+ : INHERITED(ClassID(), viewMatrix, std::move(paint), fill, aaType)
, fPathRange(range)
, fTotalPathCount(instanceData->count())
, fScale(scale) {
diff --git a/src/gpu/ops/GrDrawPathOp.h b/src/gpu/ops/GrDrawPathOp.h
index 0631adcdf6..8995de4bbd 100644
--- a/src/gpu/ops/GrDrawPathOp.h
+++ b/src/gpu/ops/GrDrawPathOp.h
@@ -23,31 +23,33 @@ class GrPaint;
class GrDrawPathOpBase : public GrDrawOp {
protected:
- GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
- GrPathRendering::FillType fill, GrAA aa);
+ GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&&,
+ GrPathRendering::FillType, GrAAType);
FixedFunctionFlags fixedFunctionFlags() const override {
- return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
+ if (GrAATypeIsHW(fAAType)) {
+ return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
+ }
+ return FixedFunctionFlags::kUsesStencil;
}
bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
return this->doProcessorAnalysis(caps, clip).requiresDstTexture();
}
- void wasRecorded() override { fProcessorSet.makePendingExecution(); }
-
protected:
const SkMatrix& viewMatrix() const { return fViewMatrix; }
- GrColor color() const { return fAnalysis.inputColor(); }
+ GrColor color() const { return fInputColor; }
GrPathRendering::FillType fillType() const { return fFillType; }
const GrProcessorSet& processors() const { return fProcessorSet; }
void initPipeline(const GrOpFlushState&, GrPipeline*);
const GrProcessorSet::Analysis& doProcessorAnalysis(const GrCaps& caps,
const GrAppliedClip* clip) {
- fProcessorSet.analyzeAndEliminateFragmentProcessors(
- &fAnalysis, fAnalysis.inputColor(), GrProcessorAnalysisCoverage::kNone, clip, caps);
+ bool isMixedSamples = GrAAType::kMixedSamples == fAAType;
+ fAnalysis = fProcessorSet.finalize(fInputColor, GrProcessorAnalysisCoverage::kNone, clip,
+ isMixedSamples, caps, &fInputColor);
return fAnalysis;
}
const GrProcessorSet::Analysis& processorAnalysis() const {
- SkASSERT(fAnalysis.isInitializedWithProcessorSet());
+ SkASSERT(fAnalysis.isInitialized());
return fAnalysis;
}
@@ -55,10 +57,11 @@ private:
void onPrepare(GrOpFlushState*) final {}
SkMatrix fViewMatrix;
+ GrColor fInputColor;
GrProcessorSet fProcessorSet;
GrProcessorSet::Analysis fAnalysis;
GrPathRendering::FillType fFillType;
- GrAA fAA;
+ GrAAType fAAType;
typedef GrDrawOp INHERITED;
};
@@ -67,9 +70,10 @@ class GrDrawPathOp final : public GrDrawPathOpBase {
public:
DEFINE_OP_CLASS_ID
- static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa,
- GrPath* path) {
- return std::unique_ptr<GrDrawOp>(new GrDrawPathOp(viewMatrix, std::move(paint), aa, path));
+ static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, GrPaint&& paint,
+ GrAAType aaType, GrPath* path) {
+ return std::unique_ptr<GrDrawOp>(
+ new GrDrawPathOp(viewMatrix, std::move(paint), aaType, path));
}
const char* name() const override { return "DrawPath"; }
@@ -77,8 +81,8 @@ public:
SkString dumpInfo() const override;
private:
- GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa, const GrPath* path)
- : GrDrawPathOpBase(ClassID(), viewMatrix, std::move(paint), path->getFillType(), aa)
+ GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAAType aaType, const GrPath* path)
+ : GrDrawPathOpBase(ClassID(), viewMatrix, std::move(paint), path->getFillType(), aaType)
, fPath(path) {
this->setTransformedBounds(path->getBounds(), viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
@@ -160,11 +164,12 @@ public:
static std::unique_ptr<GrDrawOp> Make(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
SkScalar y, GrPaint&& paint,
- GrPathRendering::FillType fill, GrAA aa,
+ GrPathRendering::FillType fill, GrAAType aaType,
GrPathRange* range, const InstanceData* instanceData,
const SkRect& bounds) {
- return std::unique_ptr<GrDrawOp>(new GrDrawPathRangeOp(
- viewMatrix, scale, x, y, std::move(paint), fill, aa, range, instanceData, bounds));
+ return std::unique_ptr<GrDrawOp>(new GrDrawPathRangeOp(viewMatrix, scale, x, y,
+ std::move(paint), fill, aaType,
+ range, instanceData, bounds));
}
const char* name() const override { return "DrawPathRange"; }
@@ -173,8 +178,8 @@ public:
private:
GrDrawPathRangeOp(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y,
- GrPaint&& paint, GrPathRendering::FillType fill, GrAA aa, GrPathRange* range,
- const InstanceData* instanceData, const SkRect& bounds);
+ GrPaint&& paint, GrPathRendering::FillType fill, GrAAType aaType,
+ GrPathRange* range, const InstanceData* instanceData, const SkRect& bounds);
TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); }
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index 41d3848666..8fbd30d280 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -101,20 +101,22 @@ public:
* Performs analysis of the fragment processors in GrProcessorSet and GrAppliedClip using the
* initial color and coverage from this op's geometry processor.
*/
- void analyzeProcessors(GrProcessorSet::Analysis* analysis,
- GrPipelineBuilder* pipelineBuilder,
- const GrAppliedClip* appliedClip,
- const GrCaps& caps) const {
+ GrProcessorSet::Analysis analyzeUpdateAndRecordProcessors(GrPipelineBuilder* pipelineBuilder,
+ const GrAppliedClip* appliedClip,
+ bool isMixedSamples,
+ const GrCaps& caps,
+ GrColor* overrideColor) const {
GrProcessorAnalysisColor inputColor;
GrProcessorAnalysisCoverage inputCoverage;
this->getProcessorAnalysisInputs(&inputColor, &inputCoverage);
- pipelineBuilder->analyzeAndEliminateFragmentProcessors(analysis, inputColor, inputCoverage,
- appliedClip, caps);
+ return pipelineBuilder->finalizeProcessors(inputColor, inputCoverage, appliedClip,
+ isMixedSamples, caps, overrideColor);
}
- void initPipeline(const GrPipeline::InitArgs& args, const GrProcessorSet::Analysis& analysis) {
+ void initPipeline(const GrPipeline::InitArgs& args, const GrProcessorSet::Analysis& analysis,
+ GrColor overrideColor) {
fPipeline.init(args);
- this->applyPipelineOptimizations(PipelineOptimizations(analysis));
+ this->applyPipelineOptimizations(PipelineOptimizations(analysis, overrideColor));
}
/**
@@ -138,11 +140,11 @@ protected:
*/
class PipelineOptimizations {
public:
- PipelineOptimizations(const GrProcessorSet::Analysis& analysis) {
+ PipelineOptimizations(const GrProcessorSet::Analysis& analysis, GrColor overrideColor) {
fFlags = 0;
- if (analysis.getInputColorOverrideAndColorProcessorEliminationCount(&fOverrideColor) >=
- 0) {
+ if (analysis.inputColorIsOverridden()) {
fFlags |= kUseOverrideColor_Flag;
+ fOverrideColor = overrideColor;
}
if (analysis.usesLocalCoords()) {
fFlags |= kReadsLocalCoords_Flag;
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index a4e32acff3..bd5c297cd8 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -145,9 +145,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
std::move(coverOp));
}
} else {
- GrAA aa = GrBoolToAA(GrAATypeIsHW(args.fAAType));
std::unique_ptr<GrDrawOp> op =
- GrDrawPathOp::Make(viewMatrix, std::move(args.fPaint), aa, path.get());
+ GrDrawPathOp::Make(viewMatrix, std::move(args.fPaint), args.fAAType, path.get());
args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op));
}
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index e572e5d633..0ae4023b1c 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -570,9 +570,7 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
SkScalar y, const SkIRect& clipBounds,
GrAtlasTextContext* fallbackTextContext,
const SkPaint& originalSkPaint) const {
- GrAA runAA = this->isAntiAlias();
SkASSERT(fInstanceData);
- SkASSERT(renderTargetContext->isStencilBufferMultisampled() || GrAA::kNo == runAA);
if (fInstanceData->count()) {
static constexpr GrUserStencilSettings kCoverPass(
@@ -606,9 +604,18 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
renderTargetContext->height());
// The run's "font" overrides the anti-aliasing of the passed in SkPaint!
+ GrAAType aaType;
+ if (this->aa() == GrAA::kYes) {
+ SkASSERT(renderTargetContext->isStencilBufferMultisampled());
+ aaType = renderTargetContext->isUnifiedMultisampled() ? GrAAType::kMSAA
+ : GrAAType::kMixedSamples;
+ } else {
+ aaType = GrAAType::kNone;
+ }
+
std::unique_ptr<GrDrawOp> op = GrDrawPathRangeOp::Make(
viewMatrix, fTextRatio, fTextInverseRatio * x, fTextInverseRatio * y,
- std::move(grPaint), GrPathRendering::kWinding_FillType, runAA, glyphs.get(),
+ std::move(grPaint), GrPathRendering::kWinding_FillType, aaType, glyphs.get(),
fInstanceData.get(), bounds);
renderTargetContext->addDrawOp(clip, std::move(op));
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.h b/src/gpu/text/GrStencilAndCoverTextContext.h
index f06442b1be..54c0a9d758 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.h
+++ b/src/gpu/text/GrStencilAndCoverTextContext.h
@@ -83,7 +83,7 @@ private:
size_t computeSizeInCache() const;
- GrAA isAntiAlias() const { return fFont.isAntiAlias() ? GrAA::kYes : GrAA::kNo; }
+ GrAA aa() const { return fFont.isAntiAlias() ? GrAA::kYes : GrAA::kNo; }
private:
typedef GrDrawPathRangeOp::InstanceData InstanceData;
diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp
index 75fa6fcf65..26d7e70148 100644
--- a/tests/GpuSampleLocationsTest.cpp
+++ b/tests/GpuSampleLocationsTest.cpp
@@ -91,17 +91,8 @@ public:
virtual ~TestSampleLocationsInterface() {}
};
-static void construct_dummy_pipeline(GrRenderTargetContext* dc, GrPipeline* pipeline) {
- GrPipelineBuilder dummyBuilder(GrPaint(), GrAAType::kNone);
- GrScissorState dummyScissor;
- GrWindowRectsState dummyWindows;
-
- GrPipeline::InitArgs args;
- dummyBuilder.getPipelineInitArgs(&args);
- args.fRenderTarget = dc->accessRenderTarget();
- args.fCaps = dc->caps();
- args.fDstTexture = GrXferProcessor::DstTexture();
- pipeline->init(args);
+static sk_sp<GrPipeline> construct_dummy_pipeline(GrRenderTargetContext* dc) {
+ return sk_sp<GrPipeline>(new GrPipeline(dc->accessRenderTarget(), SkBlendMode::kSrcOver));
}
void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern,
@@ -146,11 +137,10 @@ void test_sampleLocations(skiatest::Reporter* reporter, TestSampleLocationsInter
for (int i = 0; i < numTestPatterns; ++i) {
testInterface->overrideSamplePattern(kTestPatterns[i]);
for (GrRenderTargetContext* dc : {bottomUps[i].get(), topDowns[i].get()}) {
- GrPipeline dummyPipeline;
- construct_dummy_pipeline(dc, &dummyPipeline);
+ sk_sp<GrPipeline> dummyPipeline = construct_dummy_pipeline(dc);
GrRenderTarget* rt = dc->accessRenderTarget();
assert_equal(reporter, kTestPatterns[i],
- rt->renderTargetPriv().getMultisampleSpecs(dummyPipeline),
+ rt->renderTargetPriv().getMultisampleSpecs(*dummyPipeline),
kBottomLeft_GrSurfaceOrigin == rt->origin());
}
}
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index f2bd1e729d..4066d28503 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -55,16 +55,30 @@ enum {
kISCModulate_OutputType
};
+static GrProcessorSet::Analysis do_analysis(const GrXPFactory* xpf,
+ const GrProcessorAnalysisColor& colorInput,
+ GrProcessorAnalysisCoverage coverageInput,
+ const GrCaps& caps) {
+ GrPaint paint;
+ paint.setXPFactory(xpf);
+ GrProcessorSet procs(std::move(paint));
+ GrColor overrideColor;
+ GrProcessorSet::Analysis analysis =
+ procs.finalize(colorInput, coverageInput, nullptr, false, caps, &overrideColor);
+ return analysis;
+}
+
class GrPorterDuffTest {
public:
struct XPInfo {
XPInfo(skiatest::Reporter* reporter, SkBlendMode xfermode, const GrCaps& caps,
GrProcessorAnalysisColor inputColor, GrProcessorAnalysisCoverage inputCoverage) {
const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode);
- GrProcessorSet::Analysis analysis(inputColor, inputCoverage, xpf, caps);
+
+ GrProcessorSet::Analysis analysis = do_analysis(xpf, inputColor, inputCoverage, caps);
fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
fCanCombineOverlappedStencilAndCover = analysis.canCombineOverlappedStencilAndCover();
- fIgnoresInputColor = analysis.isInputColorIgnored();
+ fIgnoresInputColor = analysis.inputColorIsIgnored();
sk_sp<GrXferProcessor> xp(
GrXPFactory::MakeXferProcessor(xpf, inputColor, inputCoverage, false, caps));
TEST_ASSERT(!analysis.requiresDstTexture());
@@ -1040,8 +1054,6 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode);
- GrProcessorSet::Analysis analysis;
- analysis = GrProcessorSet::Analysis(colorInput, coverageType, xpf, caps);
sk_sp<GrXferProcessor> xp(
GrXPFactory::MakeXferProcessor(xpf, colorInput, coverageType, false, caps));
if (!xp) {