Add use of RG textures in wacky_yuv_formats

Bug: skia:7903
Change-Id: I77346b301777479694b051486d95d720d8fd179f
Reviewed-on: https://skia-review.googlesource.com/c/175360
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/gm/wacky_yuv_formats.cpp b/gm/wacky_yuv_formats.cpp
index 00c2fe1..0a05596 100644
--- a/gm/wacky_yuv_formats.cpp
+++ b/gm/wacky_yuv_formats.cpp
@@ -661,6 +661,50 @@
     canvas->drawText(rowLabel.c_str(), rowLabel.size(), 0, y, textPaint);
 }
 
+static GrBackendTexture create_yuva_texture(GrGpu* gpu, const SkBitmap& bm,
+                                            SkYUVAIndex yuvaIndices[4], int texIndex) {
+    SkASSERT(texIndex >= 0 && texIndex <= 3);
+    int channelCount = 0;
+    for (int i = 0; i < SkYUVAIndex::kIndexCount; ++i) {
+        if (yuvaIndices[i].fIndex == texIndex) {
+            ++channelCount;
+        }
+    }
+    // Need to create an RG texture for two-channel planes
+    GrBackendTexture tex;
+    if (2 == channelCount) {
+        SkASSERT(kRGBA_8888_SkColorType == bm.colorType());
+        SkAutoTMalloc<char> pixels(2 * bm.width()*bm.height());
+        char* currPixel = pixels;
+        for (int y = 0; y < bm.height(); ++y) {
+            for (int x = 0; x < bm.width(); ++x) {
+                SkColor color = bm.getColor(x, y);
+                currPixel[0] = SkColorGetR(color);
+                currPixel[1] = SkColorGetG(color);
+                currPixel += 2;
+            }
+        }
+        tex = gpu->createTestingOnlyBackendTexture(
+            pixels,
+            bm.width(),
+            bm.height(),
+            GrColorType::kRG_88,
+            false,
+            GrMipMapped::kNo,
+            2*bm.width());
+    } else {
+        tex = gpu->createTestingOnlyBackendTexture(
+            bm.getPixels(),
+            bm.width(),
+            bm.height(),
+            bm.colorType(),
+            false,
+            GrMipMapped::kNo,
+            bm.rowBytes());
+    }
+    return tex;
+}
+
 namespace skiagm {
 
 // This GM creates an opaque and transparent bitmap, extracts the planes and then recombines
@@ -723,6 +767,10 @@
                     SkBitmap resultBMs[4];
                     SkYUVAIndex yuvaIndices[4];
                     create_YUV(planes, (YUVFormat) format, resultBMs, yuvaIndices, opaque);
+                    int numTextures;
+                    if (!SkYUVAIndex::AreValidIndices(yuvaIndices, &numTextures)) {
+                        continue;
+                    }
 
                     if (context) {
                         if (context->abandoned()) {
@@ -734,30 +782,12 @@
                             return;
                         }
 
-                        bool used[4] = { false, false, false, false };
-                        for (int i = 0; i < 4; ++i) {
-                            if (yuvaIndices[i].fIndex >= 0) {
-                                SkASSERT(yuvaIndices[i].fIndex < 4);
-                                used[yuvaIndices[i].fIndex] = true;
-                            }
-                        }
-
                         GrBackendTexture yuvaTextures[4];
                         SkPixmap yuvaPixmaps[4];
 
-                        for (int i = 0; i < 4; ++i) {
-                            if (!used[i]) {
-                                continue;
-                            }
-
-                            yuvaTextures[i] = gpu->createTestingOnlyBackendTexture(
-                                resultBMs[i].getPixels(),
-                                resultBMs[i].width(),
-                                resultBMs[i].height(),
-                                resultBMs[i].colorType(),
-                                false,
-                                GrMipMapped::kNo,
-                                resultBMs[i].rowBytes());
+                        for (int i = 0; i < numTextures; ++i) {
+                            yuvaTextures[i] = create_yuva_texture(gpu, resultBMs[i],
+                                                                  yuvaIndices, i);
                             yuvaPixmaps[i] = resultBMs[i].pixmap();
                         }
 
diff --git a/tools/DDLPromiseImageHelper.cpp b/tools/DDLPromiseImageHelper.cpp
index 53fcd1c..fcda20e 100644
--- a/tools/DDLPromiseImageHelper.cpp
+++ b/tools/DDLPromiseImageHelper.cpp
@@ -51,6 +51,51 @@
     return inputPicture->serialize(&procs);
 }
 
+// needed until we have SkRG_88_ColorType;
+static GrBackendTexture create_yuva_texture(GrGpu* gpu, const SkPixmap& pm,
+                                            const SkYUVAIndex yuvaIndices[4], int texIndex) {
+    SkASSERT(texIndex >= 0 && texIndex <= 3);
+    int channelCount = 0;
+    for (int i = 0; i < SkYUVAIndex::kIndexCount; ++i) {
+        if (yuvaIndices[i].fIndex == texIndex) {
+            ++channelCount;
+        }
+    }
+    // Need to create an RG texture for two-channel planes
+    GrBackendTexture tex;
+    if (2 == channelCount) {
+        SkASSERT(kRGBA_8888_SkColorType == pm.colorType());
+        SkAutoTMalloc<char> pixels(2 * pm.width()*pm.height());
+        char* currPixel = pixels;
+        for (int y = 0; y < pm.height(); ++y) {
+            for (int x = 0; x < pm.width(); ++x) {
+                SkColor color = pm.getColor(x, y);
+                currPixel[0] = SkColorGetR(color);
+                currPixel[1] = SkColorGetG(color);
+                currPixel += 2;
+            }
+        }
+        tex = gpu->createTestingOnlyBackendTexture(
+            pixels,
+            pm.width(),
+            pm.height(),
+            GrColorType::kRG_88,
+            false,
+            GrMipMapped::kNo,
+            2 * pm.width());
+    } else {
+        tex = gpu->createTestingOnlyBackendTexture(
+            pm.addr(),
+            pm.width(),
+            pm.height(),
+            pm.colorType(),
+            false,
+            GrMipMapped::kNo,
+            pm.rowBytes());
+    }
+    return tex;
+}
+
 void DDLPromiseImageHelper::uploadAllToGPU(GrContext* context) {
     GrGpu* gpu = context->contextPriv().getGpu();
     SkASSERT(gpu);
@@ -67,13 +112,9 @@
 
                 sk_sp<PromiseImageCallbackContext> callbackContext(
                                                         new PromiseImageCallbackContext(context));
-                callbackContext->setBackendTexture(gpu->createTestingOnlyBackendTexture(
-                                                            yuvPixmap.addr(),
-                                                            yuvPixmap.width(),
-                                                            yuvPixmap.height(),
-                                                            yuvPixmap.colorType(),
-                                                            false, GrMipMapped::kNo,
-                                                            yuvPixmap.rowBytes()));
+
+                callbackContext->setBackendTexture(create_yuva_texture(gpu, yuvPixmap,
+                                                                       info.yuvaIndices(), j));
                 SkAssertResult(callbackContext->backendTexture().isValid());
 
                 fImageInfo[i].setCallbackContext(j, std::move(callbackContext));