Prepare sRGB encoding conversion for the removal of GrPixelConfig

Standardizes that GrGpu subclass's onRead/WritePixels never do sRGB<->linear conversion. This means that they can eventually take a color type rather than config. It also means direct callers of GrGpu::read/writePixels can never expect conversion (which in practice is no change).

Consolidate logic about whether to do sRGB<->linear encoding conversions in GrContext::read/writeSurfacePixels helpers. No change in when conversions are done (yet). This prepares this logic to operate on SkColorSpace and color type rather than config WRT the CPU data.

Bug: skia:6718
Change-Id: I346d669624861578f1bb9ea465a7ab4b549117fa
Reviewed-on: https://skia-review.googlesource.com/105286
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 985d182..e35d1f5 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -791,13 +791,27 @@
     return false;
 }
 
-// Returns true if the color (non-alpha) components represent sRGB values. It does NOT indicate that
-// all three color components are present in the config or anything about their order.
-static inline bool GrPixelConfigIsSRGB(GrPixelConfig config) {
+/**
+ * Refers to the encoding of a GPU buffer as it will be interpreted by the GPU when sampling and
+ * blending.
+ */
+enum class GrSRGBEncoded : bool { kNo = false, kYes = true };
+
+/**
+ * Describes whether pixel data encoding should be converted to/from linear/sRGB encoding.
+ */
+enum class GrSRGBConversion {
+    kNone,
+    kSRGBToLinear,
+    kLinearToSRGB,
+};
+
+// Returns whether the config's color channels are sRGB encoded.
+static inline GrSRGBEncoded GrPixelConfigIsSRGBEncoded(GrPixelConfig config) {
     switch (config) {
         case kSRGBA_8888_GrPixelConfig:
         case kSBGRA_8888_GrPixelConfig:
-            return true;
+            return GrSRGBEncoded::kYes;
         case kUnknown_GrPixelConfig:
         case kAlpha_8_GrPixelConfig:
         case kAlpha_8_as_Alpha_GrPixelConfig:
@@ -814,12 +828,15 @@
         case kAlpha_half_GrPixelConfig:
         case kAlpha_half_as_Red_GrPixelConfig:
         case kRGBA_half_GrPixelConfig:
-            return false;
+            return GrSRGBEncoded::kNo;
     }
     SK_ABORT("Invalid pixel config");
-    return false;
+    return GrSRGBEncoded::kNo;
 }
 
+static inline bool GrPixelConfigIsSRGB(GrPixelConfig config) {
+    return GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(config);
+}
 // Takes a config and returns the equivalent config with the R and B order
 // swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
 static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 09985e6..f8522f0 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -542,6 +542,63 @@
            (kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config);
 }
 
+static GrSRGBConversion determine_write_pixels_srgb_conversion(
+        GrPixelConfig srcConfig,
+        const SkColorSpace* srcColorSpace,
+        GrSRGBEncoded dstSRGBEncoded,
+        const SkColorSpace* dstColorSpace) {
+    // No support for sRGB-encoded alpha.
+    if (GrPixelConfigIsAlphaOnly(srcConfig)) {
+        return GrSRGBConversion::kNone;
+    }
+    // When the destination has no color space or it has a ~sRGB gamma but isn't sRGB encoded
+    // (because of caps) then we act in "legacy" mode where no conversions are performed.
+    if (!dstColorSpace ||
+        (dstColorSpace->gammaCloseToSRGB() && GrSRGBEncoded::kNo == dstSRGBEncoded)) {
+        return GrSRGBConversion::kNone;
+    }
+    // Similarly, if the src was sRGB gamma and 8888 but we didn't choose a sRGB config we must be
+    // in legacy mode. For now, anyway.
+    if (srcColorSpace && srcColorSpace->gammaCloseToSRGB() &&
+        GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(srcConfig) &&
+        GrPixelConfigIs8888Unorm(srcConfig)) {
+        return GrSRGBConversion::kNone;
+    }
+
+    bool srcColorSpaceIsSRGB = srcColorSpace && srcColorSpace->gammaCloseToSRGB();
+    bool dstColorSpaceIsSRGB = dstColorSpace->gammaCloseToSRGB();
+
+    // For now we are assuming that if color space of the dst does not have sRGB gamma then the
+    // texture format is not sRGB encoded and vice versa. Note that we already checked for "legacy"
+    // mode being forced on by caps above. This may change in the future.
+    SkASSERT(dstColorSpaceIsSRGB == (GrSRGBEncoded::kYes == dstSRGBEncoded));
+
+    // Similarly we are assuming that if the color space of the src does not have sRGB gamma then
+    // the CPU pixels don't have a sRGB pixel config. This will become moot soon as we will not
+    // be using GrPixelConfig to describe CPU pixel allocations.
+     SkASSERT(srcColorSpaceIsSRGB == GrPixelConfigIsSRGB(srcConfig));
+
+    if (srcColorSpaceIsSRGB == dstColorSpaceIsSRGB) {
+        return GrSRGBConversion::kNone;
+    }
+    return srcColorSpaceIsSRGB ? GrSRGBConversion::kSRGBToLinear : GrSRGBConversion::kLinearToSRGB;
+}
+
+static GrSRGBConversion determine_read_pixels_srgb_conversion(
+        GrSRGBEncoded srcSRGBEncoded,
+        const SkColorSpace* srcColorSpace,
+        GrPixelConfig dstConfig,
+        const SkColorSpace* dstColorSpace) {
+    // This is symmetrical with the write version.
+    switch (determine_write_pixels_srgb_conversion(dstConfig, dstColorSpace, srcSRGBEncoded,
+                                                   srcColorSpace)) {
+        case GrSRGBConversion::kNone:         return GrSRGBConversion::kNone;
+        case GrSRGBConversion::kLinearToSRGB: return GrSRGBConversion::kSRGBToLinear;
+        case GrSRGBConversion::kSRGBToLinear: return GrSRGBConversion::kLinearToSRGB;
+    }
+    return GrSRGBConversion::kNone;
+}
+
 bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst,
                                        int left, int top, int width, int height,
                                        GrPixelConfig srcConfig, SkColorSpace* srcColorSpace,
