Revert "remove fAllocators from GrOpsTask"
This reverts commit f00d6a8efd723ecccda716d0360df49bdc48feaa.
Reason for revert: In the long run, it seems like this might leak.
Original change's description:
> remove fAllocators from GrOpsTask
>
> Change-Id: I5901f005c2758a92692e5cd70ba46a2b5ad797fd
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/393116
> Commit-Queue: Herb Derby <herb@google.com>
> Reviewed-by: Adlai Holler <adlai@google.com>
> Reviewed-by: Chris Dalton <csmartdalton@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>
TBR=herb@google.com,robertphillips@google.com,csmartdalton@google.com,adlai@google.com
Change-Id: I895e47c999c6961fa14c356d6d5bde80dd86b63e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/393176
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/gpu/GrOpsTask.cpp b/src/gpu/GrOpsTask.cpp
index 0db04fc..2d106d1 100644
--- a/src/gpu/GrOpsTask.cpp
+++ b/src/gpu/GrOpsTask.cpp
@@ -363,6 +363,7 @@
, fTargetOrigin(view.origin())
, fArenas{std::move(arenas)}
SkDEBUGCODE(, fNumClips(0)) {
+ fAllocators.push_back(std::make_unique<SkArenaAlloc>(4096));
this->addTarget(drawingMgr, view.detachProxy());
}
@@ -425,6 +426,7 @@
void GrOpsTask::endFlush(GrDrawingManager* drawingMgr) {
fLastClipStackGenID = SK_InvalidUniqueID;
this->deleteOps();
+ fAllocators.reset();
fDeferredProxies.reset();
fSampledProxies.reset();
@@ -671,6 +673,7 @@
void GrOpsTask::reset() {
fDeferredProxies.reset();
fSampledProxies.reset();
+ fAllocators.reset();
fClippedContentBounds = SkIRect::MakeEmpty();
fTotalBounds = SkRect::MakeEmpty();
this->deleteOps();
@@ -686,7 +689,6 @@
if (!opsTask || opsTask->target(0) != this->target(0)) {
break;
}
- SkASSERT(this->fArenas == opsTask->fArenas);
SkASSERT(fTargetSwizzle == opsTask->fTargetSwizzle);
SkASSERT(fTargetOrigin == opsTask->fTargetOrigin);
if (GrLoadOp::kClear == opsTask->fColorLoadOp) {
@@ -735,6 +737,7 @@
fDeferredProxies.reserve_back(addlDeferredProxyCount);
fSampledProxies.reserve_back(addlProxyCount);
fOpChains.reserve_back(addlOpChainCount);
+ fAllocators.reserve_back(opsTasks.count());
for (const auto& opsTask : opsTasks) {
fDeferredProxies.move_back_n(opsTask->fDeferredProxies.count(),
opsTask->fDeferredProxies.data());
@@ -742,6 +745,9 @@
opsTask->fSampledProxies.data());
fOpChains.move_back_n(opsTask->fOpChains.count(),
opsTask->fOpChains.data());
+ SkASSERT(1 == opsTask->fAllocators.count());
+ fAllocators.push_back(std::move(opsTask->fAllocators[0]));
+ opsTask->fAllocators.reset();
opsTask->fDeferredProxies.reset();
opsTask->fSampledProxies.reset();
opsTask->fOpChains.reset();
@@ -963,7 +969,7 @@
while (true) {
OpChain& candidate = fOpChains.fromBack(i);
op = candidate.appendOp(std::move(op), processorAnalysis, dstProxyView, clip, caps,
- fArenas->arenaAlloc(), fAuditTrail);
+ fAllocators.front().get(), fAuditTrail);
if (!op) {
return;
}
@@ -982,7 +988,7 @@
GrOP_INFO("\t\tBackward: FirstOp\n");
}
if (clip) {
- clip = fArenas->arenaAlloc()->make<GrAppliedClip>(std::move(*clip));
+ clip = fAllocators[0]->make<GrAppliedClip>(std::move(*clip));
SkDEBUGCODE(fNumClips++;)
}
fOpChains.emplace_back(std::move(op), processorAnalysis, clip, dstProxyView);
@@ -998,7 +1004,7 @@
int j = i + 1;
while (true) {
OpChain& candidate = fOpChains[j];
- if (candidate.prependChain(&chain, caps, fArenas->arenaAlloc(), fAuditTrail)) {
+ if (candidate.prependChain(&chain, caps, fAllocators.front().get(), fAuditTrail)) {
break;
}
// Stop traversing if we would cause a painter's order violation.
diff --git a/src/gpu/GrOpsTask.h b/src/gpu/GrOpsTask.h
index 967adb1..8ec0595 100644
--- a/src/gpu/GrOpsTask.h
+++ b/src/gpu/GrOpsTask.h
@@ -272,6 +272,9 @@
// For ops/opsTask we have mean: 5 stdDev: 28
SkSTArray<25, OpChain> fOpChains;
+ // MDB TODO: 4096 for the first allocation may be huge overkill. Gather statistics to determine
+ // the correct size.
+ SkSTArray<1, std::unique_ptr<SkArenaAlloc>> fAllocators;
sk_sp<GrArenas> fArenas;
SkDEBUGCODE(int fNumClips;)
diff --git a/tests/GrCCPRTest.cpp b/tests/GrCCPRTest.cpp
index 1a1f82e..f8aae59 100644
--- a/tests/GrCCPRTest.cpp
+++ b/tests/GrCCPRTest.cpp
@@ -169,6 +169,22 @@
void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override {
REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+ // Ensure paths get unreffed.
+ for (int i = 0; i < 10; ++i) {
+ ccpr.clipFullscreenRect(fPath);
+ }
+ REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
+ ccpr.flush();
+ REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+
+ // Ensure clip paths get unreffed.
+ for (int i = 0; i < 10; ++i) {
+ ccpr.clipFullscreenRect(fPath);
+ }
+ REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
+ ccpr.flush();
+ REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+
// Ensure paths get unreffed when we delete the context without flushing.
for (int i = 0; i < 10; ++i) {
ccpr.clipFullscreenRect(fPath);
@@ -230,6 +246,26 @@
};
DEF_CCPR_TEST(CCPR_parseEmptyPath)
+class CCPR_unrefPerOpsTaskPathsBeforeOps : public CCPRTest {
+ void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override {
+ REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+ for (int i = 0; i < 10000; ++i) {
+ // Draw enough paths to make the arena allocator hit the heap.
+ ccpr.clipFullscreenRect(fPath);
+ }
+
+ // Unref the GrCCPerOpsTaskPaths object.
+ auto perOpsTaskPathsMap = ccpr.ccpr()->detachPendingPaths();
+ perOpsTaskPathsMap.clear();
+
+ // Now delete the Op and all its draws.
+ REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
+ ccpr.flush();
+ REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
+ }
+};
+DEF_CCPR_TEST(CCPR_unrefPerOpsTaskPathsBeforeOps)
+
class CCPRRenderingTest {
public:
void run(skiatest::Reporter* reporter, GrDirectContext* dContext) const {