Simplify GrProcessorSet by removing multiple color/coverage FP support.

GrProcessorSet is meant to encapsulate the processors in a GrPaint, and
GrPaint no longer supports more than one color or coverage fragment
processor on a paint.

Change-Id: I4334c967e0329503672db3b5510fce1265f25762
Bug: skia:10217
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/304857
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-07-21 17:28:12 -04:00 committed by Skia Commit-Bot
parent 247835b6c8
commit 29d3e2205a
5 changed files with 76 additions and 123 deletions

View File

@ -43,21 +43,21 @@ GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
: GrPipeline(args, processors.refXferProcessor(), appliedClip.hardClip()) { : GrPipeline(args, processors.refXferProcessor(), appliedClip.hardClip()) {
SkASSERT(processors.isFinalized()); SkASSERT(processors.isFinalized());
// Copy GrFragmentProcessors from GrProcessorSet to Pipeline // Copy GrFragmentProcessors from GrProcessorSet to Pipeline
fNumColorProcessors = processors.numColorFragmentProcessors(); fNumColorProcessors = processors.hasColorFragmentProcessor() ? 1 : 0;
int numTotalProcessors = fNumColorProcessors + int numTotalProcessors = fNumColorProcessors +
processors.numCoverageFragmentProcessors() + (processors.hasCoverageFragmentProcessor() ? 1 : 0) +
appliedClip.numClipCoverageFragmentProcessors(); appliedClip.numClipCoverageFragmentProcessors();
fFragmentProcessors.reset(numTotalProcessors); fFragmentProcessors.reset(numTotalProcessors);
int currFPIdx = 0; int currFPIdx = 0;
for (int i = 0; i < processors.numColorFragmentProcessors(); ++i, ++currFPIdx) { if (processors.hasColorFragmentProcessor()) {
fFragmentProcessors[currFPIdx] = processors.detachColorFragmentProcessor(i); fFragmentProcessors[currFPIdx++] = processors.detachColorFragmentProcessor();
} }
for (int i = 0; i < processors.numCoverageFragmentProcessors(); ++i, ++currFPIdx) { if (processors.hasCoverageFragmentProcessor()) {
fFragmentProcessors[currFPIdx] = processors.detachCoverageFragmentProcessor(i); fFragmentProcessors[currFPIdx++] = processors.detachCoverageFragmentProcessor();
} }
for (int i = 0; i < appliedClip.numClipCoverageFragmentProcessors(); ++i, ++currFPIdx) { for (int i = 0; i < appliedClip.numClipCoverageFragmentProcessors(); ++i) {
fFragmentProcessors[currFPIdx] = appliedClip.detachClipCoverageFragmentProcessor(i); fFragmentProcessors[currFPIdx++] = appliedClip.detachClipCoverageFragmentProcessor(i);
} }
} }
@ -88,15 +88,15 @@ void GrPipeline::genKey(GrProcessorKeyBuilder* b, const GrCaps& caps) const {
// kSnapVerticesToPixelCenters is implemented in a shader. // kSnapVerticesToPixelCenters is implemented in a shader.
InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters; InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters;
if (!caps.multisampleDisableSupport()) { if (!caps.multisampleDisableSupport()) {
// Ganesh will omit kHWAntialias regardless multisampleDisableSupport. // Ganesh will omit kHWAntialias regardless of multisampleDisableSupport.
ignoredFlags |= InputFlags::kHWAntialias; ignoredFlags |= InputFlags::kHWAntialias;
} }
b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags); b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags);
const GrXferProcessor::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo(); const GrXferProcessor::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo();
static const uint32_t kBlendWriteShift = 1; static constexpr uint32_t kBlendWriteShift = 1;
static const uint32_t kBlendCoeffShift = 5; static constexpr uint32_t kBlendCoeffShift = 5;
static_assert(kLast_GrBlendCoeff < (1 << kBlendCoeffShift)); static_assert(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
static_assert(kFirstAdvancedGrBlendEquation - 1 < 4); static_assert(kFirstAdvancedGrBlendEquation - 1 < 4);

View File

@ -230,7 +230,7 @@ private:
friend bool operator&(Flags, InputFlags); friend bool operator&(Flags, InputFlags);
using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>; using FragmentProcessorArray = SkAutoSTArray<6, std::unique_ptr<const GrFragmentProcessor>>;
GrSurfaceProxyView fDstProxyView; GrSurfaceProxyView fDstProxyView;
SkIPoint fDstTextureOffset; SkIPoint fDstTextureOffset;

View File

@ -86,7 +86,7 @@ private:
enum class GrProcessorAnalysisCoverage { kNone, kSingleChannel, kLCD }; enum class GrProcessorAnalysisCoverage { kNone, kSingleChannel, kLCD };
/** /**
* GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processor. * GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processors.
* It is used to recognize optimizations that can simplify the generated shader or make blending * It is used to recognize optimizations that can simplify the generated shader or make blending
* more effecient. * more effecient.
*/ */

View File

@ -23,51 +23,25 @@ GrProcessorSet GrProcessorSet::MakeEmptySet() {
} }
GrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) { GrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) {
fFlags = 0; fColorFragmentProcessor = std::move(paint.fColorFragmentProcessor);
fColorFragmentProcessorCnt = paint.hasColorFragmentProcessor() ? 1 : 0; fCoverageFragmentProcessor = std::move(paint.fCoverageFragmentProcessor);
fFragmentProcessors.reset(paint.numTotalFragmentProcessors());
int i = 0;
if (paint.fColorFragmentProcessor) {
fFragmentProcessors[i++] = std::move(paint.fColorFragmentProcessor);
}
if (paint.fCoverageFragmentProcessor) {
fFragmentProcessors[i++] = std::move(paint.fCoverageFragmentProcessor);
}
SkDEBUGCODE(paint.fAlive = false;) SkDEBUGCODE(paint.fAlive = false;)
} }
GrProcessorSet::GrProcessorSet(SkBlendMode mode) GrProcessorSet::GrProcessorSet(SkBlendMode mode) : fXP(SkBlendMode_AsXPFactory(mode)) {}
: fXP(SkBlendMode_AsXPFactory(mode))
, fColorFragmentProcessorCnt(0)
, fFragmentProcessorOffset(0)
, fFlags(0) {}
GrProcessorSet::GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP) GrProcessorSet::GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP)
: fFragmentProcessors(1) : fXP((const GrXPFactory*)nullptr) {
, fXP((const GrXPFactory*)nullptr)
, fColorFragmentProcessorCnt(1)
, fFragmentProcessorOffset(0)
, fFlags(0) {
SkASSERT(colorFP); SkASSERT(colorFP);
fFragmentProcessors[0] = std::move(colorFP); fColorFragmentProcessor = std::move(colorFP);
} }
GrProcessorSet::GrProcessorSet(GrProcessorSet&& that) GrProcessorSet::GrProcessorSet(GrProcessorSet&& that)
: fXP(std::move(that.fXP)) : fColorFragmentProcessor(std::move(that.fColorFragmentProcessor))
, fColorFragmentProcessorCnt(that.fColorFragmentProcessorCnt) , fCoverageFragmentProcessor(std::move(that.fCoverageFragmentProcessor))
, fFragmentProcessorOffset(0) , fXP(std::move(that.fXP))
, fFlags(that.fFlags) { , fFlags(that.fFlags) {}
fFragmentProcessors.reset(that.fFragmentProcessors.count() - that.fFragmentProcessorOffset);
for (int i = 0; i < fFragmentProcessors.count(); ++i) {
fFragmentProcessors[i] =
std::move(that.fFragmentProcessors[i + that.fFragmentProcessorOffset]);
}
that.fFragmentProcessors.reset(0);
that.fColorFragmentProcessorCnt = 0;
that.fFragmentProcessorOffset = 0;
}
GrProcessorSet::~GrProcessorSet() { GrProcessorSet::~GrProcessorSet() {
if (this->isFinalized() && this->xferProcessor()) { if (this->isFinalized() && this->xferProcessor()) {
@ -94,25 +68,17 @@ SkString dump_fragment_processor_tree(const GrFragmentProcessor* fp, int indentC
SkString GrProcessorSet::dumpProcessors() const { SkString GrProcessorSet::dumpProcessors() const {
SkString result; SkString result;
if (this->numFragmentProcessors()) { if (this->hasColorFragmentProcessor()) {
if (this->numColorFragmentProcessors()) { result.append("Color Fragment Processor:\n");
result.append("Color Fragment Processors:\n"); result += dump_fragment_processor_tree(this->colorFragmentProcessor(), 1);
for (int i = 0; i < this->numColorFragmentProcessors(); ++i) {
result += dump_fragment_processor_tree(this->colorFragmentProcessor(i), 1);
}
} else {
result.append("No color fragment processors.\n");
}
if (this->numCoverageFragmentProcessors()) {
result.append("Coverage Fragment Processors:\n");
for (int i = 0; i < this->numColorFragmentProcessors(); ++i) {
result += dump_fragment_processor_tree(this->coverageFragmentProcessor(i), 1);
}
} else {
result.append("No coverage fragment processors.\n");
}
} else { } else {
result.append("No color or coverage fragment processors.\n"); result.append("No color fragment processor.\n");
}
if (this->hasColorFragmentProcessor()) {
result.append("Coverage Fragment Processor:\n");
result += dump_fragment_processor_tree(this->coverageFragmentProcessor(), 1);
} else {
result.append("No coverage fragment processors.\n");
} }
if (this->isFinalized()) { if (this->isFinalized()) {
result.append("Xfer Processor: "); result.append("Xfer Processor: ");
@ -131,19 +97,24 @@ SkString GrProcessorSet::dumpProcessors() const {
bool GrProcessorSet::operator==(const GrProcessorSet& that) const { bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
SkASSERT(this->isFinalized()); SkASSERT(this->isFinalized());
SkASSERT(that.isFinalized()); SkASSERT(that.isFinalized());
int fpCount = this->numFragmentProcessors(); if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) ||
if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) || fpCount != that.numFragmentProcessors() || this->hasColorFragmentProcessor() != that.hasColorFragmentProcessor() ||
fColorFragmentProcessorCnt != that.fColorFragmentProcessorCnt) { this->hasCoverageFragmentProcessor() != that.hasCoverageFragmentProcessor()) {
return false; return false;
} }
for (int i = 0; i < fpCount; ++i) { if (this->hasColorFragmentProcessor()) {
int a = i + fFragmentProcessorOffset; if (!colorFragmentProcessor()->isEqual(*that.colorFragmentProcessor())) {
int b = i + that.fFragmentProcessorOffset;
if (!fFragmentProcessors[a]->isEqual(*that.fFragmentProcessors[b])) {
return false; return false;
} }
} }
if (this->hasCoverageFragmentProcessor()) {
if (!coverageFragmentProcessor()->isEqual(*that.coverageFragmentProcessor())) {
return false;
}
}
// Most of the time both of these are null // Most of the time both of these are null
if (!this->xferProcessor() && !that.xferProcessor()) { if (!this->xferProcessor() && !that.xferProcessor()) {
return true; return true;
@ -163,23 +134,19 @@ GrProcessorSet::Analysis GrProcessorSet::finalize(
bool hasMixedSampledCoverage, const GrCaps& caps, GrClampType clampType, bool hasMixedSampledCoverage, const GrCaps& caps, GrClampType clampType,
SkPMColor4f* overrideInputColor) { SkPMColor4f* overrideInputColor) {
SkASSERT(!this->isFinalized()); SkASSERT(!this->isFinalized());
SkASSERT(!fFragmentProcessorOffset);
GrProcessorSet::Analysis analysis; GrProcessorSet::Analysis analysis;
analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput; analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
const std::unique_ptr<GrFragmentProcessor>* fps = GrColorFragmentProcessorAnalysis colorAnalysis(colorInput, &fColorFragmentProcessor,
fFragmentProcessors.get() + fFragmentProcessorOffset; this->hasColorFragmentProcessor() ? 1 : 0);
GrColorFragmentProcessorAnalysis colorAnalysis(colorInput, fps, fColorFragmentProcessorCnt); bool hasCoverageFP = this->hasCoverageFragmentProcessor();
fps += fColorFragmentProcessorCnt;
int n = this->numCoverageFragmentProcessors();
bool hasCoverageFP = n > 0;
bool coverageUsesLocalCoords = false; bool coverageUsesLocalCoords = false;
for (int i = 0; i < n; ++i) { if (hasCoverageFP) {
if (!fps[i]->compatibleWithCoverageAsAlpha()) { if (!fCoverageFragmentProcessor->compatibleWithCoverageAsAlpha()) {
analysis.fCompatibleWithCoverageAsAlpha = false; analysis.fCompatibleWithCoverageAsAlpha = false;
} }
coverageUsesLocalCoords |= fps[i]->usesVaryingCoords(); coverageUsesLocalCoords |= fCoverageFragmentProcessor->usesVaryingCoords();
} }
if (clip) { if (clip) {
hasCoverageFP = hasCoverageFP || clip->numClipCoverageFragmentProcessors(); hasCoverageFP = hasCoverageFP || clip->numClipCoverageFragmentProcessors();
@ -205,17 +172,14 @@ GrProcessorSet::Analysis GrProcessorSet::finalize(
GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties( GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties(
this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, caps, clampType); this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, caps, clampType);
if (!this->numCoverageFragmentProcessors() &&
GrProcessorAnalysisCoverage::kNone == coverageInput) {
}
analysis.fRequiresDstTexture = analysis.fRequiresDstTexture =
SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture); SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture);
analysis.fCompatibleWithCoverageAsAlpha &= analysis.fCompatibleWithCoverageAsAlpha &=
SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithCoverageAsAlpha); SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithCoverageAsAlpha);
analysis.fRequiresNonOverlappingDraws = SkToBool( analysis.fRequiresNonOverlappingDraws =
props & GrXPFactory::AnalysisProperties::kRequiresNonOverlappingDraws); SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresNonOverlappingDraws);
if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) { if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) {
colorFPsToEliminate = this->numColorFragmentProcessors(); colorFPsToEliminate = this->hasColorFragmentProcessor() ? 1 : 0;
analysis.fInputColorType = analysis.fInputColorType =
static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType); static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType);
analysis.fUsesLocalCoords = coverageUsesLocalCoords; analysis.fUsesLocalCoords = coverageUsesLocalCoords;
@ -224,12 +188,11 @@ GrProcessorSet::Analysis GrProcessorSet::finalize(
colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha(); colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha();
analysis.fUsesLocalCoords = coverageUsesLocalCoords | colorAnalysis.usesLocalCoords(); analysis.fUsesLocalCoords = coverageUsesLocalCoords | colorAnalysis.usesLocalCoords();
} }
for (int i = 0; i < colorFPsToEliminate; ++i) { if (colorFPsToEliminate) {
fFragmentProcessors[i].reset(nullptr); SkASSERT(colorFPsToEliminate == 1);
fColorFragmentProcessor = nullptr;
} }
fFragmentProcessorOffset = colorFPsToEliminate; analysis.fHasColorFragmentProcessor = this->hasColorFragmentProcessor();
fColorFragmentProcessorCnt -= colorFPsToEliminate;
analysis.fHasColorFragmentProcessor = (fColorFragmentProcessorCnt != 0);
auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(), auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(),
outputCoverage, hasMixedSampledCoverage, caps, outputCoverage, hasMixedSampledCoverage, caps,
@ -249,7 +212,10 @@ GrProcessorSet::Analysis GrProcessorSet::finalize(
} }
void GrProcessorSet::visitProxies(const GrOp::VisitProxyFunc& func) const { void GrProcessorSet::visitProxies(const GrOp::VisitProxyFunc& func) const {
for (int i = fFragmentProcessorOffset; i < fFragmentProcessors.count(); ++i) { if (this->hasColorFragmentProcessor()) {
fFragmentProcessors[i]->visitProxies(func); fColorFragmentProcessor->visitProxies(func);
}
if (this->hasCoverageFragmentProcessor()) {
fCoverageFragmentProcessor->visitProxies(func);
} }
} }

View File

@ -33,18 +33,14 @@ public:
~GrProcessorSet(); ~GrProcessorSet();
int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; } bool hasColorFragmentProcessor() const { return fColorFragmentProcessor != nullptr; }
int numCoverageFragmentProcessors() const { bool hasCoverageFragmentProcessor() const { return fCoverageFragmentProcessor != nullptr; }
return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
}
const GrFragmentProcessor* colorFragmentProcessor(int idx) const { const GrFragmentProcessor* colorFragmentProcessor() const {
SkASSERT(idx < fColorFragmentProcessorCnt); return fColorFragmentProcessor.get();
return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
} }
const GrFragmentProcessor* coverageFragmentProcessor(int idx) const { const GrFragmentProcessor* coverageFragmentProcessor() const {
return fFragmentProcessors[idx + fColorFragmentProcessorCnt + return fCoverageFragmentProcessor.get();
fFragmentProcessorOffset].get();
} }
const GrXferProcessor* xferProcessor() const { const GrXferProcessor* xferProcessor() const {
@ -56,14 +52,12 @@ public:
return sk_ref_sp(fXP.fProcessor); return sk_ref_sp(fXP.fProcessor);
} }
std::unique_ptr<const GrFragmentProcessor> detachColorFragmentProcessor(int idx) { std::unique_ptr<const GrFragmentProcessor> detachColorFragmentProcessor() {
SkASSERT(idx < fColorFragmentProcessorCnt); return std::move(fColorFragmentProcessor);
return std::move(fFragmentProcessors[idx + fFragmentProcessorOffset]);
} }
std::unique_ptr<const GrFragmentProcessor> detachCoverageFragmentProcessor(int idx) { std::unique_ptr<const GrFragmentProcessor> detachCoverageFragmentProcessor() {
return std::move( return std::move(fCoverageFragmentProcessor);
fFragmentProcessors[idx + fFragmentProcessorOffset + fColorFragmentProcessorCnt]);
} }
/** Comparisons are only legal on finalized processor sets. */ /** Comparisons are only legal on finalized processor sets. */
@ -159,15 +153,9 @@ private:
GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {} GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
int numFragmentProcessors() const { int numFragmentProcessors() const {
return fFragmentProcessors.count() - fFragmentProcessorOffset; return (fColorFragmentProcessor ? 1 : 0) + (fCoverageFragmentProcessor ? 1 : 0);
} }
const GrFragmentProcessor* fragmentProcessor(int idx) const {
return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
}
static constexpr int kMaxColorProcessors = 1;
enum Flags : uint16_t { kFinalized_Flag = 0x1 }; enum Flags : uint16_t { kFinalized_Flag = 0x1 };
union XP { union XP {
@ -186,11 +174,10 @@ private:
return fXP.fFactory; return fXP.fFactory;
} }
SkAutoSTArray<4, std::unique_ptr<GrFragmentProcessor>> fFragmentProcessors; std::unique_ptr<GrFragmentProcessor> fColorFragmentProcessor;
std::unique_ptr<GrFragmentProcessor> fCoverageFragmentProcessor;
XP fXP; XP fXP;
uint8_t fColorFragmentProcessorCnt = 0; uint8_t fFlags = 0;
uint8_t fFragmentProcessorOffset = 0;
uint8_t fFlags;
}; };
#endif #endif