Hook DDLPromiseImageHelper up to new YUVA API.

The old API is no longer implemented by SkCodecImageGenerator, meaning
we would never take the YUVA code path.

Bug: skia:10632

Change-Id: I33adb348768fdcd70368640d6857c5c7e3c2dc0f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/312882
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/tools/DDLPromiseImageHelper.cpp b/tools/DDLPromiseImageHelper.cpp
index 35e8ed8..2af072f 100644
--- a/tools/DDLPromiseImageHelper.cpp
+++ b/tools/DDLPromiseImageHelper.cpp
@@ -17,6 +17,7 @@
 #include "src/core/SkCachedData.h"
 #include "src/core/SkMipmap.h"
 #include "src/core/SkTaskGroup.h"
+#include "src/core/SkYUVAInfoPriv.h"
 #include "src/gpu/GrContextPriv.h"
 #include "src/image/SkImage_Base.h"
 #include "src/image/SkImage_GpuYUVA.h"
@@ -35,12 +36,11 @@
         , fImageInfo(other.fImageInfo)
         , fBaseLevel(other.fBaseLevel)
         , fMipLevels(std::move(other.fMipLevels))
-        , fYUVColorSpace(other.fYUVColorSpace) {
-    memcpy(fYUVAIndices, other.fYUVAIndices, sizeof(fYUVAIndices));
+        , fYUVAPixmaps(std::move(other.fYUVAPixmaps)) {
     for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
-        fYUVPlanes[i] = std::move(other.fYUVPlanes[i]);
         fCallbackContexts[i] = std::move(other.fCallbackContexts[i]);
     }
+    std::copy_n(other.fYUVAIndices, SkYUVAIndex::kIndexCount, fYUVAIndices);
 }
 
 DDLPromiseImageHelper::PromiseImageInfo::~PromiseImageInfo() {}
@@ -70,41 +70,21 @@
     fMipLevels = std::move(mipLevels);
 }
 
