Add SkSurface::asyncReadPixels()

Initial version. Current limitations: No Metal support, no color space
conversions, for each src color type only one dst color type is legal (
which may or may not be the src color type), no alpha type conversions.

Bug: skia:8962

Change-Id: I6f046a32342b8f5ffb1799d67d7ba15c250ef9bf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/212981
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index ab2ad06..c95f1e5 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -36,7 +36,6 @@
 public:
     InlineUpload(GrOpFlushState* state, const GrDeferredTextureUploadFn& upload)
             : fFlushState(state), fUpload(upload) {}
-    ~InlineUpload() override = default;
 
     void execute(const Args& args) override { fFlushState->doUpload(fUpload); }
 
@@ -54,7 +53,6 @@
             , fSrcRect(srcRect)
             , fDstPoint(dstPoint)
             , fShouldDiscardDst(shouldDiscardDst) {}
-    ~Copy() override = default;
 
     void execute(const Args& args) override {
         args.fGpu->copySurface(args.fSurface, args.fOrigin, fSrc.get(), fSrcOrigin, fSrcRect,
@@ -70,6 +68,28 @@
     bool fShouldDiscardDst;
 };
 
+class TransferFrom : public GrVkPrimaryCommandBufferTask {
+public:
+    TransferFrom(const SkIRect& srcRect, GrColorType bufferColorType, GrGpuBuffer* transferBuffer,
+                 size_t offset)
+            : fTransferBuffer(sk_ref_sp(transferBuffer))
+            , fOffset(offset)
+            , fSrcRect(srcRect)
+            , fBufferColorType(bufferColorType) {}
+
+    void execute(const Args& args) override {
+        args.fGpu->transferPixelsFrom(args.fSurface, fSrcRect.fLeft, fSrcRect.fTop,
+                                      fSrcRect.width(), fSrcRect.height(), fBufferColorType,
+                                      fTransferBuffer.get(), fOffset);
+    }
+
+private:
+    sk_sp<GrGpuBuffer> fTransferBuffer;
+    size_t fOffset;
+    SkIRect fSrcRect;
+    GrColorType fBufferColorType;
+};
+
 }  // anonymous namespace
 
 /////////////////////////////////////////////////////////////////////////////
@@ -79,6 +99,11 @@
     fTasks.emplace<Copy>(src, srcOrigin, srcRect, dstPoint, false);
 }
 
+void GrVkGpuTextureCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
+                                               GrGpuBuffer* transferBuffer, size_t offset) {
+    fTasks.emplace<TransferFrom>(srcRect, bufferColorType, transferBuffer, offset);
+}
+
 void GrVkGpuTextureCommandBuffer::insertEventMarker(const char* msg) {
     // TODO: does Vulkan have a correlate?
 }
@@ -620,6 +645,16 @@
     }
 }
 
+void GrVkGpuRTCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
+                                          GrGpuBuffer* transferBuffer, size_t offset) {
+    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
+    if (!cbInfo.fIsEmpty) {
+        this->addAdditionalRenderPass();
+    }
+    fPreCommandBufferTasks.emplace<TransferFrom>(srcRect, bufferColorType, transferBuffer, offset);
+    ++fCommandBufferInfos[fCurrentCmdInfo].fNumPreCmds;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrVkGpuRTCommandBuffer::bindGeometry(const GrGpuBuffer* indexBuffer,