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()) {
SkASSERT(processors.isFinalized());
// Copy GrFragmentProcessors from GrProcessorSet to Pipeline
fNumColorProcessors = processors.numColorFragmentProcessors();
fNumColorProcessors = processors.hasColorFragmentProcessor() ? 1 : 0;
int numTotalProcessors = fNumColorProcessors +
processors.numCoverageFragmentProcessors() +
(processors.hasCoverageFragmentProcessor() ? 1 : 0) +
appliedClip.numClipCoverageFragmentProcessors();
fFragmentProcessors.reset(numTotalProcessors);
int currFPIdx = 0;
for (int i = 0; i < processors.numColorFragmentProcessors(); ++i, ++currFPIdx) {
fFragmentProcessors[currFPIdx] = processors.detachColorFragmentProcessor(i);
if (processors.hasColorFragmentProcessor()) {
fFragmentProcessors[currFPIdx++] = processors.detachColorFragmentProcessor();
}
for (int i = 0; i < processors.numCoverageFragmentProcessors(); ++i, ++currFPIdx) {
fFragmentProcessors[currFPIdx] = processors.detachCoverageFragmentProcessor(i);
if (processors.hasCoverageFragmentProcessor()) {
fFragmentProcessors[currFPIdx++] = processors.detachCoverageFragmentProcessor();
}
for (int i = 0; i < appliedClip.numClipCoverageFragmentProcessors(); ++i, ++currFPIdx) {
fFragmentProcessors[currFPIdx] = appliedClip.detachClipCoverageFragmentProcessor(i);
for (int i = 0; i < appliedClip.numClipCoverageFragmentProcessors(); ++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.
InputFlags ignoredFlags = InputFlags::kSnapVerticesToPixelCenters;
if (!caps.multisampleDisableSupport()) {
// Ganesh will omit kHWAntialias regardless multisampleDisableSupport.
// Ganesh will omit kHWAntialias regardless of multisampleDisableSupport.
ignoredFlags |= InputFlags::kHWAntialias;
}
b->add32((uint32_t)fFlags & ~(uint32_t)ignoredFlags);
const GrXferProcessor::BlendInfo& blendInfo = this->getXferProcessor().getBlendInfo();
static const uint32_t kBlendWriteShift = 1;
static const uint32_t kBlendCoeffShift = 5;
static constexpr uint32_t kBlendWriteShift = 1;
static constexpr uint32_t kBlendCoeffShift = 5;
static_assert(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
static_assert(kFirstAdvancedGrBlendEquation - 1 < 4);

View File

@ -230,7 +230,7 @@ private:
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;
SkIPoint fDstTextureOffset;

View File

@ -86,7 +86,7 @@ private:
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
* more effecient.
*/

View File

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

View File

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