Rewrite tessellation atlases as normal render tasks
Rewrites tessellation atlases as normal render tasks instead of
"onFlush" tasks. These tasks get inserted into the DAG upfront, lay
out their atlases as dependent tasks get built and reference them, and
finally add their ops to render themselves during onMakeClosed. Doing it
this way allows us to pause the flush and re-render the atlas whenever
it runs out of room.
Bug: b/188794626
Bug: chromium:928984
Change-Id: Id59a5527924c63d5ff7c5bce46a88368e79fc3ef
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/420556
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Adlai Holler <adlai@google.com>
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 85cea19..6c71c4d 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -657,7 +657,8 @@
// activeTask does.
bool isActiveResolveTask =
fActiveOpsTask && fActiveOpsTask->fTextureResolveTask == fDAG[i].get();
- SkASSERT(isActiveResolveTask || fDAG[i]->isClosed());
+ bool isAtlas = fDAG[i]->isSetFlag(GrRenderTask::kAtlas_Flag);
+ SkASSERT(isActiveResolveTask || isAtlas || fDAG[i]->isClosed());
}
}
@@ -704,6 +705,32 @@
return opsTask;
}
+void GrDrawingManager::addAtlasTask(sk_sp<GrRenderTask> atlasTask,
+ GrRenderTask* previousAtlasTask) {
+ SkDEBUGCODE(this->validate());
+ SkASSERT(fContext);
+
+ if (previousAtlasTask) {
+ previousAtlasTask->makeClosed(fContext);
+ for (GrRenderTask* previousAtlasUser : previousAtlasTask->dependents()) {
+ // Make the new atlas depend on everybody who used the old atlas, and close their tasks.
+ // This guarantees that the previous atlas is totally out of service before we render
+ // the next one, meaning there is only ever one atlas active at a time and that they can
+ // all share the same texture.
+ atlasTask->addDependency(previousAtlasUser);
+ previousAtlasUser->makeClosed(fContext);
+ if (previousAtlasUser == fActiveOpsTask) {
+ fActiveOpsTask = nullptr;
+ }
+ }
+ }
+
+ atlasTask->setFlag(GrRenderTask::kAtlas_Flag);
+ this->insertTaskBeforeLast(std::move(atlasTask));
+
+ SkDEBUGCODE(this->validate());
+}
+
GrTextureResolveRenderTask* GrDrawingManager::newTextureResolveRenderTask(const GrCaps& caps) {
// Unlike in the "new opsTask" case, we do not want to close the active opsTask, nor (if we are
// in sorting and opsTask reduction mode) the render tasks that depend on any proxy's current