@@ -590,8 +647,12 @@
     GrGpu::DrawPreference drawPreference = premulOnGpu ? GrGpu::kCallerPrefersDraw_DrawPreference
                                                        : GrGpu::kNoDraw_DrawPreference;
     GrGpu::WritePixelTempDrawInfo tempDrawInfo;
+    GrSRGBConversion srgbConversion = determine_write_pixels_srgb_conversion(
+            srcConfig, srcColorSpace, GrPixelConfigIsSRGBEncoded(dstProxy->config()),
+            dst->colorSpaceInfo().colorSpace());
     if (!fContext->fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(), width, height,
-                                            srcConfig, &drawPreference, &tempDrawInfo)) {
+                                            srcConfig, srgbConversion, &drawPreference,
+                                            &tempDrawInfo)) {
         return false;
     }
 
@@ -723,8 +784,12 @@
     GrGpu::DrawPreference drawPreference = unpremulOnGpu ? GrGpu::kCallerPrefersDraw_DrawPreference
                                                          : GrGpu::kNoDraw_DrawPreference;
     GrGpu::ReadPixelTempDrawInfo tempDrawInfo;
+    GrSRGBConversion srgbConversion = determine_read_pixels_srgb_conversion(
+            GrPixelConfigIsSRGBEncoded(srcProxy->config()), src->colorSpaceInfo().colorSpace(),
+            dstConfig, dstColorSpace);
     if (!fContext->fGpu->getReadPixelsInfo(srcSurface, srcProxy->origin(), width, height, rowBytes,
-                                           dstConfig, &drawPreference, &tempDrawInfo)) {
+                                           dstConfig, srgbConversion, &drawPreference,
+                                           &tempDrawInfo)) {
         return false;
     }
 
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index afe9cd8..ff26c79 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -193,35 +193,65 @@
     return this->onCopySurface(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
 }
 
-bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                              int width, int height, size_t rowBytes,
-                              GrPixelConfig readConfig, DrawPreference* drawPreference,
+bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width,
+                              int height, size_t rowBytes, GrPixelConfig dstConfig,
+                              GrSRGBConversion srgbConversion, DrawPreference* drawPreference,
                               ReadPixelTempDrawInfo* tempDrawInfo) {
     SkASSERT(drawPreference);
     SkASSERT(tempDrawInfo);
     SkASSERT(srcSurface);
     SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);
 
-    // Default values for intermediate draws. The intermediate texture config matches the src's
+    // Default values for intermediate draws. The intermediate texture config matches the dst's
     // config, is approx sized to the read rect, no swizzling or spoofing of the dst config.
     tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
     tempDrawInfo->fTempSurfaceDesc.fWidth = width;
     tempDrawInfo->fTempSurfaceDesc.fHeight = height;
     tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1;
     tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
-    tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config();
+    tempDrawInfo->fTempSurfaceDesc.fConfig = dstConfig;
     tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox;
     tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
-    tempDrawInfo->fReadConfig = readConfig;
+    tempDrawInfo->fReadConfig = dstConfig;
 
     // We currently do not support reading into the packed formats 565 or 4444 as they are not
     // required to have read back support on all devices and backends.
