Improve API for skipping render tasks

This lets the user query if a task is skippable, makes
the naming clearer, and only calls the virtual once.

Bug: skia:10877
Change-Id: Ia8a7e0e3014d447bd8b4e914edf4f705a2ea107b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401856
Commit-Queue: Adlai Holler <[email protected]>
Auto-Submit: Adlai Holler <[email protected]>
Reviewed-by: Robert Phillips <[email protected]>
diff --git a/src/gpu/GrCopyRenderTask.h b/src/gpu/GrCopyRenderTask.h
index 756e598..f6e6e06 100644
--- a/src/gpu/GrCopyRenderTask.h
+++ b/src/gpu/GrCopyRenderTask.h
@@ -31,7 +31,7 @@
                      SkIPoint dstPoint,
                      GrSurfaceOrigin);
 
-    void onCanSkip() override { fSrc.reset(); }
+    void onMakeSkippable() override { fSrc.reset(); }
     bool onIsUsed(GrSurfaceProxy* proxy) const override { return proxy == fSrc.get(); }
     void gatherProxyIntervals(GrResourceAllocator*) const override;
     ExpectedOutcome onMakeClosed(const GrCaps&, SkIRect* targetUpdateBounds) override;
diff --git a/src/gpu/GrOpsTask.cpp b/src/gpu/GrOpsTask.cpp
index b6161e4..552f8a2 100644
--- a/src/gpu/GrOpsTask.cpp
+++ b/src/gpu/GrOpsTask.cpp
@@ -858,7 +858,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrOpsTask::onCanSkip() {
+void GrOpsTask::onMakeSkippable() {
     this->deleteOps();
     fDeferredProxies.reset();
     fColorLoadOp = GrLoadOp::kLoad;
diff --git a/src/gpu/GrOpsTask.h b/src/gpu/GrOpsTask.h
index 55f0caf..5556bbb 100644
--- a/src/gpu/GrOpsTask.h
+++ b/src/gpu/GrOpsTask.h
@@ -222,7 +222,7 @@
         SkRect fBounds;
     };
 
-    void onCanSkip() override;
+    void onMakeSkippable() override;
 
     bool onIsUsed(GrSurfaceProxy*) const override;
 
diff --git a/src/gpu/GrRenderTask.cpp b/src/gpu/GrRenderTask.cpp
index 1437e4f..9c8e06a 100644
--- a/src/gpu/GrRenderTask.cpp
+++ b/src/gpu/GrRenderTask.cpp
@@ -42,9 +42,12 @@
     }
 }
 