-void DDLPromiseImageHelper::PromiseImageInfo::setYUVPlanes(
-        const SkYUVASizeInfo& yuvaSizeInfo,
-        const SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
-        SkYUVColorSpace cs,
-        std::unique_ptr<char[]> planes[SkYUVAIndex::kIndexCount]) {
-    memcpy(fYUVAIndices, yuvaIndices, sizeof(fYUVAIndices));
-    fYUVColorSpace = cs;
-    SkColorType colorTypes[] = {kUnknown_SkColorType,
-                                kUnknown_SkColorType,
-                                kUnknown_SkColorType,
-                                kUnknown_SkColorType};
-    for (int yuvIndex = 0; yuvIndex < SkYUVAIndex::kIndexCount; ++yuvIndex) {
-        int texIdx = yuvaIndices[yuvIndex].fIndex;
-        if (texIdx < 0) {
-            SkASSERT(SkYUVAIndex::kA_Index == yuvIndex);
-            continue;
+void DDLPromiseImageHelper::PromiseImageInfo::initYUVAIndices() {
+    SkYUVASizeInfo unusedSizeInfo;
+    SkYUVAInfoPriv::InitLegacyInfo(fYUVAPixmaps.yuvaInfo(), fYUVAPixmaps.planes(), &unusedSizeInfo,
+                                   fYUVAIndices);
+    // We can wind up with alpha pixmaps that become red textures. If so, update YUVA indices.
+    // Note: This goes away when we start creating YUVA images using SkYUVAInfo.
+    for (int i = 0; i < SkYUVAIndex::kIndexCount; ++i) {
+        if (fYUVAIndices[i].fIndex >= 0) {
+            int textureIdx = fYUVAIndices[i].fIndex;
+            const auto& format = fCallbackContexts[textureIdx]->backendFormat();
+            if (fYUVAIndices[i].fChannel == SkColorChannel::kA &&
+                format.channelMask() == SkColorChannelFlag::kRed_SkColorChannelFlag) {
+                fYUVAIndices[i].fChannel = SkColorChannel::kR;
+            }
         }
-        // In current testing only ever expect A8, RG_88
-        if (colorTypes[texIdx] == kUnknown_SkColorType) {
-            colorTypes[texIdx] = kAlpha_8_SkColorType;
-        } else {
-            SkASSERT(colorTypes[texIdx] == kAlpha_8_SkColorType);
-            colorTypes[texIdx] = kR8G8_unorm_SkColorType;
-        }
-    }
-
-    for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
-        if (yuvaSizeInfo.fSizes[i].isEmpty()) {
-            SkASSERT(!yuvaSizeInfo.fWidthBytes[i] && colorTypes[i] == kUnknown_SkColorType);
-            continue;
-        }
-        auto info = SkImageInfo::Make(yuvaSizeInfo.fSizes[i], colorTypes[i], kPremul_SkAlphaType);
-        auto release = [](void* addr, void*) { std::unique_ptr<char[]>(static_cast<char*>(addr)); };
-        char* pixels = planes[i].release();
-        fYUVPlanes[i].installPixels(info, pixels, yuvaSizeInfo.fWidthBytes[i], release, pixels);
     }
 }
 
@@ -262,8 +242,7 @@
         PromiseImageInfo& info = fImageInfo[i];
 
         if (info.isYUV()) {
-            int numPixmaps;
-            SkAssertResult(SkYUVAIndex::AreValidIndices(info.yuvaIndices(), &numPixmaps));
+            int numPixmaps = info.numYUVAPlanes();
 
             for (int j = 0; j < numPixmaps; ++j) {
                 const SkPixmap& yuvPixmap = info.yuvPixmap(j);
@@ -276,6 +255,7 @@
 
                 info.setCallbackContext(j, std::move(callbackContext));
             }
+            info.initYUVAIndices();
         } else {
             const SkBitmap& baseLevel = info.baseLevel();
 
@@ -464,22 +444,15 @@
                                                              image->uniqueID(),
                                                              overallII);
 
-    SkYUVASizeInfo yuvaSizeInfo;
-    SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount];
-    SkYUVColorSpace yuvColorSpace;
     auto codec = SkCodecImageGenerator::MakeFromEncodedCodec(ib->refEncodedData());
-    std::unique_ptr<char[]> planes[SkYUVASizeInfo::kMaxCount];
-    if (codec && codec->queryYUVA8(&yuvaSizeInfo, yuvaIndices, &yuvColorSpace)) {
-        void* data[4];
-        for (int i = 0; i < 4; ++i) {
-            size_t size = yuvaSizeInfo.fSizes[i].height() * yuvaSizeInfo.fWidthBytes[i];
-            if (size) {
-                planes[i].reset(new char[size]);
-            }
-            data[i] = planes[i].get();
-        }
-        SkAssertResult(codec->getYUVA8Planes(yuvaSizeInfo, yuvaIndices, data));
-        newImageInfo.setYUVPlanes(yuvaSizeInfo, yuvaIndices, yuvColorSpace, planes);
+    SkYUVAInfo yuvaInfo;
+    SkColorType colorTypes[SkYUVAInfo::kMaxPlanes];
+    size_t rowBytes[SkYUVAInfo::kMaxPlanes];
+    if (codec && codec->queryYUVAInfo(&yuvaInfo, colorTypes, rowBytes)) {
+        sk_gpu_test::YUVAPixmaps yuvaPixmaps(yuvaInfo, colorTypes, rowBytes);
+        SkAssertResult(codec->getYUVAPlanes(yuvaPixmaps.planes()));
+        SkASSERT(yuvaPixmaps.isValid());
+        newImageInfo.setYUVPlanes(std::move(yuvaPixmaps));
     } else {
         sk_sp<SkImage> rasterImage = image->makeRasterImage(); // force decoding of lazy images
         if (!rasterImage) {