Start on supporting transfer from GrSurface.

This only implements the GrGpu level functionality and is not exposed in
the public API.

Currently implemented for OpenGL only.

Bug: skia:8962

Change-Id: I8e58c1860185aa913bcdb0954908ce9e0b8e78f3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206383
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index e7d34e7..5ffcf38 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -207,10 +207,8 @@
     }
 
     /**
-     * Updates the pixels in a rectangle of a texture using a buffer
-     *
-     * There are a couple of assumptions here. First, we only update the top miplevel.
-     * And second, that any y flip needed has already been done in the buffer.
+     * Updates the pixels in a rectangle of a texture using a buffer. If the texture is MIP mapped,
+     * the base level is written to.
      *
      * @param texture          The texture to write to.
      * @param left             left edge of the rectangle to write (inclusive)
@@ -223,9 +221,29 @@
      * @param rowBytes         number of bytes between consecutive rows in the buffer. Zero
      *                         means rows are tightly packed.
      */
-    bool transferPixels(GrTexture* texture, int left, int top, int width, int height,
-                        GrColorType bufferColorType, GrGpuBuffer* transferBuffer, size_t offset,
-                        size_t rowBytes);
+    bool transferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
+                          GrColorType bufferColorType, GrGpuBuffer* transferBuffer, size_t offset,
+                          size_t rowBytes);
+
+    /**
+     * Reads the pixels from a rectangle of a surface into a buffer. Use
+     * GrCaps::transferFromBufferRequirements to determine the requirements for the buffer size
+     * and offset alignment. If the surface is a MIP mapped texture, the base level is read.
+     *
+     * Returns the number of bytes per row in the buffer or zero on failure.
+     *
+     * @param surface          The surface to read from.
+     * @param left             left edge of the rectangle to read (inclusive)
+     * @param top              top edge of the rectangle to read (inclusive)
+     * @param width            width of rectangle to read in pixels.
+     * @param height           height of rectangle to read in pixels.
+     * @param bufferColorType  the color type of the transfer buffer's pixel data
+     * @param transferBuffer   GrBuffer to write pixels to (type must be "kXferGpuToCpu")
+     * @param offset           offset from the start of the buffer
+     */
+    size_t transferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
+                              GrColorType bufferColorType, GrGpuBuffer* transferBuffer,
+                              size_t offset);
 
     // After the client interacts directly with the 3D context state the GrGpu
     // must resync its internal state and assumptions about 3D context state.
@@ -314,19 +332,9 @@
     class Stats {
     public:
 #if GR_GPU_STATS
-        Stats() { this->reset(); }
+        Stats() = default;
 
-        void reset() {
-            fRenderTargetBinds = 0;
-            fShaderCompilations = 0;
-            fTextureCreates = 0;
-            fTextureUploads = 0;
-            fTransfersToTexture = 0;
-            fStencilAttachmentCreates = 0;
-            fNumDraws = 0;
-            fNumFailedDraws = 0;
-            fNumFinishFlushes = 0;
-        }
+        void reset() { *this = {}; }
 
         int renderTargetBinds() const { return fRenderTargetBinds; }
         void incRenderTargetBinds() { fRenderTargetBinds++; }
@@ -337,7 +345,9 @@
         int textureUploads() const { return fTextureUploads; }
         void incTextureUploads() { fTextureUploads++; }
         int transfersToTexture() const { return fTransfersToTexture; }
+        int transfersFromSurface() const { return fTransfersFromSurface; }
         void incTransfersToTexture() { fTransfersToTexture++; }
+        void incTransfersFromSurface() { fTransfersFromSurface++; }
         void incStencilAttachmentCreates() { fStencilAttachmentCreates++; }
         void incNumDraws() { fNumDraws++; }
         void incNumFailedDraws() { ++fNumFailedDraws; }
@@ -350,15 +360,16 @@
         int numFailedDraws() const { return fNumFailedDraws; }
         int numFinishFlushes() const { return fNumFinishFlushes; }
     private:
-        int fRenderTargetBinds;
-        int fShaderCompilations;
-        int fTextureCreates;
-        int fTextureUploads;
-        int fTransfersToTexture;
-        int fStencilAttachmentCreates;
-        int fNumDraws;
-        int fNumFailedDraws;
-        int fNumFinishFlushes;
+        int fRenderTargetBinds = 0;
+        int fShaderCompilations = 0;
+        int fTextureCreates = 0;
+        int fTextureUploads = 0;
+        int fTransfersToTexture = 0;
+        int fTransfersFromSurface = 0;
+        int fStencilAttachmentCreates = 0;
+        int fNumDraws = 0;
+        int fNumFailedDraws = 0;
+        int fNumFinishFlushes = 0;
 #else
 
 #if GR_TEST_UTILS
@@ -515,9 +526,13 @@
                                const GrMipLevel texels[], int mipLevelCount) = 0;
 
     // overridden by backend-specific derived class to perform the texture transfer
-    virtual bool onTransferPixels(GrTexture*, int left, int top, int width, int height,
-                                  GrColorType colorType, GrGpuBuffer* transferBuffer, size_t offset,
-                                  size_t rowBytes) = 0;
+    virtual bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
+                                    GrColorType colorType, GrGpuBuffer* transferBuffer,
+                                    size_t offset, size_t rowBytes) = 0;
+    // overridden by backend-specific derived class to perform the surface transfer
+    virtual size_t onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
+                                        GrColorType colorType, GrGpuBuffer* transferBuffer,
+                                        size_t offset) = 0;
 
     // overridden by backend-specific derived class to perform the resolve
     virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;