ccpr: Remove GrCCDrawPathsOp's back-pointer into CCPR
Bug: skia:7988
Change-Id: Ia05173e90fa2cda28de6ae2a9aaee577eaf4bc65
Reviewed-on: https://skia-review.googlesource.com/129621
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
index 0c1b493..ee0dbde 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
@@ -13,8 +13,8 @@
#include "SkMakeUnique.h"
#include "SkPathOps.h"
#include "ccpr/GrCCClipProcessor.h"
+#include "ccpr/GrCCDrawPathsOp.h"
#include "ccpr/GrCCPathParser.h"
-#include "ccpr/GrCCPerFlushResources.h"
using PathInstance = GrCCPathProcessor::Instance;
@@ -47,14 +47,22 @@
return sk_sp<GrCoverageCountingPathRenderer>(ccpr);
}
-GrCoverageCountingPathRenderer::GrCoverageCountingPathRenderer(bool drawCachablePaths)
- : fDrawCachablePaths(drawCachablePaths) {
+GrCCPerOpListPaths* GrCoverageCountingPathRenderer::lookupPendingPaths(uint32_t opListID) {
+ auto it = fPendingPaths.find(opListID);
+ if (fPendingPaths.end() == it) {
+ auto paths = skstd::make_unique<GrCCPerOpListPaths>();
+ it = fPendingPaths.insert(std::make_pair(opListID, std::move(paths))).first;
+ }
+ return it->second.get();
}
-GrCoverageCountingPathRenderer::~GrCoverageCountingPathRenderer() {
- // Ensure no Ops exist that could have a dangling pointer back into this class.
- SkASSERT(fRTPendingPathsMap.empty());
- SkASSERT(0 == fNumOutstandingDrawOps);
+void GrCoverageCountingPathRenderer::adoptAndRecordOp(GrCCDrawPathsOp* op,
+ const DrawPathArgs& args) {
+ GrRenderTargetContext* rtc = args.fRenderTargetContext;
+ if (uint32_t opListID = rtc->addDrawOp(*args.fClip, std::unique_ptr<GrDrawOp>(op))) {
+ // If the Op wasn't dropped or combined, give it a pointer to its owning GrCCPerOpListPaths.
+ op->wasRecorded(this->lookupPendingPaths(opListID));
+ }
}
GrPathRenderer::CanDrawPath GrCoverageCountingPathRenderer::onCanDrawPath(
@@ -112,25 +120,17 @@
SkPath croppedPath;
path.transform(*args.fViewMatrix, &croppedPath);
crop_path(croppedPath, clipIBounds, &croppedPath);
- this->adoptAndRecordOp(new GrCCDrawPathsOp(this, std::move(args.fPaint), clipIBounds,
+ this->adoptAndRecordOp(new GrCCDrawPathsOp(std::move(args.fPaint), clipIBounds,
SkMatrix::I(), croppedPath,
croppedPath.getBounds()), args);
return true;
}
- this->adoptAndRecordOp(new GrCCDrawPathsOp(this, std::move(args.fPaint), clipIBounds,
+ this->adoptAndRecordOp(new GrCCDrawPathsOp(std::move(args.fPaint), clipIBounds,
*args.fViewMatrix, path, devBounds), args);
return true;
}
-void GrCoverageCountingPathRenderer::adoptAndRecordOp(GrCCDrawPathsOp* op,
- const DrawPathArgs& args) {
- GrRenderTargetContext* rtc = args.fRenderTargetContext;
- if (uint32_t opListID = rtc->addDrawOp(*args.fClip, std::unique_ptr<GrDrawOp>(op))) {
- op->wasRecorded(&fRTPendingPathsMap[opListID]);
- }
-}
-
std::unique_ptr<GrFragmentProcessor> GrCoverageCountingPathRenderer::makeClipProcessor(
GrProxyProvider* proxyProvider,
uint32_t opListID, const SkPath& deviceSpacePath, const SkIRect& accessRect,
@@ -140,7 +140,7 @@
SkASSERT(!fFlushing);
GrCCClipPath& clipPath =
- fRTPendingPathsMap[opListID].fClipPaths[deviceSpacePath.getGenerationID()];
+ this->lookupPendingPaths(opListID)->fClipPaths[deviceSpacePath.getGenerationID()];
if (!clipPath.isInitialized()) {
// This ClipPath was just created during lookup. Initialize it.
const SkRect& pathDevBounds = deviceSpacePath.getBounds();
@@ -166,56 +166,55 @@
const uint32_t* opListIDs, int numOpListIDs,
SkTArray<sk_sp<GrRenderTargetContext>>* atlasDraws) {
SkASSERT(!fFlushing);
- SkASSERT(!fPerFlushResources);
+ SkASSERT(fFlushingPaths.empty());
SkDEBUGCODE(fFlushing = true);
- if (fRTPendingPathsMap.empty()) {
+ if (fPendingPaths.empty()) {
return; // Nothing to draw.
}
- // Count up the paths about to be flushed so we can preallocate buffers.
+ // Move the per-opList paths that are about to be flushed from fPendingPaths to fFlushingPaths,
+ // and count up the paths about to be flushed so we can preallocate buffers.
int numPathDraws = 0;
int numClipPaths = 0;
GrCCPathParser::PathStats flushingPathStats;
- fFlushingRTPathIters.reserve(numOpListIDs);
+ fFlushingPaths.reserve(numOpListIDs);
for (int i = 0; i < numOpListIDs; ++i) {
- auto iter = fRTPendingPathsMap.find(opListIDs[i]);
- if (fRTPendingPathsMap.end() == iter) {
- continue;
+ auto iter = fPendingPaths.find(opListIDs[i]);
+ if (fPendingPaths.end() == iter) {
+ continue; // No paths on this opList.
}
- const GrCCRTPendingPaths& rtPendingPaths = iter->second;
- for (const GrCCDrawPathsOp* op : rtPendingPaths.fDrawOps) {
+ fFlushingPaths.push_back(std::move(iter->second)).get();
+ fPendingPaths.erase(iter);
+
+ for (const GrCCDrawPathsOp* op : fFlushingPaths.back()->fDrawOps) {
numPathDraws += op->countPaths(&flushingPathStats);
}
- for (const auto& clipsIter : rtPendingPaths.fClipPaths) {
+ for (const auto& clipsIter : fFlushingPaths.back()->fClipPaths) {
flushingPathStats.statPath(clipsIter.second.deviceSpacePath());
}
- numClipPaths += rtPendingPaths.fClipPaths.size();
-
- fFlushingRTPathIters.push_back(std::move(iter));
+ numClipPaths += fFlushingPaths.back()->fClipPaths.size();
}
if (0 == numPathDraws + numClipPaths) {
return; // Nothing to draw.
}
- auto resources = skstd::make_unique<GrCCPerFlushResources>(onFlushRP, numPathDraws,
- numClipPaths, flushingPathStats);
+ auto resources = sk_make_sp<GrCCPerFlushResources>(onFlushRP, numPathDraws, numClipPaths,
+ flushingPathStats);
if (!resources->isMapped()) {
return; // Some allocation failed.
}
// Layout atlas(es) and parse paths.
SkDEBUGCODE(int numSkippedPaths = 0);
- for (const auto& iter : fFlushingRTPathIters) {
- GrCCRTPendingPaths* rtPendingPaths = &iter->second;
-
- for (GrCCDrawPathsOp* op : rtPendingPaths->fDrawOps) {
+ for (const auto& flushingPaths : fFlushingPaths) {
+ for (GrCCDrawPathsOp* op : flushingPaths->fDrawOps) {
op->setupResources(resources.get(), onFlushRP);
SkDEBUGCODE(numSkippedPaths += op->numSkippedInstances_debugOnly());
}
- for (auto& clipsIter : rtPendingPaths->fClipPaths) {
+ for (auto& clipsIter : flushingPaths->fClipPaths) {
clipsIter.second.placePathInAtlas(resources.get(), onFlushRP);
}
}
@@ -226,17 +225,16 @@
return;
}
- fPerFlushResources = std::move(resources);
+ // Commit flushing paths to the resources once they are successfully completed.
+ for (auto& flushingPaths : fFlushingPaths) {
+ flushingPaths->fFlushResources = resources;
+ }
}
void GrCoverageCountingPathRenderer::postFlush(GrDeferredUploadToken, const uint32_t* opListIDs,
int numOpListIDs) {
SkASSERT(fFlushing);
- fPerFlushResources.reset();
// We wait to erase these until after flush, once Ops and FPs are done accessing their data.
- for (const auto& iter : fFlushingRTPathIters) {
- fRTPendingPathsMap.erase(iter);
- }
- fFlushingRTPathIters.reset();
+ fFlushingPaths.reset();
SkDEBUGCODE(fFlushing = false);
}