Pass alpha type to GrSurfaceContext::read/writePixels and remove flags.

We deduce whether to premul or unpremul based on the the input/output
alpha types. This means we also now support unpremuling on write and
premuling on read.

Class-ify former struct GrPixelInfo. Remove origin and instead pass a
flip bool to GrConvertPixels.

Unifies read/write methods on GrSurfaceContext via automatic conversion
of SkImageInfo to GrPixelInfo and making GrDirectContext an optional
parameter.

Bug: skia:7580

Change-Id: I42f6997852b4b902fb81264c6de68ca9537606aa
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/224281
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index 9912dc0..2299591 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -96,7 +96,7 @@
         return false;
     }
 
-    if (!sContext->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), 0, 0)) {
+    if (!sContext->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), {0, 0})) {
         return false;
     }
 
@@ -128,28 +128,6 @@
                                    std::move(copyProxy), this->refColorSpace());
 }
 
-static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
-    switch (info.colorType()) {
-    case kRGBA_8888_SkColorType:
-    case kBGRA_8888_SkColorType:
-        break;
-    default:
-        return; // nothing to do
-    }
-
-    // SkColor is not necessarily RGBA or BGRA, but it is one of them on little-endian,
-    // and in either case, the alpha-byte is always in the same place, so we can safely call
-    // SkPreMultiplyColor()
-    //
-    SkColor* row = (SkColor*)pixels;
-    for (int y = 0; y < info.height(); ++y) {
-        for (int x = 0; x < info.width(); ++x) {
-            row[x] = SkPreMultiplyColor(row[x]);
-        }
-        row = (SkColor*)((char*)(row)+rowBytes);
-    }
-}
-
 bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
                                    int srcX, int srcY, CachingHint) const {
     auto direct = fContext->priv().asDirectContext();
@@ -162,20 +140,6 @@
         return false;
     }
 
-    SkReadPixelsRec rec(dstInfo, dstPixels, dstRB, srcX, srcY);
-    if (!rec.trim(this->width(), this->height())) {
-        return false;
-    }
-
-    // TODO: this seems to duplicate code in GrTextureContext::onReadPixels and
-    // GrRenderTargetContext::onReadPixels
-    uint32_t flags = 0;
-    if (kUnpremul_SkAlphaType == rec.fInfo.alphaType() &&
-        kPremul_SkAlphaType == this->alphaType()) {
-        // let the GPU perform this transformation for us
-        flags = GrSurfaceContext::kUnpremul_PixelOpsFlag;
-    }
-
     sk_sp<GrSurfaceContext> sContext = direct->priv().makeWrappedSurfaceContext(
             this->asTextureProxyRef(direct), SkColorTypeToGrColorType(this->colorType()),
             this->alphaType(), this->refColorSpace());
@@ -183,23 +147,7 @@
         return false;
     }
 
-    if (!sContext->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY, flags)) {
-        return false;
-    }
-
-    // do we have to manually fix-up the alpha channel?
-    //      src         dst
-    //      unpremul    premul      fix manually
-    //      premul      unpremul    done by kUnpremul_PixelOpsFlag
-    // all other combos need to change.
-    //
-    // Should this be handled by Ganesh? todo:?
-    //
-    if (kPremul_SkAlphaType == rec.fInfo.alphaType() &&
-        kUnpremul_SkAlphaType == this->alphaType()) {
-        apply_premul(rec.fInfo, rec.fPixels, rec.fRowBytes);
-    }
-    return true;
+    return sContext->readPixels(dstInfo, dstPixels, dstRB, {srcX, srcY});
 }
 
 sk_sp<GrTextureProxy> SkImage_GpuBase::asTextureProxyRef(GrRecordingContext* context,