Initiate regeneration of mipmaps from proxy DAG land
This allows us to resolve all the textures before executing a command
buffer, rather than interrupting execution as is currently done in the
GL backend.
Change-Id: I998546b312d24cf47fc2c837e7c94fbf95571af0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/230636
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrRenderTask.cpp b/src/gpu/GrRenderTask.cpp
index 66b6c3e..3b572fc 100644
--- a/src/gpu/GrRenderTask.cpp
+++ b/src/gpu/GrRenderTask.cpp
@@ -24,7 +24,6 @@
: fTarget(std::move(target))
, fUniqueID(CreateUniqueID())
, fFlags(0) {
- fTarget->setLastRenderTask(this);
}
GrRenderTask::~GrRenderTask() {
@@ -69,13 +68,44 @@
}
// Convert from a GrSurface-based dependency to a GrRenderTask one
-void GrRenderTask::addDependency(GrSurfaceProxy* dependedOn, GrMipMapped, GrTextureResolveManager,
+void GrRenderTask::addDependency(GrSurfaceProxy* dependedOn, GrMipMapped mipMapped,
+ GrTextureResolveManager textureResolveManager,
const GrCaps& caps) {
- if (dependedOn->getLastRenderTask()) {
+ GrRenderTask* dependedOnTask = dependedOn->getLastRenderTask();
+
+ GrTextureProxy* textureProxy = dependedOn->asTextureProxy();
+ SkASSERT(GrMipMapped::kNo == mipMapped || textureProxy);
+
+ // Does this proxy have mipmaps that need to be regenerated?
+ if (GrMipMapped::kYes == mipMapped && textureProxy->mipMapsAreDirty()) {
+ // We only read our own target during dst reads, and we shouldn't use mipmaps in that case.
+ SkASSERT(dependedOnTask != this);
+
+ // Create an opList that resolves the texture's mipmap data.
+ GrRenderTask* textureResolveTask = textureResolveManager.newTextureResolveRenderTask(
+ sk_ref_sp(textureProxy), GrTextureResolveFlags::kMipMaps, caps);
+
+ // The GrTextureResolveRenderTask factory should have called addDependency (in this
+ // instance, recursively) on the textureProxy.
+ SkASSERT(!dependedOnTask || textureResolveTask->dependsOn(dependedOnTask));
+ SkASSERT(!textureProxy->texPriv().isDeferred() ||
+ textureResolveTask->fDeferredProxies.back() == textureProxy);
+
+ // The GrTextureResolveRenderTask factory should have also marked the mipmaps clean and set
+ // the last opList on the textureProxy to textureResolveTask.
+ SkASSERT(!textureProxy->mipMapsAreDirty());
+ SkASSERT(textureProxy->getLastRenderTask() == textureResolveTask);
+
+ // Fall through and add textureResolveTask as a dependency of "this".
+ dependedOnTask = textureResolveTask;
+ } else if (textureProxy && textureProxy->texPriv().isDeferred()) {
+ fDeferredProxies.push_back(textureProxy);
+ }
+
+ if (dependedOnTask) {
// If it is still receiving dependencies, this GrRenderTask shouldn't be closed
SkASSERT(!this->isClosed());
- GrRenderTask* dependedOnTask = dependedOn->getLastRenderTask();
if (dependedOnTask == this) {
// self-read - presumably for dst reads. We can't make it closed in the self-read case.
} else {
@@ -87,12 +117,6 @@
dependedOnTask->makeClosed(caps);
}
}
-
- if (GrTextureProxy* textureProxy = dependedOn->asTextureProxy()) {
- if (textureProxy->texPriv().isDeferred()) {
- fDeferredProxies.push_back(textureProxy);
- }
- }
}
bool GrRenderTask::dependsOn(const GrRenderTask* dependedOn) const {