-void GrRenderTask::canSkip() {
+void GrRenderTask::makeSkippable() {
     SkASSERT(this->isClosed());
-    this->onCanSkip();
+    if (!this->isSkippable()) {
+        this->setFlag(kSkippable_Flag);
+        this->onMakeSkippable();
+    }
 }
 
 #ifdef SK_DEBUG
diff --git a/src/gpu/GrRenderTask.h b/src/gpu/GrRenderTask.h
index 16dedfd..08da5dc 100644
--- a/src/gpu/GrRenderTask.h
+++ b/src/gpu/GrRenderTask.h
@@ -53,7 +53,7 @@
     bool isClosed() const { return this->isSetFlag(kClosed_Flag); }
 
     /**
-     * A task can be marked as able to be skipped. It must be used purely for optimization purposes
+     * Make this task skippable. This must be used purely for optimization purposes
      * at this point as not all tasks will actually skip their work. It would be better if we could
      * detect tasks that can be skipped automatically. We'd need to support minimal flushes (i.e.,
      * only flush that which is required for SkSurfaces/SkImages) and the ability to detect
@@ -62,7 +62,9 @@
      * exported to the client in case the client is doing direct reads outside of Skia and thus
      * may require tasks targeting the proxy to execute even if our DAG contains no reads.
      */
-    void canSkip();
+    void makeSkippable();
+
+    bool isSkippable() const { return this->isSetFlag(kSkippable_Flag); }
 
     /*
      * Notify this GrRenderTask that it relies on the contents of 'dependedOn'
@@ -173,9 +175,10 @@
     enum Flags {
         kClosed_Flag    = 0x01,   //!< This task can't accept any more dependencies.
         kDisowned_Flag  = 0x02,   //!< This task is disowned by its creating GrDrawingManager.
+        kSkippable_Flag = 0x04,   //!< This task is skippable.
 
-        kWasOutput_Flag = 0x04,   //!< Flag for topological sorting
-        kTempMark_Flag  = 0x08,   //!< Flag for topological sorting
+        kWasOutput_Flag = 0x08,   //!< Flag for topological sorting
+        kTempMark_Flag  = 0x10,   //!< Flag for topological sorting
     };
 
     void setFlag(uint32_t flag) {
@@ -192,13 +195,13 @@
 
     void setIndex(uint32_t index) {
         SkASSERT(!this->isSetFlag(kWasOutput_Flag));
-        SkASSERT(index < (1 << 28));
-        fFlags |= index << 4;
+        SkASSERT(index < (1 << 27));
+        fFlags |= index << 5;
     }
 
     uint32_t getIndex() const {
         SkASSERT(this->isSetFlag(kWasOutput_Flag));
-        return fFlags >> 4;
+        return fFlags >> 5;
     }
 
 private:
@@ -246,9 +249,9 @@
         }
     };
 
-    virtual void onCanSkip() {}
-    virtual void onPrePrepare(GrRecordingContext*) {} // Only the GrOpsTask currently overrides this
-    virtual void onPrepare(GrOpFlushState*) {} // Only GrOpsTask and GrDDLTask override this virtual
+    virtual void onMakeSkippable() {}
+    virtual void onPrePrepare(GrRecordingContext*) {} // Only GrOpsTask currently overrides this
+    virtual void onPrepare(GrOpFlushState*) {} // GrOpsTask and GrDDLTask override this
     virtual bool onExecute(GrOpFlushState* flushState) = 0;
 
     const uint32_t         fUniqueID;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 022dc98..0687ff7 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -69,7 +69,7 @@
     // The image is being destroyed. If there is a stable copy proxy but we've been able to use
     // the volatile proxy for all requests then we can skip the copy.
     if (fVolatileToStableCopyTask) {
-        fVolatileToStableCopyTask->canSkip();
+        fVolatileToStableCopyTask->makeSkippable();
     }
 }
 
@@ -102,7 +102,7 @@
     SkAutoSpinlock hold(fLock);
     if (fVolatileProxy) {
         fStableProxy = std::move(fVolatileProxy);
-        fVolatileToStableCopyTask->canSkip();
+        fVolatileToStableCopyTask->makeSkippable();
         fVolatileToStableCopyTask.reset();
     }
     return fStableProxy;
diff --git a/tests/WrappedSurfaceCopyOnWriteTest.cpp b/tests/WrappedSurfaceCopyOnWriteTest.cpp
index 52fbad6..1a91568 100644
--- a/tests/WrappedSurfaceCopyOnWriteTest.cpp
+++ b/tests/WrappedSurfaceCopyOnWriteTest.cpp
@@ -110,7 +110,7 @@
         return;
     }
 
-    task->canSkip();
+    task->makeSkippable();
 
     SkAutoPixmapStorage pixels;
     pixels.alloc(SkImageInfo::Make({10, 10}, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
@@ -151,7 +151,7 @@
     temp->clear(SkPMColor4f{0, 0, 0, 0});
 
     GrSurfaceProxyView readView = dst->readSurfaceView();
-    task->canSkip();
+    task->makeSkippable();
 
     SkAutoPixmapStorage pixels;
     pixels.alloc(SkImageInfo::Make({10, 10}, kRGBA_8888_SkColorType, kPremul_SkAlphaType));