Replace analytic clip stack with chained fragment processors.
We no longer need to maintain a vector of analytic FPs and run them in series. (CCPR and fShader do not support chaining in this CL, so we do need to assemble a vector of FPs at the last instant.) Change-Id: I1f7a64cf617d577e05e1fe41c740361f702a76b0 Bug: skia:10217 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/296861 Commit-Queue: John Stiles <johnstiles@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
851b90e102
commit
907f34bfc1
@ -651,15 +651,10 @@ GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkRect& deviceSpace
|
||||
return ClipResult::kNotClipped;
|
||||
}
|
||||
|
||||
if (fAnalyticFPs.empty()) {
|
||||
fAnalyticFPs.push_back(nullptr);
|
||||
}
|
||||
|
||||
fAnalyticFPs.back() = GrAARectEffect::Make(std::move(fAnalyticFPs.back()),
|
||||
GetClipEdgeType(invert, aa), deviceSpaceRect);
|
||||
|
||||
SkASSERT(fAnalyticFPs.back() != nullptr);
|
||||
fAnalyticFP = GrAARectEffect::Make(std::move(fAnalyticFP), GetClipEdgeType(invert, aa),
|
||||
deviceSpaceRect);
|
||||
|
||||
SkASSERT(fAnalyticFP != nullptr);
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
|
||||
@ -669,23 +664,13 @@ GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkRRect& deviceSpac
|
||||
return ClipResult::kNotClipped;
|
||||
}
|
||||
|
||||
if (fAnalyticFPs.empty()) {
|
||||
// Create our first analytic effect in the stack.
|
||||
auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, GetClipEdgeType(invert, aa),
|
||||
deviceSpaceRRect, *fCaps->shaderCaps());
|
||||
if (success) {
|
||||
fAnalyticFPs.push_back(std::move(fp));
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
} else {
|
||||
// Combine this analytic effect with the previous effect in the stack.
|
||||
auto [success, fp] = GrRRectEffect::Make(std::move(fAnalyticFPs.back()),
|
||||
GetClipEdgeType(invert, aa), deviceSpaceRRect,
|
||||
*fCaps->shaderCaps());
|
||||
fAnalyticFPs.back() = std::move(fp);
|
||||
if (success) {
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
// Combine this analytic effect with the previous effect in the stack.
|
||||
bool success;
|
||||
std::tie(success, fAnalyticFP) = GrRRectEffect::Make(std::move(fAnalyticFP),
|
||||
GetClipEdgeType(invert, aa),
|
||||
deviceSpaceRRect, *fCaps->shaderCaps());
|
||||
if (success) {
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
|
||||
SkPath deviceSpacePath;
|
||||
@ -700,22 +685,13 @@ GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkPath& deviceSpace
|
||||
return ClipResult::kNotClipped;
|
||||
}
|
||||
|
||||
if (fAnalyticFPs.empty()) {
|
||||
// Create our first analytic effect in the stack.
|
||||
auto [success, fp] = GrConvexPolyEffect::Make(/*inputFP=*/nullptr,
|
||||
GetClipEdgeType(invert, aa), deviceSpacePath);
|
||||
if (success) {
|
||||
fAnalyticFPs.push_back(std::move(fp));
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
} else {
|
||||
// Combine this analytic effect with the previous effect in the stack.
|
||||
auto [success, fp] = GrConvexPolyEffect::Make(std::move(fAnalyticFPs.back()),
|
||||
GetClipEdgeType(invert, aa), deviceSpacePath);
|
||||
fAnalyticFPs.back() = std::move(fp);
|
||||
if (success) {
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
// Combine this analytic effect with the previous effect in the stack.
|
||||
bool success;
|
||||
std::tie(success, fAnalyticFP) = GrConvexPolyEffect::Make(std::move(fAnalyticFP),
|
||||
GetClipEdgeType(invert, aa),
|
||||
deviceSpacePath);
|
||||
if (success) {
|
||||
return ClipResult::kClipped;
|
||||
}
|
||||
|
||||
if (fCCPRClipPaths.count() < fMaxCCPRClipPaths && GrAA::kYes == aa) {
|
||||
@ -914,19 +890,36 @@ bool GrReducedClip::drawStencilClipMask(GrRecordingContext* context,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int count_fp_recursive(GrFragmentProcessor* fp) {
|
||||
int count = 0;
|
||||
if (fp != nullptr) {
|
||||
count += 1; // count self
|
||||
for (int index=0; index < fp->numChildProcessors(); ++index) {
|
||||
count += count_fp_recursive(&fp->childProcessor(index)); // count children
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int GrReducedClip::numAnalyticFPs() const {
|
||||
return fCCPRClipPaths.size() + count_fp_recursive(fAnalyticFP.get());
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrReducedClip::finishAndDetachAnalyticFPs(
|
||||
GrRecordingContext* context, const SkMatrixProvider& matrixProvider,
|
||||
GrCoverageCountingPathRenderer* ccpr, uint32_t opsTaskID) {
|
||||
// Make sure finishAndDetachAnalyticFPs hasn't been called already.
|
||||
SkDEBUGCODE(for (const auto& fp : fAnalyticFPs) { SkASSERT(fp); })
|
||||
std::vector<std::unique_ptr<GrFragmentProcessor>> clipFPs;
|
||||
clipFPs.reserve(fCCPRClipPaths.size() + 2);
|
||||
|
||||
if (fAnalyticFP != nullptr) {
|
||||
clipFPs.push_back(std::move(fAnalyticFP));
|
||||
}
|
||||
|
||||
if (!fCCPRClipPaths.empty()) {
|
||||
fAnalyticFPs.reserve(fAnalyticFPs.count() + fCCPRClipPaths.count());
|
||||
for (const SkPath& ccprClipPath : fCCPRClipPaths) {
|
||||
SkASSERT(ccpr);
|
||||
SkASSERT(fHasScissor);
|
||||
auto fp = ccpr->makeClipProcessor(opsTaskID, ccprClipPath, fScissor, *fCaps);
|
||||
fAnalyticFPs.push_back(std::move(fp));
|
||||
clipFPs.push_back(ccpr->makeClipProcessor(opsTaskID, ccprClipPath, fScissor, *fCaps));
|
||||
}
|
||||
fCCPRClipPaths.reset();
|
||||
}
|
||||
@ -939,9 +932,10 @@ std::unique_ptr<GrFragmentProcessor> GrReducedClip::finishAndDetachAnalyticFPs(
|
||||
auto fp = as_SB(fShader)->asFragmentProcessor(args);
|
||||
if (fp) {
|
||||
fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::AAAA());
|
||||
fAnalyticFPs.push_back(std::move(fp));
|
||||
clipFPs.push_back(std::move(fp));
|
||||
}
|
||||
}
|
||||
|
||||
return GrFragmentProcessor::RunInSeries(fAnalyticFPs.begin(), fAnalyticFPs.count());
|
||||
return GrFragmentProcessor::RunInSeries(&clipFPs.front(), clipFPs.size());
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
bool drawAlphaClipMask(GrRenderTargetContext*) const;
|
||||
bool drawStencilClipMask(GrRecordingContext*, GrRenderTargetContext*) const;
|
||||
|
||||
int numAnalyticFPs() const { return fAnalyticFPs.count() + fCCPRClipPaths.count(); }
|
||||
int numAnalyticFPs() const;
|
||||
|
||||
/**
|
||||
* Called once the client knows the ID of the opsTask that the clip FPs will operate in. This
|
||||
@ -152,7 +152,7 @@ private:
|
||||
ElementList fMaskElements;
|
||||
uint32_t fMaskGenID;
|
||||
bool fMaskRequiresAA;
|
||||
SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fAnalyticFPs;
|
||||
std::unique_ptr<GrFragmentProcessor> fAnalyticFP;
|
||||
SkSTArray<4, SkPath> fCCPRClipPaths; // Will convert to FPs once we have an opsTask ID for CCPR.
|
||||
// Will be the combination of all kShader elements or null if there's no clip shader.
|
||||
// Does not count against the analytic FP limit.
|
||||
|
Loading…
Reference in New Issue
Block a user