aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/private/SkDeferredDisplayList.h10
-rw-r--r--src/core/SkDeferredDisplayList.cpp7
-rw-r--r--src/gpu/GrContext.cpp1
-rw-r--r--src/gpu/GrDrawingManager.cpp12
-rw-r--r--src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp10
-rw-r--r--src/gpu/ccpr/GrCoverageCountingPathRenderer.h21
6 files changed, 51 insertions, 10 deletions
diff --git a/include/private/SkDeferredDisplayList.h b/include/private/SkDeferredDisplayList.h
index 4d379636a9..69e9def519 100644
--- a/include/private/SkDeferredDisplayList.h
+++ b/include/private/SkDeferredDisplayList.h
@@ -11,7 +11,10 @@
#include "SkSurfaceCharacterization.h"
#if SK_SUPPORT_GPU
+#include <map>
#include "GrOpList.h"
+
+struct GrCCPerOpListPaths;
#endif
class SkSurface;
@@ -22,7 +25,7 @@ class SkSurface;
*
* TODO: we probably need to expose this class so users can query it for memory usage.
*/
-class SkDeferredDisplayList {
+class SK_API SkDeferredDisplayList {
public:
#if SK_SUPPORT_GPU
@@ -42,6 +45,7 @@ public:
SkDeferredDisplayList(const SkSurfaceCharacterization& characterization,
sk_sp<LazyProxyData>);
+ ~SkDeferredDisplayList();
const SkSurfaceCharacterization& characterization() const {
return fCharacterization;
@@ -54,7 +58,11 @@ private:
const SkSurfaceCharacterization fCharacterization;
#if SK_SUPPORT_GPU
+ // This needs to match the same type in GrCoverageCountingPathRenderer.h
+ using PendingPathsMap = std::map<uint32_t, sk_sp<GrCCPerOpListPaths>>;
+
SkTArray<sk_sp<GrOpList>> fOpLists;
+ PendingPathsMap fPendingPaths; // This is the path data from CCPR.
#endif
sk_sp<LazyProxyData> fLazyProxyData;
};
diff --git a/src/core/SkDeferredDisplayList.cpp b/src/core/SkDeferredDisplayList.cpp
index 530523a4b6..6a4dc43406 100644
--- a/src/core/SkDeferredDisplayList.cpp
+++ b/src/core/SkDeferredDisplayList.cpp
@@ -10,8 +10,15 @@
#include "SkCanvas.h"
#include "SkSurface.h"
+#if SK_SUPPORT_GPU
+#include "ccpr/GrCoverageCountingPathRenderer.h"
+#endif
+
SkDeferredDisplayList::SkDeferredDisplayList(const SkSurfaceCharacterization& characterization,
sk_sp<LazyProxyData> lazyProxyData)
: fCharacterization(characterization)
, fLazyProxyData(std::move(lazyProxyData)) {
}
+
+SkDeferredDisplayList::~SkDeferredDisplayList() {
+}
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 572f58972b..3d57f9818d 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -113,7 +113,6 @@ bool GrContext::initCommon(const GrContextOptions& options) {
// Disable the small path renderer bc of the proxies in the atlas. They need to be
// unified when the opLists are added back to the destination drawing manager.
prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
- prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
}
GrTextContext::Options textContextOptions;
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 4391117248..a1df078d7b 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -26,6 +26,7 @@
#include "SkSurface_Gpu.h"
#include "SkTTopoSort.h"
#include "GrTracing.h"
+#include "ccpr/GrCoverageCountingPathRenderer.h"
#include "text/GrTextContext.h"
// Turn on/off the sorting of opLists at flush time
@@ -381,6 +382,11 @@ void GrDrawingManager::moveOpListsToDDL(SkDeferredDisplayList* ddl) {
}
ddl->fOpLists = std::move(fOpLists);
+ if (fPathRendererChain) {
+ if (auto ccpr = fPathRendererChain->getCoverageCountingPathRenderer()) {
+ ddl->fPendingPaths = ccpr->detachPendingPaths();
+ }
+ }
}
void GrDrawingManager::copyOpListsFromDDL(const SkDeferredDisplayList* ddl,
@@ -388,6 +394,12 @@ void GrDrawingManager::copyOpListsFromDDL(const SkDeferredDisplayList* ddl,
// Here we jam the proxy that backs the current replay SkSurface into the LazyProxyData.
// The lazy proxy that references it (in the copied opLists) will steal its GrTexture.
ddl->fLazyProxyData->fReplayDest = newDest;
+
+ if (ddl->fPendingPaths.size()) {
+ GrCoverageCountingPathRenderer* ccpr = this->getCoverageCountingPathRenderer();
+
+ ccpr->mergePendingPaths(ddl->fPendingPaths);
+ }
fOpLists.push_back_n(ddl->fOpLists.count(), ddl->fOpLists.begin());
}
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
index d51c0b525a..63e503b4c1 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
@@ -50,7 +50,7 @@ sk_sp<GrCoverageCountingPathRenderer> GrCoverageCountingPathRenderer::CreateIfSu
GrCCPerOpListPaths* GrCoverageCountingPathRenderer::lookupPendingPaths(uint32_t opListID) {
auto it = fPendingPaths.find(opListID);
if (fPendingPaths.end() == it) {
- auto paths = skstd::make_unique<GrCCPerOpListPaths>();
+ sk_sp<GrCCPerOpListPaths> paths = sk_make_sp<GrCCPerOpListPaths>();
it = fPendingPaths.insert(std::make_pair(opListID, std::move(paths))).first;
}
return it->second.get();
@@ -227,6 +227,7 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
// Commit flushing paths to the resources once they are successfully completed.
for (auto& flushingPaths : fFlushingPaths) {
+ SkASSERT(!flushingPaths->fFlushResources);
flushingPaths->fFlushResources = resources;
}
}
@@ -234,6 +235,13 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
void GrCoverageCountingPathRenderer::postFlush(GrDeferredUploadToken, const uint32_t* opListIDs,
int numOpListIDs) {
SkASSERT(fFlushing);
+
+ // In DDL mode these aren't guaranteed to be deleted so we must clear out the perFlush
+ // resources manually.
+ for (auto& flushingPaths : fFlushingPaths) {
+ flushingPaths->fFlushResources = nullptr;
+ }
+
// We wait to erase these until after flush, once Ops and FPs are done accessing their data.
fFlushingPaths.reset();
SkDEBUGCODE(fFlushing = false);
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h
index d10186601c..66374ea007 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h
@@ -21,7 +21,8 @@ class GrCCDrawPathsOp;
/**
* Tracks all the paths in a given opList that will be drawn when it flushes.
*/
-struct GrCCPerOpListPaths {
+// DDL TODO: given the usage pattern in DDL mode, this could probably be non-atomic refcounting.
+struct GrCCPerOpListPaths : SkRefCnt {
~GrCCPerOpListPaths() {
// Ensure there are no surviving DrawPathsOps with a dangling pointer into this class.
if (!fDrawOps.isEmpty()) {
@@ -57,17 +58,23 @@ public:
SkASSERT(!fFlushing);
}
- using PendingPathsMap = std::map<uint32_t, std::unique_ptr<GrCCPerOpListPaths>>;
+ using PendingPathsMap = std::map<uint32_t, sk_sp<GrCCPerOpListPaths>>;
// In DDL mode, Ganesh needs to be able to move the pending GrCCPerOpListPaths to the DDL object
// (detachPendingPaths) and then return them upon replay (mergePendingPaths).
PendingPathsMap detachPendingPaths() { return std::move(fPendingPaths); }
- void mergePendingPaths(PendingPathsMap&& paths) {
+ void mergePendingPaths(const PendingPathsMap& paths) {
+#ifdef SK_DEBUG
// Ensure there are no duplicate opList IDs between the incoming path map and ours.
- SkDEBUGCODE(for (const auto& it : paths) SkASSERT(!fPendingPaths.count(it.first)));
- fPendingPaths.insert(std::make_move_iterator(paths.begin()),
- std::make_move_iterator(paths.end()));
+ // This should always be true since opList IDs are globally unique and these are coming
+ // from different DDL recordings.
+ for (const auto& it : paths) {
+ SkASSERT(!fPendingPaths.count(it.first));
+ }
+#endif
+
+ fPendingPaths.insert(paths.begin(), paths.end());
}
// GrPathRenderer overrides.
@@ -101,7 +108,7 @@ private:
// fFlushingPaths holds the GrCCPerOpListPaths objects that are currently being flushed.
// (It will only contain elements when fFlushing is true.)
- SkSTArray<4, std::unique_ptr<GrCCPerOpListPaths>> fFlushingPaths;
+ SkSTArray<4, sk_sp<GrCCPerOpListPaths>> fFlushingPaths;
SkDEBUGCODE(bool fFlushing = false);
const bool fDrawCachablePaths;