-    if (kRGB_565_GrPixelConfig == readConfig || kRGBA_4444_GrPixelConfig == readConfig) {
+    if (kRGB_565_GrPixelConfig == dstConfig || kRGBA_4444_GrPixelConfig == dstConfig) {
         return false;
     }
 
-   if (!this->onGetReadPixelsInfo(srcSurface, srcOrigin, width, height, rowBytes, readConfig,
-                                  drawPreference, tempDrawInfo)) {
+    // GrGpu::readPixels doesn't do any sRGB conversions, so we must draw if there is one.
+    switch (srgbConversion) {
+        case GrSRGBConversion::kNone:
+            break;
+        case GrSRGBConversion::kLinearToSRGB:
+            SkASSERT(this->caps()->srgbSupport());
+            // This check goes away when we start referring to CPU data using color type.
+            SkASSERT(GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(dstConfig));
+            // Currently we don't expect to make a SRGB encoded surface and then read data from it
+            // such that we treat it as though it were linear and is then converted to sRGB.
+            if (GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(srcSurface->config())) {
+                return false;
+            }
+            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+            break;
+        case GrSRGBConversion::kSRGBToLinear:
+            SkASSERT(this->caps()->srgbSupport());
+            // This assert goes away when we start referring to CPU data using color type.
+            SkASSERT(GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(dstConfig));
+            // We don't currently support reading sRGB encoded data into linear from a surface
+            // unless it is an sRGB-encoded config. That is likely to change when we need to store
+            // sRGB encoded data in 101010102 and F16 textures. We'll have to provoke the caller to
+            // do the conversion in a shader.
+            if (GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(srcSurface->config())) {
+                return false;
+            }
+            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+            break;
+    }
+
+    if (!this->onGetReadPixelsInfo(srcSurface, srcOrigin, width, height, rowBytes, dstConfig,
+                                   drawPreference, tempDrawInfo)) {
         return false;
     }
 
@@ -237,9 +267,9 @@
 
     return true;
 }
-bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
-                               int width, int height,
-                               GrPixelConfig srcConfig, DrawPreference* drawPreference,
+bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width,
+                               int height, GrPixelConfig srcConfig, GrSRGBConversion srgbConversion,
+                               DrawPreference* drawPreference,
                                WritePixelTempDrawInfo* tempDrawInfo) {
     SkASSERT(drawPreference);
     SkASSERT(tempDrawInfo);
@@ -257,6 +287,36 @@
     tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
     tempDrawInfo->fWriteConfig = srcConfig;
 
+    // GrGpu::writePixels doesn't do any sRGB conversions, so we must draw if there is one.
+    switch (srgbConversion) {
+        case GrSRGBConversion::kNone:
+            break;
+        case GrSRGBConversion::kLinearToSRGB:
+            SkASSERT(this->caps()->srgbSupport());
+            // This assert goes away when we start referring to CPU data using color type.
+            SkASSERT(GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(srcConfig));
+            // We don't currently support storing sRGB encoded data in a surface unless it is
+            // an SRGB-encoded config. That is likely to change when we need to store sRGB encoded
+            // data in 101010102 and F16 textures. We'll have to provoke the caller to do the
+            // conversion in a shader.
+            if (GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(dstSurface->config())) {
+                return false;
+            }
+            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+            break;
+        case GrSRGBConversion::kSRGBToLinear:
+            SkASSERT(this->caps()->srgbSupport());
+            // This assert goes away when we start referring to CPU data using color type.
+            SkASSERT(GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(srcConfig));
+            // Currently we don't expect to make a SRGB encoded surface and then succeed at
+            // treating it as though it were linear and then convert to sRGB.
+            if (GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(dstSurface->config())) {
+                return false;
+            }
+            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+            break;
+    }
+
     if (!this->onGetWritePixelsInfo(dstSurface, dstOrigin, width, height, srcConfig, drawPreference,
                                     tempDrawInfo)) {
         return false;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index baeb46a..87ddb76 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -199,9 +199,9 @@
      * that would allow a successful readPixels call. The passed width, height, and rowBytes,
      * must be non-zero and already reflect clipping to the src bounds.
      */
-    bool getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                           int readWidth, int readHeight, size_t rowBytes,
-                           GrPixelConfig readConfig, DrawPreference*, ReadPixelTempDrawInfo*);
+    bool getReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width,
+                           int height, size_t rowBytes, GrPixelConfig,
+                           GrSRGBConversion, DrawPreference*, ReadPixelTempDrawInfo*);
 
     /** Info struct returned by getWritePixelsInfo about performing an intermediate draw in order
         to write pixels to a GrSurface for either performance or correctness reasons. */
@@ -226,18 +226,19 @@
      * that would allow a successful transfer of the src pixels to the dst. The passed width,
      * height, and rowBytes, must be non-zero and already reflect clipping to the dst bounds.
      */
-    bool getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width, int height,
-                            GrPixelConfig srcConfig, DrawPreference*, WritePixelTempDrawInfo*);
+    bool getWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
+                            GrPixelConfig, GrSRGBConversion, DrawPreference*,
+                            WritePixelTempDrawInfo*);
 
     /**
-     * Reads a rectangle of pixels from a render target.
+     * Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed.
      *
      * @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 config        the pixel config of the destination buffer
+     * @param dstConfig     the pixel config of the destination buffer
      * @param buffer        memory to read the rectangle into.
      * @param rowBytes      the number of bytes between consecutive rows. Zero
      *                      means rows are tightly packed.
@@ -248,39 +249,32 @@
      *              because of a unsupported pixel config or because no render
      *              target is currently set.
      */
