Migrate flush & misc methods to GrDirectContext

More cut and paste work.

Change-Id: I0dfc822ae168e15c6734a6c079bb930fc0fa9e60
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/325618
Commit-Queue: Adlai Holler <adlai@google.com>
Auto-Submit: Adlai Holler <adlai@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrDirectContext.h b/include/gpu/GrDirectContext.h
index 9ec2f86..38051fc 100644
--- a/include/gpu/GrDirectContext.h
+++ b/include/gpu/GrDirectContext.h
@@ -274,6 +274,105 @@
      */
     using GrRecordingContext::maxSurfaceSampleCountForColorType;
 
+    ///////////////////////////////////////////////////////////////////////////
+    // Misc.
+
+    /**
+     * Inserts a list of GPU semaphores that the current GPU-backed API must wait on before
+     * executing any more commands on the GPU. If this call returns false, then the GPU back-end
+     * will not wait on any passed in semaphores, and the client will still own the semaphores,
+     * regardless of the value of deleteSemaphoresAfterWait.
+     *
+     * If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case
+     * it is the client's responsibility to not destroy or attempt to reuse the semaphores until it
+     * knows that Skia has finished waiting on them. This can be done by using finishedProcs on
+     * flush calls.
+     */
+    bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores,
+              bool deleteSemaphoresAfterWait = true);
+
+    /**
+     * Call to ensure all drawing to the context has been flushed and submitted to the underlying 3D
+     * API. This is equivalent to calling GrContext::flush with a default GrFlushInfo followed by
+     * GrContext::submit(syncCpu).
+     */
+    void flushAndSubmit(bool syncCpu = false) {
+        this->flush(GrFlushInfo());
+        this->submit(syncCpu);
+    }
+
+    /**
+     * Call to ensure all drawing to the context has been flushed to underlying 3D API specific
+     * objects. A call to `submit` is always required to ensure work is actually sent to
+     * the gpu. Some specific API details:
+     *     GL: Commands are actually sent to the driver, but glFlush is never called. Thus some
+     *         sync objects from the flush will not be valid until a submission occurs.
+     *
+     *     Vulkan/Metal/D3D/Dawn: Commands are recorded to the backend APIs corresponding command
+     *         buffer or encoder objects. However, these objects are not sent to the gpu until a
+     *         submission occurs.
+     *
+     * If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will be
+     * submitted to the gpu during the next submit call (it is possible Skia failed to create a
+     * subset of the semaphores). The client should not wait on these semaphores until after submit
+     * has been called, and must keep them alive until then. If this call returns
+     * GrSemaphoresSubmitted::kNo, the GPU backend will not submit any semaphores to be signaled on
+     * the GPU. Thus the client should not have the GPU wait on any of the semaphores passed in with
+     * the GrFlushInfo. Regardless of whether semaphores were submitted to the GPU or not, the
+     * client is still responsible for deleting any initialized semaphores.
+     * Regardleess of semaphore submission the context will still be flushed. It should be
+     * emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not
+     * happen. It simply means there were no semaphores submitted to the GPU. A caller should only
+     * take this as a failure if they passed in semaphores to be submitted.
+     */
+    GrSemaphoresSubmitted flush(const GrFlushInfo& info);
+
+    void flush() { this->flush({}); }
+
+    /**
+     * Submit outstanding work to the gpu from all previously un-submitted flushes. The return
+     * value of the submit will indicate whether or not the submission to the GPU was successful.
+     *
+     * If the call returns true, all previously passed in semaphores in flush calls will have been
+     * submitted to the GPU and they can safely be waited on. The caller should wait on those
+     * semaphores or perform some other global synchronization before deleting the semaphores.
+     *
+     * If it returns false, then those same semaphores will not have been submitted and we will not
+     * try to submit them again. The caller is free to delete the semaphores at any time.
+     *
+     * If the syncCpu flag is true this function will return once the gpu has finished with all
+     * submitted work.
+     */
+    bool submit(bool syncCpu = false);
+
+    /**
+     * Checks whether any asynchronous work is complete and if so calls related callbacks.
+     */
+    void checkAsyncWorkCompletion();
+
+    /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
+    // Chrome is using this!
+    void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
+
+    bool supportsDistanceFieldText() const;
+
+    void storeVkPipelineCacheData();
+
+    // Returns the gpu memory size of the the texture that backs the passed in SkImage. Returns 0 if
+    // the SkImage is not texture backed. For external format textures this will also return 0 as we
+    // cannot determine the correct size.
+    static size_t ComputeImageSize(sk_sp<SkImage> image, GrMipmapped, bool useNextPow2 = false);
+
+    /**
+     * Retrieve the default GrBackendFormat for a given SkColorType and renderability.
+     * It is guaranteed that this backend format will be the one used by the following
+     * SkColorType and SkSurfaceCharacterization-based createBackendTexture methods.
+     *
+     * The caller should check that the returned format is valid.
+     */
+    GrBackendFormat defaultBackendFormat(SkColorType ct, GrRenderable renderable) const {
+        return INHERITED::defaultBackendFormat(ct, renderable);
+    }
 protected:
     GrDirectContext(GrBackendApi backend, const GrContextOptions& options);
 
