Reland "Initiate regeneration of mipmaps from proxy DAG land"
This is a reland of fe19203eb7d7e8bef528287494d82c2eb4efff0e
Original change's description:
> 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>
Change-Id: Ic904d0b1bcb451bcb74cfae2204fb7297eaff108
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/234016
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrTextureResolveRenderTask.cpp b/src/gpu/GrTextureResolveRenderTask.cpp
new file mode 100644
index 0000000..08df318
--- /dev/null
+++ b/src/gpu/GrTextureResolveRenderTask.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/gpu/GrTextureResolveRenderTask.h"
+
+#include "src/gpu/GrGpu.h"
+#include "src/gpu/GrMemoryPool.h"
+#include "src/gpu/GrOpFlushState.h"
+#include "src/gpu/GrResourceAllocator.h"
+#include "src/gpu/GrTexturePriv.h"
+
+sk_sp<GrRenderTask> GrTextureResolveRenderTask::Make(
+ sk_sp<GrTextureProxy> textureProxyPtr, GrTextureResolveFlags flags, const GrCaps& caps) {
+ GrTextureProxy* textureProxy = textureProxyPtr.get();
+ sk_sp<GrTextureResolveRenderTask> resolveTask(
+ new GrTextureResolveRenderTask(std::move(textureProxyPtr), flags));
+
+ // Add the target as a dependency: We will read the existing contents of this texture while
+ // generating mipmap levels and/or resolving MSAA.
+ //
+ // NOTE: This must be called before makeClosed.
+ resolveTask->addDependency(
+ textureProxy, GrMipMapped::kNo, GrTextureResolveManager(nullptr), caps);
+ textureProxy->setLastRenderTask(resolveTask.get());
+
+ // We only resolve the texture; nobody should try to do anything else with this opList.
+ resolveTask->makeClosed(caps);
+
+ if (GrTextureResolveFlags::kMipMaps & flags) {
+ SkASSERT(GrMipMapped::kYes == textureProxy->mipMapped());
+ SkASSERT(textureProxy->mipMapsAreDirty());
+ textureProxy->markMipMapsClean();
+ }
+
+ // On some old ISO C++11 compilers, 'resolveTask' will require an explicit std::move() when
+ // returned from this function. This is because its type (sk_sp<GrTextureResolveRenderTask>)
+ // does not match the return type (sk_sp<GrRenderTask>).
+ return std::move(resolveTask);
+}
+
+void GrTextureResolveRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
+ // This renderTask doesn't have "normal" ops. In this case we still need to add an interval (so
+ // fEndOfOpListOpIndices will remain in sync), so we create a fake op# to capture the fact that
+ // we manipulate fTarget.
+ alloc->addInterval(fTarget.get(), alloc->curOp(), alloc->curOp(),
+ GrResourceAllocator::ActualUse::kYes);
+ alloc->incOps();
+}
+
+bool GrTextureResolveRenderTask::onExecute(GrOpFlushState* flushState) {
+ GrTexture* texture = fTarget->peekTexture();
+ SkASSERT(texture);
+
+ if (GrTextureResolveFlags::kMipMaps & fResolveFlags) {
+ SkASSERT(texture->texturePriv().mipMapsAreDirty());
+ flushState->gpu()->regenerateMipMapLevels(texture);
+ }
+
+ return true;
+}