-    bool readPixels(GrSurface* surface, GrSurfaceOrigin,
-                    int left, int top, int width, int height,
-                    GrPixelConfig config, void* buffer, size_t rowBytes);
+    bool readPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height,
+                    GrPixelConfig dstConfig, void* buffer, size_t rowBytes);
 
     /**
-     * Updates the pixels in a rectangle of a surface.
+     * Updates the pixels in a rectangle of a surface.  No sRGB/linear conversions are performed.
      *
      * @param surface       The surface to write to.
      * @param left          left edge of the rectangle to write (inclusive)
      * @param top           top edge of the rectangle to write (inclusive)
      * @param width         width of rectangle to write in pixels.
      * @param height        height of rectangle to write in pixels.
-     * @param config        the pixel config of the source buffer
+     * @param srcConfig     the pixel config of the source buffer
      * @param texels        array of mipmap levels containing texture data
      * @param mipLevelCount number of levels in 'texels'
      */
     bool writePixels(GrSurface* surface, GrSurfaceOrigin origin,
                      int left, int top, int width, int height,
-                     GrPixelConfig config,
+                     GrPixelConfig srcConfig,
                      const GrMipLevel texels[], int mipLevelCount);
 
     /**
      * This function is a shim which creates a SkTArray<GrMipLevel> of size 1.
      * It then calls writePixels with that SkTArray.
-     *
-     * @param buffer   memory to read pixels from.
-     * @param rowBytes number of bytes between consecutive rows. Zero
-     *                 means rows are tightly packed.
      */