diff --git a/include/private/GrContext.h b/include/private/GrContext.h
index 92c5eea..3da11b0 100644
--- a/include/private/GrContext.h
+++ b/include/private/GrContext.h
@@ -57,110 +57,6 @@
 public:
     ~GrContext() override;
 
-    ///////////////////////////////////////////////////////////////////////////
-    // Misc.
-
-    /**
-     * Inserts a list of GPU semaphores that the current GPU-backed API must wait on before
-     * executing any more commands on the GPU. If this call returns false, then the GPU back-end
-     * will not wait on any passed in semaphores, and the client will still own the semaphores,
-     * regardless of the value of deleteSemaphoresAfterWait.
-     *
-     * If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case
-     * it is the client's responsibility to not destroy or attempt to reuse the semaphores until it
-     * knows that Skia has finished waiting on them. This can be done by using finishedProcs on
-     * flush calls.
-     */
-    bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores,
-              bool deleteSemaphoresAfterWait = true);
-
-    /**
-     * Call to ensure all drawing to the context has been flushed and submitted to the underlying 3D
-     * API. This is equivalent to calling GrContext::flush with a default GrFlushInfo followed by
-     * GrContext::submit(syncCpu).
-     */
-    void flushAndSubmit(bool syncCpu = false) {
-        this->flush(GrFlushInfo());
-        this->submit(syncCpu);
-    }
-
-    /**
-     * Call to ensure all drawing to the context has been flushed to underlying 3D API specific
-     * objects. A call to GrContext::submit is always required to ensure work is actually sent to
-     * the gpu. Some specific API details:
-     *     GL: Commands are actually sent to the driver, but glFlush is never called. Thus some
-     *         sync objects from the flush will not be valid until a submission occurs.
-     *
-     *     Vulkan/Metal/D3D/Dawn: Commands are recorded to the backend APIs corresponding command
-     *         buffer or encoder objects. However, these objects are not sent to the gpu until a
-     *         submission occurs.
-     *
-     * If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will be
-     * submitted to the gpu during the next submit call (it is possible Skia failed to create a
-     * subset of the semaphores). The client should not wait on these semaphores until after submit
-     * has been called, and must keep them alive until then. If this call returns
-     * GrSemaphoresSubmitted::kNo, the GPU backend will not submit any semaphores to be signaled on
-     * the GPU. Thus the client should not have the GPU wait on any of the semaphores passed in with
-     * the GrFlushInfo. Regardless of whether semaphores were submitted to the GPU or not, the
-     * client is still responsible for deleting any initialized semaphores.
-     * Regardleess of semaphore submission the context will still be flushed. It should be
-     * emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not
-     * happen. It simply means there were no semaphores submitted to the GPU. A caller should only
-     * take this as a failure if they passed in semaphores to be submitted.
-     */
-    GrSemaphoresSubmitted flush(const GrFlushInfo& info);
-
-    void flush() { this->flush({}); }
-
-    /**
-     * Submit outstanding work to the gpu from all previously un-submitted flushes. The return
-     * value of the submit will indicate whether or not the submission to the GPU was successful.
-     *
-     * If the call returns true, all previously passed in semaphores in flush calls will have been
-     * submitted to the GPU and they can safely be waited on. The caller should wait on those
-     * semaphores or perform some other global synchronization before deleting the semaphores.
-     *
-     * If it returns false, then those same semaphores will not have been submitted and we will not
-     * try to submit them again. The caller is free to delete the semaphores at any time.
-     *
-     * If the syncCpu flag is true this function will return once the gpu has finished with all
-     * submitted work.
-     */
-    bool submit(bool syncCpu = false);
-
-    /**
-     * Checks whether any asynchronous work is complete and if so calls related callbacks.
-     */
-    void checkAsyncWorkCompletion();
-
-    // Provides access to functions that aren't part of the public API.
-    GrContextPriv priv();
-    const GrContextPriv priv() const;  // NOLINT(readability-const-return-type)
-
-    /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
-    // Chrome is using this!
-    void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
-
-    bool supportsDistanceFieldText() const;
-
-    void storeVkPipelineCacheData();
-
-    // Returns the gpu memory size of the the texture that backs the passed in SkImage. Returns 0 if
-    // the SkImage is not texture backed. For external format textures this will also return 0 as we
-    // cannot determine the correct size.
-    static size_t ComputeImageSize(sk_sp<SkImage> image, GrMipmapped, bool useNextPow2 = false);
-
-    /**
-     * Retrieve the default GrBackendFormat for a given SkColorType and renderability.
-     * It is guaranteed that this backend format will be the one used by the following
-     * SkColorType and SkSurfaceCharacterization-based createBackendTexture methods.
-     *
-     * The caller should check that the returned format is valid.
-     */
-    GrBackendFormat defaultBackendFormat(SkColorType ct, GrRenderable renderable) const {
-        return INHERITED::defaultBackendFormat(ct, renderable);
-    }
-
    /**
     * The explicitly allocated backend texture API allows clients to use Skia to create backend
     * objects outside of Skia proper (i.e., Skia's caching system will not know about them.)
@@ -478,6 +374,9 @@
     SkString dump() const;
 #endif
 
+    // Provides access to functions that aren't part of the public API.
+    GrContextPriv priv();
+    const GrContextPriv priv() const;  // NOLINT(readability-const-return-type)
 protected:
     GrContext(sk_sp<GrContextThreadSafeProxy>);
 
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 183cd59..575adf9 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -48,114 +48,10 @@
 #define RETURN_FALSE_IF_ABANDONED if (this->abandoned()) { return false; }
 #define RETURN_NULL_IF_ABANDONED if (this->abandoned()) { return nullptr; }
 
-////////////////////////////////////////////////////////////////////////////////
-
 GrContext::GrContext(sk_sp<GrContextThreadSafeProxy> proxy) : INHERITED(std::move(proxy)) { }
 
 GrContext::~GrContext() = default;
 
-size_t GrContext::ComputeImageSize(sk_sp<SkImage> image, GrMipmapped mipMapped, bool useNextPow2) {
-    if (!image->isTextureBacked()) {
-        return 0;
-    }
-    SkImage_GpuBase* gpuImage = static_cast<SkImage_GpuBase*>(as_IB(image.get()));
-    GrTextureProxy* proxy = gpuImage->peekProxy();
-    if (!proxy) {
-        return 0;
-    }
-
-    int colorSamplesPerPixel = 1;
-    return GrSurface::ComputeSize(proxy->backendFormat(), image->dimensions(),
-                                  colorSamplesPerPixel, mipMapped, useNextPow2);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-bool GrContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
-                     bool deleteSemaphoresAfterWait) {
-    if (!fGpu || fGpu->caps()->semaphoreSupport()) {
-        return false;
-    }
-    GrWrapOwnership ownership =
-            deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;
-    for (int i = 0; i < numSemaphores; ++i) {
-        std::unique_ptr<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
-                waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait, ownership);
-        // If we failed to wrap the semaphore it means the client didn't give us a valid semaphore
-        // to begin with. Therefore, it is fine to not wait on it.
-        if (sema) {
-            fGpu->waitSemaphore(sema.get());
-        }
-    }
-    return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-GrSemaphoresSubmitted GrContext::flush(const GrFlushInfo& info) {
-    ASSERT_SINGLE_OWNER
-    if (this->abandoned()) {
-        if (info.fFinishedProc) {
-            info.fFinishedProc(info.fFinishedContext);
-        }
-        if (info.fSubmittedProc) {
-            info.fSubmittedProc(info.fSubmittedContext, false);
-        }
-        return GrSemaphoresSubmitted::kNo;
-    }
-
-    bool flushed = this->drawingManager()->flush(
-            nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess, info, nullptr);
-
-    if (!flushed || (!this->priv().caps()->semaphoreSupport() && info.fNumSemaphores)) {
-        return GrSemaphoresSubmitted::kNo;
-    }
-    return GrSemaphoresSubmitted::kYes;
-}
-
-bool GrContext::submit(bool syncCpu) {
-    ASSERT_SINGLE_OWNER
-    if (this->abandoned()) {
-        return false;
-    }
-
-    if (!fGpu) {
-        return false;
-    }
-
-    return fGpu->submitToGpu(syncCpu);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::checkAsyncWorkCompletion() {
-    if (fGpu) {
-        fGpu->checkFinishProcs();
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrContext::storeVkPipelineCacheData() {
-    if (fGpu) {
-        fGpu->storeVkPipelineCacheData();
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool GrContext::supportsDistanceFieldText() const {
-    return this->caps()->shaderCaps()->supportsDistanceFieldText();
-}
-
-//////////////////////////////////////////////////////////////////////////////
-void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
-    ASSERT_SINGLE_OWNER
-    fResourceCache->dumpMemoryStatistics(traceMemoryDump);
-    traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
-                                      this->getTextBlobCache()->usedBytes());
-}
-
-//////////////////////////////////////////////////////////////////////////////
 GrBackendTexture GrContext::createBackendTexture(int width, int height,
                                                  const GrBackendFormat& backendFormat,
                                                  GrMipmapped mipMapped,
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index 5967304..476da52 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -173,7 +173,7 @@
 }
 
 void GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
-    fContext->flushAndSubmit();
+    fContext->asDirectContext()->flushAndSubmit();
     fContext->drawingManager()->testingOnly_removeOnFlushCallbackObject(cb);
 }
 #endif
diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp
index f2e8f3f..78fa9ab 100644
--- a/src/gpu/GrDirectContext.cpp
+++ b/src/gpu/GrDirectContext.cpp
@@ -8,6 +8,7 @@
 
 #include "include/gpu/GrDirectContext.h"
 
+#include "include/core/SkTraceMemoryDump.h"
 #include "include/gpu/GrContextThreadSafeProxy.h"
 #include "src/core/SkTaskGroup.h"
 #include "src/gpu/GrClientMappedBufferManager.h"
@@ -17,6 +18,7 @@
 #include "src/gpu/GrGpu.h"
 #include "src/gpu/GrResourceProvider.h"
 #include "src/gpu/GrShaderUtils.h"
+#include "src/image/SkImage_GpuBase.h"
 
 #include "src/gpu/ccpr/GrCoverageCountingPathRenderer.h"
 #include "src/gpu/effects/GrSkSLFP.h"
@@ -330,6 +332,25 @@
     fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+bool GrDirectContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
+                           bool deleteSemaphoresAfterWait) {
+    if (!fGpu || fGpu->caps()->semaphoreSupport()) {
+        return false;
+    }
+    GrWrapOwnership ownership =
+            deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;
+    for (int i = 0; i < numSemaphores; ++i) {
+        std::unique_ptr<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
+                waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait, ownership);
+        // If we failed to wrap the semaphore it means the client didn't give us a valid semaphore
+        // to begin with. Therefore, it is fine to not wait on it.
+        if (sema) {
+            fGpu->waitSemaphore(sema.get());
+        }
+    }
+    return true;
+}
 
 GrSmallPathAtlasMgr* GrDirectContext::onGetSmallPathAtlasMgr() {
     if (!fSmallPathAtlasMgr) {
@@ -345,6 +366,89 @@
     return fSmallPathAtlasMgr.get();
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+GrSemaphoresSubmitted GrDirectContext::flush(const GrFlushInfo& info) {
+    ASSERT_SINGLE_OWNER
+    if (this->abandoned()) {
+        if (info.fFinishedProc) {
+            info.fFinishedProc(info.fFinishedContext);
+        }
+        if (info.fSubmittedProc) {
+            info.fSubmittedProc(info.fSubmittedContext, false);
+        }
+        return GrSemaphoresSubmitted::kNo;
+    }
+
+    bool flushed = this->drawingManager()->flush(
+            nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess, info, nullptr);
+
+    if (!flushed || (!this->priv().caps()->semaphoreSupport() && info.fNumSemaphores)) {
+        return GrSemaphoresSubmitted::kNo;
+    }
+    return GrSemaphoresSubmitted::kYes;
+}
+
+bool GrDirectContext::submit(bool syncCpu) {
+    ASSERT_SINGLE_OWNER
+    if (this->abandoned()) {
+        return false;
+    }
+
+    if (!fGpu) {
+        return false;
+    }
+
+    return fGpu->submitToGpu(syncCpu);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDirectContext::checkAsyncWorkCompletion() {
+    if (fGpu) {
+        fGpu->checkFinishProcs();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDirectContext::storeVkPipelineCacheData() {
+    if (fGpu) {
+        fGpu->storeVkPipelineCacheData();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool GrDirectContext::supportsDistanceFieldText() const {
+    return this->caps()->shaderCaps()->supportsDistanceFieldText();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void GrDirectContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
+    ASSERT_SINGLE_OWNER
+    fResourceCache->dumpMemoryStatistics(traceMemoryDump);
+    traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
+                                      this->getTextBlobCache()->usedBytes());
+}
+
+size_t GrDirectContext::ComputeImageSize(sk_sp<SkImage> image, GrMipmapped mipMapped,
+                                         bool useNextPow2) {
+    if (!image->isTextureBacked()) {
+        return 0;
+    }
+    SkImage_GpuBase* gpuImage = static_cast<SkImage_GpuBase*>(as_IB(image.get()));
+    GrTextureProxy* proxy = gpuImage->peekProxy();
+    if (!proxy) {
+        return 0;
+    }
+
+    int colorSamplesPerPixel = 1;
+    return GrSurface::ComputeSize(proxy->backendFormat(), image->dimensions(),
+                                  colorSamplesPerPixel, mipMapped, useNextPow2);
+}
+
 #ifdef SK_GL
 
 /*************************************************************************************************/
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index d41c61d..d3ac74b 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -203,6 +203,7 @@
     SkDEBUGCODE(void validate() const);
 
     friend class GrContext; // access to: flush & cleanup
+    friend class GrDirectContext; // access to: flush & cleanup
     friend class GrContextPriv; // access to: flush
     friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class
     friend class GrRecordingContext;  // access to: ctor