Combine coverage in GrAppliedClip using RunInSeries.
This lets us end up with a single coverage processor instead of an array of them. Coverage processors simply multiply against their input so the results are conceptually equivalent. In practice, it is uncommon to have more than one applied clip (at least on GMs). Change-Id: I73d5da8015f48c6cb1d3f37257e7e0c4329579b5 Bug: skia:10217 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/305117 Commit-Queue: John Stiles <johnstiles@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
cc848b59f8
commit
59e18dc6dd
@ -50,11 +50,11 @@ enum SrcType {
|
||||
const struct {
|
||||
SkBlendMode fMode;
|
||||
int fSourceTypeMask; // The source types to use this
|
||||
// mode with. See draw_mode for
|
||||
// an explanation of each type.
|
||||
// PDF has to play some tricks
|
||||
// to support the base modes,
|
||||
// test those more extensively.
|
||||
// mode with. See draw_mode for
|
||||
// an explanation of each type.
|
||||
// PDF has to play some tricks
|
||||
// to support the base modes,
|
||||
// test those more extensively.
|
||||
} gModes[] = {
|
||||
{ SkBlendMode::kClear, kAll_SrcType },
|
||||
{ SkBlendMode::kSrc, kAll_SrcType },
|
||||
|
@ -104,59 +104,57 @@ public:
|
||||
const GrWindowRectsState& windowRectsState() const { return fHardClip.windowRectsState(); }
|
||||
uint32_t stencilStackID() const { return fHardClip.stencilStackID(); }
|
||||
bool hasStencilClip() const { return fHardClip.hasStencilClip(); }
|
||||
int numClipCoverageFragmentProcessors() const { return fClipCoverageFPs.count(); }
|
||||
const GrFragmentProcessor* clipCoverageFragmentProcessor(int i) const {
|
||||
SkASSERT(fClipCoverageFPs[i]);
|
||||
return fClipCoverageFPs[i].get();
|
||||
int hasCoverageFragmentProcessor() const { return fCoverageFP != nullptr; }
|
||||
const GrFragmentProcessor* coverageFragmentProcessor() const {
|
||||
SkASSERT(fCoverageFP != nullptr);
|
||||
return fCoverageFP.get();
|
||||
}
|
||||
std::unique_ptr<const GrFragmentProcessor> detachClipCoverageFragmentProcessor(int i) {
|
||||
SkASSERT(fClipCoverageFPs[i]);
|
||||
return std::move(fClipCoverageFPs[i]);
|
||||
std::unique_ptr<const GrFragmentProcessor> detachCoverageFragmentProcessor() {
|
||||
SkASSERT(fCoverageFP != nullptr);
|
||||
return std::move(fCoverageFP);
|
||||
}
|
||||
|
||||
const GrAppliedHardClip& hardClip() const { return fHardClip; }
|
||||
GrAppliedHardClip& hardClip() { return fHardClip; }
|
||||
|
||||
void addCoverageFP(std::unique_ptr<GrFragmentProcessor> fp) {
|
||||
SkASSERT(fp);
|
||||
fClipCoverageFPs.push_back(std::move(fp));
|
||||
if (fCoverageFP == nullptr) {
|
||||
fCoverageFP = std::move(fp);
|
||||
} else {
|
||||
// Run this coverage FP in series with the previously-added coverage.
|
||||
std::unique_ptr<GrFragmentProcessor> series[] = {
|
||||
std::move(fCoverageFP),
|
||||
std::move(fp),
|
||||
};
|
||||
fCoverageFP = GrFragmentProcessor::RunInSeries(series, SK_ARRAY_COUNT(series));
|
||||
}
|
||||
}
|
||||
|
||||
bool doesClip() const {
|
||||
return fHardClip.doesClip() || !fClipCoverageFPs.empty();
|
||||
return fHardClip.doesClip() || fCoverageFP != nullptr;
|
||||
}
|
||||
|
||||
bool operator==(const GrAppliedClip& that) const {
|
||||
if (fHardClip != that.fHardClip ||
|
||||
fClipCoverageFPs.count() != that.fClipCoverageFPs.count()) {
|
||||
this->hasCoverageFragmentProcessor() != that.hasCoverageFragmentProcessor()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < fClipCoverageFPs.count(); ++i) {
|
||||
if (!fClipCoverageFPs[i] || !that.fClipCoverageFPs[i]) {
|
||||
if (fClipCoverageFPs[i] == that.fClipCoverageFPs[i]) {
|
||||
continue; // Both are null.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!fClipCoverageFPs[i]->isEqual(*that.fClipCoverageFPs[i])) {
|
||||
return false;
|
||||
}
|
||||
if (fCoverageFP != nullptr && !fCoverageFP->isEqual(*that.fCoverageFP)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const GrAppliedClip& that) const { return !(*this == that); }
|
||||
|
||||
void visitProxies(const GrOp::VisitProxyFunc& func) const {
|
||||
for (const std::unique_ptr<GrFragmentProcessor>& fp : fClipCoverageFPs) {
|
||||
if (fp) { // This might be called after detach.
|
||||
fp->visitProxies(func);
|
||||
}
|
||||
if (fCoverageFP != nullptr) {
|
||||
fCoverageFP->visitProxies(func);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GrAppliedHardClip fHardClip;
|
||||
SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fClipCoverageFPs;
|
||||
std::unique_ptr<GrFragmentProcessor> fCoverageFP;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -311,10 +311,9 @@ bool GrOpsTask::OpChain::prependChain(OpChain* that, const GrCaps& caps,
|
||||
fBounds = that->fBounds;
|
||||
|
||||
that->fDstProxyView.setProxyView({});
|
||||
if (that->fAppliedClip) {
|
||||
for (int i = 0; i < that->fAppliedClip->numClipCoverageFragmentProcessors(); ++i) {
|
||||
that->fAppliedClip->detachClipCoverageFragmentProcessor(i);
|
||||
}
|
||||
if (that->fAppliedClip && that->fAppliedClip->hasCoverageFragmentProcessor()) {
|
||||
// Obliterates the processor.
|
||||
that->fAppliedClip->detachCoverageFragmentProcessor();
|
||||
}
|
||||
this->validate();
|
||||
return true;
|
||||
|
@ -46,7 +46,7 @@ GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
|
||||
fNumColorProcessors = processors.hasColorFragmentProcessor() ? 1 : 0;
|
||||
int numTotalProcessors = fNumColorProcessors +
|
||||
(processors.hasCoverageFragmentProcessor() ? 1 : 0) +
|
||||
appliedClip.numClipCoverageFragmentProcessors();
|
||||
(appliedClip.hasCoverageFragmentProcessor() ? 1 : 0);
|
||||
fFragmentProcessors.reset(numTotalProcessors);
|
||||
|
||||
int currFPIdx = 0;
|
||||
@ -56,8 +56,8 @@ GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
|
||||
if (processors.hasCoverageFragmentProcessor()) {
|
||||
fFragmentProcessors[currFPIdx++] = processors.detachCoverageFragmentProcessor();
|
||||
}
|
||||
for (int i = 0; i < appliedClip.numClipCoverageFragmentProcessors(); ++i) {
|
||||
fFragmentProcessors[currFPIdx++] = appliedClip.detachClipCoverageFragmentProcessor(i);
|
||||
if (appliedClip.hasCoverageFragmentProcessor()) {
|
||||
fFragmentProcessors[currFPIdx++] = appliedClip.detachCoverageFragmentProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,8 @@ private:
|
||||
|
||||
friend bool operator&(Flags, InputFlags);
|
||||
|
||||
using FragmentProcessorArray = SkAutoSTArray<6, std::unique_ptr<const GrFragmentProcessor>>;
|
||||
// A pipeline can contain up to three processors: color, paint coverage, and clip coverage.
|
||||
using FragmentProcessorArray = SkAutoSTArray<3, std::unique_ptr<const GrFragmentProcessor>>;
|
||||
|
||||
GrSurfaceProxyView fDstProxyView;
|
||||
SkIPoint fDstTextureOffset;
|
||||
|
@ -148,13 +148,11 @@ GrProcessorSet::Analysis GrProcessorSet::finalize(
|
||||
}
|
||||
coverageUsesLocalCoords |= fCoverageFragmentProcessor->usesVaryingCoords();
|
||||
}
|
||||
if (clip) {
|
||||
hasCoverageFP = hasCoverageFP || clip->numClipCoverageFragmentProcessors();
|
||||
for (int i = 0; i < clip->numClipCoverageFragmentProcessors(); ++i) {
|
||||
const GrFragmentProcessor* clipFP = clip->clipCoverageFragmentProcessor(i);
|
||||
analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
|
||||
coverageUsesLocalCoords |= clipFP->usesVaryingCoords();
|
||||
}
|
||||
if (clip && clip->hasCoverageFragmentProcessor()) {
|
||||
hasCoverageFP = true;
|
||||
const GrFragmentProcessor* clipFP = clip->coverageFragmentProcessor();
|
||||
analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
|
||||
coverageUsesLocalCoords |= clipFP->usesVaryingCoords();
|
||||
}
|
||||
int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor);
|
||||
analysis.fInputColorType = static_cast<Analysis::PackedInputColorType>(
|
||||
|
@ -90,7 +90,7 @@ GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
|
||||
if (fProcessors) {
|
||||
GrProcessorAnalysisCoverage coverage = geometryCoverage;
|
||||
if (GrProcessorAnalysisCoverage::kNone == coverage) {
|
||||
coverage = clip->numClipCoverageFragmentProcessors()
|
||||
coverage = clip->hasCoverageFragmentProcessor()
|
||||
? GrProcessorAnalysisCoverage::kSingleChannel
|
||||
: GrProcessorAnalysisCoverage::kNone;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user