Merge common code for SkImage_Gpu and SkImage_GpuYUVA.

Bug: skia:7903
Change-Id: I29957babe65e9e1c505166d01490233fe542a559
Reviewed-on: https://skia-review.googlesource.com/c/169824
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index 006533a..332e725 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -12,6 +12,7 @@
 #include "GrRenderTargetContext.h"
 #include "GrTexture.h"
 #include "GrTextureAdjuster.h"
+#include "effects/GrYUVtoRGBEffect.h"
 #include "SkBitmapCache.h"
 #include "SkImage_Gpu.h"
 #include "SkImage_GpuBase.h"
@@ -289,6 +290,59 @@
     return true;
 }
 
+bool SkImage_GpuBase::MakeTempTextureProxies(GrContext* ctx, const GrBackendTexture yuvaTextures[],
+                                             int numTextures, GrSurfaceOrigin imageOrigin,
+                                             sk_sp<GrTextureProxy> tempTextureProxies[4]) {
+    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
+
+    // We need to make a copy of the input backend textures because we need to preserve the result
+    // of validate_backend_texture.
+    GrBackendTexture yuvaTexturesCopy[4];
+    for (int textureIndex = 0; textureIndex < numTextures; ++textureIndex) {
+        yuvaTexturesCopy[textureIndex] = yuvaTextures[textureIndex];
+        if (!ctx->contextPriv().caps()->getYUVAConfigFromBackendTexture(
+            yuvaTexturesCopy[textureIndex],
+            &yuvaTexturesCopy[textureIndex].fConfig)) {
+            return false;
+        }
+        SkASSERT(yuvaTexturesCopy[textureIndex].isValid());
+
+        tempTextureProxies[textureIndex] =
+            proxyProvider->wrapBackendTexture(yuvaTexturesCopy[textureIndex], imageOrigin);
+        if (!tempTextureProxies[textureIndex]) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool SkImage_GpuBase::RenderYUVAToRGBA(GrContext* ctx, GrRenderTargetContext* renderTargetContext,
+                                       const SkRect& rect, SkYUVColorSpace yuvColorSpace,
+                                       const sk_sp<GrTextureProxy> proxies[4],
+                                       const SkYUVAIndex yuvaIndices[4]) {
+    SkASSERT(renderTargetContext);
+    if (!renderTargetContext->asSurfaceProxy()) {
+        return false;
+    }
+
+    GrPaint paint;
+    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+
+    // TODO: modify the YUVtoRGBEffect to do premul if needed
+    // (e.g., if SkImage_GpuYUVA::fImageAlphaType is kPremul_AlphaType)
+    paint.addColorFragmentProcessor(GrYUVtoRGBEffect::Make(proxies, yuvaIndices,
+                                                           yuvColorSpace,
+                                                           GrSamplerState::Filter::kNearest));
+
+    renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
+
+    // DDL TODO: in the promise image version we must not flush here
+    ctx->contextPriv().flushSurfaceWrites(renderTargetContext->asSurfaceProxy());
+
+    return true;
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////////////
 sk_sp<GrTexture> SkPromiseImageHelper::getTexture(GrResourceProvider* resourceProvider,
                                                   GrPixelConfig config) {