-    bool writePixels(GrSurface* surface, GrSurfaceOrigin origin,
-                     int left, int top, int width, int height,
-                     GrPixelConfig config, const void* buffer,
-                     size_t rowBytes);
+    bool writePixels(GrSurface*, GrSurfaceOrigin, int left, int top, int width,
+                     int height, GrPixelConfig, const void* buffer, size_t rowBytes);
 
     /**
      * Updates the pixels in a rectangle of a texture using a buffer
@@ -293,16 +287,15 @@
      * @param top              top edge of the rectangle to write (inclusive)
      * @param width            width of rectangle to write in pixels.
      * @param height           height of rectangle to write in pixels.
-     * @param config           the pixel config of the source buffer
+     * @param bufferConfig     the pixel config of the source buffer
      * @param transferBuffer   GrBuffer to read pixels from (type must be "kXferCpuToGpu")
      * @param offset           offset from the start of the buffer
      * @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,
-                        GrPixelConfig config, GrBuffer* transferBuffer,
-                        size_t offset, size_t rowBytes);
+    bool transferPixels(GrTexture* texture, int left, int top, int width, int height,
+                        GrPixelConfig bufferConfig, GrBuffer* transferBuffer, size_t offset,
+                        size_t rowBytes);
 
     // After the client interacts directly with the 3D context state the GrGpu
     // must resync its internal state and assumptions about 3D context state.
@@ -567,14 +560,11 @@
         return false;
     }
 
-    virtual bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                                     int readWidth, int readHeight,
-                                     size_t rowBytes, GrPixelConfig readConfig, DrawPreference*,
+    virtual bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
+                                     size_t rowBytes, GrPixelConfig, DrawPreference*,
                                      ReadPixelTempDrawInfo*) = 0;
-    virtual bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
-                                      int width, int height,
-                                      GrPixelConfig srcConfig, DrawPreference*,
-                                      WritePixelTempDrawInfo*) = 0;
+    virtual bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
+                                      GrPixelConfig, DrawPreference*, WritePixelTempDrawInfo*) = 0;
 
     // overridden by backend-specific derived class to perform the surface read
     virtual bool onReadPixels(GrSurface*, GrSurfaceOrigin,
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 06ee4d9..4088add 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -81,12 +81,13 @@
     GrDeferredTextureUploadWritePixelsFn wp = [this](GrTextureProxy* dstProxy, int left, int top,
                                                      int width, int height, GrPixelConfig srcConfig,
                                                      const void* buffer, size_t rowBytes) {
+        // We don't allow srgb conversions via op flush state uploads.
+        static constexpr auto kSRGBConversion = GrSRGBConversion::kNone;
         GrSurface* dstSurface = dstProxy->priv().peekSurface();
         GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
         GrGpu::WritePixelTempDrawInfo tempInfo;
-        if (!fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(),
-                                      width, height, srcConfig,
-                                      &drawPreference, &tempInfo)) {
+        if (!fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(), width, height, srcConfig,
+                                      kSRGBConversion, &drawPreference, &tempInfo)) {
             return false;
         }
         if (GrGpu::kNoDraw_DrawPreference == drawPreference) {
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 6563215..3cae7d3 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -665,6 +665,14 @@
                                    GrPixelConfig srcConfig,
                                    DrawPreference* drawPreference,
                                    WritePixelTempDrawInfo* tempDrawInfo) {
+    if (*drawPreference != kNoDraw_DrawPreference) {
+        // We assume the base class has only inserted a draw for sRGB reasons. So the temp surface
+        // has the config of the original src data. There is no swizzling nor src config spoofing.
+        SkASSERT(tempDrawInfo->fWriteConfig == srcConfig);
+        SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
+        SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
+    }
+
     if (SkToBool(dstSurface->asRenderTarget())) {
         if (this->glCaps().useDrawInsteadOfAllRenderTargetWrites()) {
             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
@@ -694,10 +702,6 @@
         ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
     }
 
-    if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConfig)) {
-        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
-    }
-
     bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
 
     if (configsAreRBSwaps) {
@@ -731,16 +735,11 @@
 }
 
 static bool check_write_and_transfer_input(GrGLTexture* glTex, GrSurface* surface,
-                                            GrPixelConfig config) {
+                                           GrPixelConfig config) {
     if (!glTex) {
         return false;
     }
 
-    // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
-    if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
-        return false;
-    }
-
     // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textures
     if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) {
         return false;
@@ -749,23 +748,21 @@
     return true;
 }
 
-bool GrGLGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin,
-                            int left, int top, int width, int height,
-                            GrPixelConfig config,
-                            const GrMipLevel texels[],
-                            int mipLevelCount) {
+bool GrGLGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top,
+                            int width, int height, GrPixelConfig dstConfig,
+                            const GrMipLevel texels[], int mipLevelCount) {
     GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
 
-    if (!check_write_and_transfer_input(glTex, surface, config)) {
+    if (!check_write_and_transfer_input(glTex, surface, dstConfig)) {
         return false;
     }
 
     this->setScratchTextureUnit();
     GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
 
-    return this->uploadTexData(glTex->config(), glTex->width(), glTex->height(),
-                               origin, glTex->target(), kWrite_UploadType,
-                               left, top, width, height, config, texels, mipLevelCount);
+    return this->uploadTexData(glTex->config(), glTex->width(), glTex->height(), origin,
+                               glTex->target(), kWrite_UploadType, left, top, width, height,
+                               dstConfig, texels, mipLevelCount);
 }
 
 // For GL_[UN]PACK_ALIGNMENT.
@@ -798,10 +795,9 @@
     return 0;
 }
 
-bool GrGLGpu::onTransferPixels(GrTexture* texture,
-                               int left, int top, int width, int height,
-                               GrPixelConfig config, GrBuffer* transferBuffer,
-                               size_t offset, size_t rowBytes) {
+bool GrGLGpu::onTransferPixels(GrTexture* texture, int left, int top, int width, int height,
+                               GrPixelConfig config, GrBuffer* transferBuffer, size_t offset,
+                               size_t rowBytes) {
     GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
     GrPixelConfig texConfig = glTex->config();
     SkASSERT(this->caps()->isConfigTexturable(texConfig));
@@ -2163,44 +2159,31 @@
     }
 }
 
-static bool requires_srgb_conversion(GrPixelConfig a, GrPixelConfig b) {
-    if (GrPixelConfigIsSRGB(a)) {
-        return !GrPixelConfigIsSRGB(b) && !GrPixelConfigIsAlphaOnly(b);
-    } else if (GrPixelConfigIsSRGB(b)) {
-        return !GrPixelConfigIsSRGB(a) && !GrPixelConfigIsAlphaOnly(a);
-    }
-    return false;
-}
-
-bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                                  int width, int height, size_t rowBytes,
-                                  GrPixelConfig readConfig, DrawPreference* drawPreference,
+bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width,
+                                  int height, size_t rowBytes, GrPixelConfig dstConfig,
+                                  DrawPreference* drawPreference,
                                   ReadPixelTempDrawInfo* tempDrawInfo) {
+    if (*drawPreference != kNoDraw_DrawPreference) {
+        // We assume the base class has only inserted a draw for sRGB reasons. So the
+        // the temp surface has the config of the dst data. There is no swizzling, nor dst config
+        // spoofing.
+        SkASSERT(tempDrawInfo->fReadConfig == dstConfig);
+        SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == dstConfig);
+        SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
+    }
     GrPixelConfig srcConfig = srcSurface->config();
 
     tempDrawInfo->fTempSurfaceFit = this->glCaps().partialFBOReadIsSlow() ? SkBackingFit::kExact
                                                                           : SkBackingFit::kApprox;
 
-    if (requires_srgb_conversion(srcConfig, readConfig)) {
-        if (!this->readPixelsSupported(readConfig, readConfig)) {
-            return false;
-        }
-        // Draw to do srgb to linear conversion or vice versa.
-        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
-        tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
-        tempDrawInfo->fReadConfig = readConfig;
-        return true;
-    }
-
-    if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig &&
+    if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == dstConfig &&
         this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelConfig)) {
         tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig;
         tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
         tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig;
         ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
     } else if (this->glCaps().rgbaToBgraReadbackConversionsAreSlow() &&
-               GrBytesPerPixel(readConfig) == 4 &&
-               GrPixelConfigSwapRAndB(readConfig) == srcConfig &&
+               GrBytesPerPixel(dstConfig) == 4 && GrPixelConfigSwapRAndB(dstConfig) == srcConfig &&
                this->readPixelsSupported(srcSurface, srcConfig)) {
         // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa.
         // Better to do a draw with a R/B swap and then read as the original config.
@@ -2208,8 +2191,8 @@
         tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
         tempDrawInfo->fReadConfig = srcConfig;
         ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
-    } else if (!this->readPixelsSupported(srcSurface, readConfig)) {
-        if (readConfig == kBGRA_8888_GrPixelConfig &&
+    } else if (!this->readPixelsSupported(srcSurface, dstConfig)) {
+        if (dstConfig == kBGRA_8888_GrPixelConfig &&
             this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig) &&
             this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPixelConfig)) {
             // We're trying to read BGRA but it's not supported. If RGBA is renderable and
@@ -2219,9 +2202,10 @@
             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
             tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig;
             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
-        } else if (readConfig == kSBGRA_8888_GrPixelConfig &&
-            this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) &&
-            this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, kSRGBA_8888_GrPixelConfig)) {
+        } else if (dstConfig == kSBGRA_8888_GrPixelConfig &&
+                   this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) &&
+                   this->readPixelsSupported(kSRGBA_8888_GrPixelConfig,
+                                             kSRGBA_8888_GrPixelConfig)) {
             // We're trying to read sBGRA but it's not supported. If sRGBA is renderable and
             // we can read it back, then do a swizzling draw to a sRGBA and read it back (which
             // will effectively be sBGRA).
@@ -2229,45 +2213,40 @@
             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
             tempDrawInfo->fReadConfig = kSRGBA_8888_GrPixelConfig;
             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
-        } else if (readConfig == kAlpha_8_GrPixelConfig) {
-            // onReadPixels implements a fallback for cases where we are want to read kAlpha_8,
+        } else if (dstConfig == kAlpha_8_GrPixelConfig) {
+            // onReadPixels implements a fallback for cases where we want to read kAlpha_8,
             // it's unsupported, but 32bit RGBA reads are supported.
-            // Don't attempt to do any srgb conversions since we only care about alpha.
-            GrPixelConfig cpuTempConfig = kRGBA_8888_GrPixelConfig;
-            if (GrPixelConfigIsSRGB(srcSurface->config())) {
-                cpuTempConfig = kSRGBA_8888_GrPixelConfig;
-            }
-            if (!this->readPixelsSupported(srcSurface, cpuTempConfig)) {
+            if (!this->readPixelsSupported(srcSurface, kRGBA_8888_GrPixelConfig)) {
                 // If we can't read RGBA from the src try to draw to a kRGBA_8888 (or kSRGBA_8888)
                 // first and then onReadPixels will read that to a 32bit temporary buffer.
-                if (this->glCaps().canConfigBeFBOColorAttachment(cpuTempConfig)) {
+                if (this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig)) {
                     ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
-                    tempDrawInfo->fTempSurfaceDesc.fConfig = cpuTempConfig;
+                    tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
                     tempDrawInfo->fReadConfig = kAlpha_8_GrPixelConfig;
                 } else {
                     return false;
                 }
             } else {
-                SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
+                tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
                 SkASSERT(tempDrawInfo->fReadConfig == kAlpha_8_GrPixelConfig);
             }
-        } else if (readConfig == kRGBA_half_GrPixelConfig &&
+        } else if (dstConfig == kRGBA_half_GrPixelConfig &&
                    this->readPixelsSupported(srcSurface, kRGBA_float_GrPixelConfig)) {
             // If reading in half float format is not supported, then read in float format.
             return true;
-        } else if (this->glCaps().canConfigBeFBOColorAttachment(readConfig) &&
-                   this->readPixelsSupported(readConfig, readConfig)) {
+        } else if (this->glCaps().canConfigBeFBOColorAttachment(dstConfig) &&
+                   this->readPixelsSupported(dstConfig, dstConfig)) {
             // Do a draw to convert from the src config to the read config.
             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
-            tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
-            tempDrawInfo->fReadConfig = readConfig;
+            tempDrawInfo->fTempSurfaceDesc.fConfig = dstConfig;
+            tempDrawInfo->fReadConfig = dstConfig;
         } else {
             return false;
         }
     }
 
     if ((srcSurface->asRenderTarget() || this->glCaps().canConfigBeFBOColorAttachment(srcConfig)) &&
-        read_pixels_pays_for_y_flip(srcOrigin, this->glCaps(), width, height, readConfig,
+        read_pixels_pays_for_y_flip(srcOrigin, this->glCaps(), width, height, dstConfig,
                                     rowBytes)) {
         ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
     }
@@ -2288,19 +2267,10 @@
         return false;
     }
 
-    // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
-    if (requires_srgb_conversion(surface->config(), config)) {
-        return false;
-    }
-
     // We have a special case fallback for reading eight bit alpha. We will read back all four 8
     // bit channels as RGBA and then extract A.
     if (!this->readPixelsSupported(surface, config)) {
-        // Don't attempt to do any srgb conversions since we only care about alpha.
         GrPixelConfig tempConfig = kRGBA_8888_GrPixelConfig;
-        if (GrPixelConfigIsSRGB(surface->config())) {
-            tempConfig = kSRGBA_8888_GrPixelConfig;
-        }
         if (kAlpha_8_GrPixelConfig == config &&
             this->readPixelsSupported(surface, tempConfig)) {
             std::unique_ptr<uint32_t[]> temp(new uint32_t[width * height * 4]);
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 48a0e2b..93b4de1 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -63,16 +63,6 @@
     void generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs, GrGLTexture* texture,
                          GrSurfaceOrigin textureOrigin);
 
-    bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                             int readWidth, int readHeight, size_t rowBytes,
-                             GrPixelConfig readConfig, DrawPreference*,
-                             ReadPixelTempDrawInfo*) override;
-
-    bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
-                              int width, int height,
-                              GrPixelConfig srcConfig, DrawPreference*,
-                              WritePixelTempDrawInfo*) override;
-
     // These functions should be used to bind GL objects. They track the GL state and skip redundant
     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
     void bindVertexArray(GrGLuint id) {
@@ -240,6 +230,12 @@
     // variations above, depending on whether the surface is a render target or not.
     bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
 
+    bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, size_t rowBytes,
+                             GrPixelConfig, DrawPreference*, ReadPixelTempDrawInfo*) override;
+
+    bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrPixelConfig,
+                              DrawPreference*, WritePixelTempDrawInfo*) override;
+
     bool onReadPixels(GrSurface*, GrSurfaceOrigin,
                       int left, int top,
                       int width, int height,
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 6221d91..4cbd49c 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -25,25 +25,6 @@
 
     ~GrMockGpu() override {}
 
-    bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                             int readWidth, int readHeight, size_t rowBytes,
-                             GrPixelConfig readConfig, DrawPreference*,
-                             ReadPixelTempDrawInfo*) override { return true; }
-
-    bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
-                              int width, int height,
-                              GrPixelConfig srcConfig, DrawPreference*,
-                              WritePixelTempDrawInfo*) override { return true; }
-
-    bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
-                       GrSurface* src, GrSurfaceOrigin srcOrigin,
-                       const SkIRect& srcRect, const SkIPoint& dstPoint) override { return true; }
-
-    void onQueryMultisampleSpecs(GrRenderTarget* rt, GrSurfaceOrigin, const GrStencilSettings&,
-                                 int* effectiveSampleCnt, SamplePattern*) override {
-        *effectiveSampleCnt = rt->numStencilSamples();
-    }
-
     GrGpuRTCommandBuffer* createCommandBuffer(
                                     GrRenderTarget*, GrSurfaceOrigin,
                                     const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
@@ -99,6 +80,18 @@
     GrBuffer* onCreateBuffer(size_t sizeInBytes, GrBufferType, GrAccessPattern,
                              const void*) override;
 
+    bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
+                             size_t rowBytes, GrPixelConfig, DrawPreference*,
+                             ReadPixelTempDrawInfo*) override {
+        return true;
+    }
+
+    bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin, int width,
+                              int height, GrPixelConfig, DrawPreference*,
+                              WritePixelTempDrawInfo*) override {
+        return true;
+    }
+
     bool onReadPixels(GrSurface* surface, GrSurfaceOrigin,
                       int left, int top, int width, int height,
                       GrPixelConfig,
@@ -121,6 +114,17 @@
         return true;
     }
 
+    bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
+                       GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
+                       const SkIPoint& dstPoint) override {
+        return true;
+    }
+
+    void onQueryMultisampleSpecs(GrRenderTarget* rt, GrSurfaceOrigin, const GrStencilSettings&,
+                                 int* effectiveSampleCnt, SamplePattern*) override {
+        *effectiveSampleCnt = rt->numStencilSamples();
+    }
+
     void onResolveRenderTarget(GrRenderTarget* target) override { return; }
 
     void onFinishFlush(bool insertedSemaphores) override {}
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 35c2fcc..daa4057 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -340,6 +340,14 @@
                                    int width, int height,
                                    GrPixelConfig srcConfig, DrawPreference* drawPreference,
                                    WritePixelTempDrawInfo* tempDrawInfo) {
+    if (*drawPreference != kNoDraw_DrawPreference) {
+        // We assume the base class has only inserted a draw for sRGB reasons. So the temp surface
+        // has the config of the original src data. There is no swizzling nor src config spoofing.
+        SkASSERT(tempDrawInfo->fWriteConfig == srcConfig);
+        SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
+        SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
+    }
+
     GrRenderTarget* renderTarget = dstSurface->asRenderTarget();
 
     if (dstSurface->config() == srcConfig) {
@@ -381,11 +389,6 @@
         return false;
     }
 
-    // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
-    if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
-        return false;
-    }
-
     bool success = false;
     bool linearTiling = vkTex->isLinearTiled();
     if (linearTiling) {
@@ -435,11 +438,6 @@
         return false;
     }
 
-    // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
-    if (GrPixelConfigIsSRGB(texture->config()) != GrPixelConfigIsSRGB(config)) {
-        return false;
-    }
-
     SkDEBUGCODE(
         SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
         SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
@@ -1859,29 +1857,35 @@
     *effectiveSampleCnt = rt->numStencilSamples();
 }
 
-bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                                  int width, int height, size_t rowBytes,
-                                  GrPixelConfig readConfig, DrawPreference* drawPreference,
+bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width,
+                                  int height, size_t rowBytes, GrPixelConfig dstConfig,
+                                  DrawPreference* drawPreference,
                                   ReadPixelTempDrawInfo* tempDrawInfo) {
-    if (srcSurface->config() == readConfig) {
+    if (*drawPreference != kNoDraw_DrawPreference) {
+        // We assume the base class has only inserted a draw for sRGB reasons. So the
+        // the temp surface has the config of the dst data. There is no swizzling nor dst config.
+        // spoofing.
+        SkASSERT(tempDrawInfo->fReadConfig == dstConfig);
+        SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == dstConfig);
+        SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
+    }
+
+    if (srcSurface->config() == dstConfig) {
         return true;
     }
 
     // Any config change requires a draw
     ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
-    tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
-    tempDrawInfo->fReadConfig = readConfig;
+    tempDrawInfo->fTempSurfaceDesc.fConfig = dstConfig;
+    tempDrawInfo->fReadConfig = dstConfig;
 
     return true;
 }
 
-bool GrVkGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin,
-                           int left, int top, int width, int height,
-                           GrPixelConfig config,
-                           void* buffer,
-                           size_t rowBytes) {
+bool GrVkGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top, int width,
+                           int height, GrPixelConfig dstConfig, void* buffer, size_t rowBytes) {
     VkFormat pixelFormat;
-    if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
+    if (!GrPixelConfigToVkFormat(dstConfig, &pixelFormat)) {
         return false;
     }
 
@@ -1916,7 +1920,7 @@
                           VK_PIPELINE_STAGE_TRANSFER_BIT,
                           false);
 
-    size_t bpp = GrBytesPerPixel(config);
+    size_t bpp = GrBytesPerPixel(dstConfig);
     size_t tightRowBytes = bpp * width;
     bool flipY = kBottomLeft_GrSurfaceOrigin == origin;
 
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 5481bf2..4302f7f 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -64,23 +64,6 @@
         kSkip_SyncQueue
     };
 
-    bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
-                             int readWidth, int readHeight, size_t rowBytes,
-                             GrPixelConfig readConfig, DrawPreference*,
-                             ReadPixelTempDrawInfo*) override;
-
-    bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
-                              int width, int height,
-                              GrPixelConfig srcConfig, DrawPreference*,
-                              WritePixelTempDrawInfo*) override;
-
-    bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
-                       GrSurface* src, GrSurfaceOrigin srcOrigin,
-                       const SkIRect& srcRect, const SkIPoint& dstPoint) override;
-
-    void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
-                                 int* effectiveSampleCnt, SamplePattern*) override;
-
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
 
     GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h,
@@ -193,11 +176,14 @@
     GrBuffer* onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern,
                              const void* data) override;
 
-    bool onReadPixels(GrSurface* surface, GrSurfaceOrigin,
-                      int left, int top, int width, int height,
-                      GrPixelConfig,
-                      void* buffer,
-                      size_t rowBytes) override;
+    bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, size_t rowBytes,
+                             GrPixelConfig, DrawPreference*, ReadPixelTempDrawInfo*) override;
+
+    bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrPixelConfig,
+                              DrawPreference*, WritePixelTempDrawInfo*) override;
+
+    bool onReadPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height,
+                      GrPixelConfig, void* buffer, size_t rowBytes) override;
 
     bool onWritePixels(GrSurface* surface, GrSurfaceOrigin,
                        int left, int top, int width, int height,
@@ -208,6 +194,13 @@
                           GrPixelConfig config, GrBuffer* transferBuffer,
                           size_t offset, size_t rowBytes) override;
 
+    bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
+                       GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
+                       const SkIPoint& dstPoint) override;
+
+    void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
+                                 int* effectiveSampleCnt, SamplePattern*) override;
+
     void onFinishFlush(bool insertedSemaphores) override;
 
     // Ends and submits the current command buffer to the queue and then creates a new command