Revert "Move all YUVA image creation in GMs into sk_gpu_test::LazyYUVImage."

This reverts commit db0288d747ae84e8cfb577f70953c1d56eb78110.

Reason for revert: undeclared tuple size

Original change's description:
> Move all YUVA image creation in GMs into sk_gpu_test::LazyYUVImage.
>
> LazyYUVImage now supports making images from a generator and from
> textures. It uses ManagedBackendTexture to manage texture plane
> lifetime via ref-counting.
>
> Adds some supporting utility functions to SkYUVAInfo and
> SkYUVAPixmaps.
>
> Eases transition of forthcoming MakeFromYUVATextures API change.
>
> Bug: skia:10632
>
> Change-Id: I8cfd747c27076d1627da6ea8a169e554a96049e0
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/326720
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>

TBR=bsalomon@google.com,robertphillips@google.com

Change-Id: Icdfb70f7dadd97eace8f88d5a886d31534102f5f
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:10632
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/327622
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/tools/gpu/YUVUtils.cpp b/tools/gpu/YUVUtils.cpp
index 93c011b..4e8ad24 100644
--- a/tools/gpu/YUVUtils.cpp
+++ b/tools/gpu/YUVUtils.cpp
@@ -7,154 +7,40 @@
 
 #include "tools/gpu/YUVUtils.h"
 
-#include "include/core/SkColorPriv.h"
 #include "include/core/SkData.h"
 #include "include/gpu/GrRecordingContext.h"
 #include "src/codec/SkCodecImageGenerator.h"
-#include "src/core/SkYUVMath.h"
 #include "src/gpu/GrDirectContextPriv.h"
 #include "src/gpu/GrRecordingContextPriv.h"
-#include "tools/gpu/ManagedBackendTexture.h"
-
-namespace {
-
-static SkPMColor convert_yuva_to_rgba(const float mtx[20], uint8_t yuva[4]) {
-    uint8_t y = yuva[0];
-    uint8_t u = yuva[1];
-    uint8_t v = yuva[2];
-    uint8_t a = yuva[3];
-
-    uint8_t r = SkTPin(SkScalarRoundToInt(mtx[ 0]*y + mtx[ 1]*u + mtx[ 2]*v + mtx[ 4]*255), 0, 255);
-    uint8_t g = SkTPin(SkScalarRoundToInt(mtx[ 5]*y + mtx[ 6]*u + mtx[ 7]*v + mtx[ 9]*255), 0, 255);
-    uint8_t b = SkTPin(SkScalarRoundToInt(mtx[10]*y + mtx[11]*u + mtx[12]*v + mtx[14]*255), 0, 255);
-
-    return SkPremultiplyARGBInline(a, r, g, b);
-}
-
-static uint8_t look_up(float x1, float y1, const SkPixmap& pmap, SkColorChannel channel) {
-    SkASSERT(x1 > 0 && x1 < 1.0f);
-    SkASSERT(y1 > 0 && y1 < 1.0f);
-    int x = SkScalarFloorToInt(x1 * pmap.width());
-    int y = SkScalarFloorToInt(y1 * pmap.height());
-
-    auto ii = pmap.info().makeColorType(kRGBA_8888_SkColorType).makeWH(1, 1);
-    uint32_t pixel;
-    SkAssertResult(pmap.readPixels(ii, &pixel, sizeof(pixel), x, y));
-    int shift = static_cast<int>(channel) * 8;
-    return static_cast<uint8_t>((pixel >> shift) & 0xff);
-}
-
-class Generator : public SkImageGenerator {
-public:
-    Generator(SkYUVAPixmaps pixmaps, sk_sp<SkColorSpace> cs)
-            : SkImageGenerator(SkImageInfo::Make(pixmaps.yuvaInfo().dimensions(),
-                                                 kN32_SkColorType,
-                                                 kPremul_SkAlphaType,
-                                                 std::move(cs)))
-            , fPixmaps(std::move(pixmaps)) {}
-
-protected:
-    bool onGetPixels(const SkImageInfo& info,
-                     void* pixels,
-                     size_t rowBytes,
-                     const Options&) override {
-        if (kUnknown_SkColorType == fFlattened.colorType()) {
-            fFlattened.allocPixels(info);
-            SkASSERT(info == this->getInfo());
-
-            float mtx[20];
-            SkColorMatrix_YUV2RGB(fPixmaps.yuvaInfo().yuvColorSpace(), mtx);
-            SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount];
-            SkAssertResult(fPixmaps.toYUVAIndices(yuvaIndices));
-
-            for (int y = 0; y < info.height(); ++y) {
-                for (int x = 0; x < info.width(); ++x) {
-                    float x1 = (x + 0.5f) / info.width();
-                    float y1 = (y + 0.5f) / info.height();
-
-                    uint8_t yuva[4] = {0, 0, 0, 255};
-
-                    for (auto c : {SkYUVAIndex::kY_Index,
-                                   SkYUVAIndex::kU_Index,
-                                   SkYUVAIndex::kV_Index}) {
-                        const auto& pmap = fPixmaps.plane(yuvaIndices[c].fIndex);
-                        yuva[c] = look_up(x1, y1, pmap, yuvaIndices[c].fChannel);
-                    }
-                    if (yuvaIndices[SkYUVAIndex::kA_Index].fIndex >= 0) {
-                        const auto& pmap =
-                                fPixmaps.plane(yuvaIndices[SkYUVAIndex::kA_Index].fIndex);
-                        yuva[3] =
-                                look_up(x1, y1, pmap, yuvaIndices[SkYUVAIndex::kA_Index].fChannel);
-                    }
-
-                    // Making premul here.
-                    *fFlattened.getAddr32(x, y) = convert_yuva_to_rgba(mtx, yuva);
-                }
-            }
-        }
-
-        return fFlattened.readPixels(info, pixels, rowBytes, 0, 0);
-    }
-
-    bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& types,
-                         SkYUVAPixmapInfo* info) const override {
-        *info = fPixmaps.pixmapsInfo();
-        return info->isValid();
-    }
-
-    bool onGetYUVAPlanes(const SkYUVAPixmaps& pixmaps) override {
-        SkASSERT(pixmaps.yuvaInfo() == fPixmaps.yuvaInfo());
-        for (int i = 0; i < pixmaps.numPlanes(); ++i) {
-            SkASSERT(fPixmaps.plane(i).colorType() == pixmaps.plane(i).colorType());
-            SkASSERT(fPixmaps.plane(i).dimensions() == pixmaps.plane(i).dimensions());
-            SkASSERT(fPixmaps.plane(i).rowBytes() == pixmaps.plane(i).rowBytes());
-            fPixmaps.plane(i).readPixels(pixmaps.plane(i));
-        }
-        return true;
-    }
-
-private:
-    SkYUVAPixmaps fPixmaps;
-    SkBitmap      fFlattened;
-};
-
-}  // anonymous namespace
 
 namespace sk_gpu_test {
 
-std::unique_ptr<LazyYUVImage> LazyYUVImage::Make(sk_sp<SkData> data,
-                                                 GrMipmapped mipmapped,
-                                                 sk_sp<SkColorSpace> cs) {
+std::unique_ptr<LazyYUVImage> LazyYUVImage::Make(sk_sp<SkData> data, GrMipmapped mipmapped) {
     std::unique_ptr<LazyYUVImage> image(new LazyYUVImage());
-    if (image->reset(std::move(data), mipmapped, std::move(cs))) {
+    if (image->reset(std::move(data), mipmapped)) {
         return image;
     } else {
         return nullptr;
     }
 }
 
-std::unique_ptr<LazyYUVImage> LazyYUVImage::Make(SkYUVAPixmaps pixmaps,
-                                                 GrMipmapped mipmapped,
-                                                 sk_sp<SkColorSpace> cs) {
-    std::unique_ptr<LazyYUVImage> image(new LazyYUVImage());
-    if (image->reset(std::move(pixmaps), mipmapped, std::move(cs))) {
-        return image;
+sk_sp<SkImage> LazyYUVImage::refImage(GrRecordingContext* rContext) {
+    if (this->ensureYUVImage(rContext)) {
+        return fYUVImage;
     } else {
         return nullptr;
     }
 }
 
-sk_sp<SkImage> LazyYUVImage::refImage(GrRecordingContext* rContext, Type type) {
-    if (this->ensureYUVImage(rContext, type)) {
-        size_t idx = static_cast<size_t>(type);
-        SkASSERT(idx >= 0 && idx < SK_ARRAY_COUNT(fYUVImage));
-        return fYUVImage[idx];
+const SkImage* LazyYUVImage::getImage(GrRecordingContext* rContext) {
+    if (this->ensureYUVImage(rContext)) {
+        return fYUVImage.get();
     } else {
         return nullptr;
     }
 }
 
-bool LazyYUVImage::reset(sk_sp<SkData> data, GrMipmapped mipmapped, sk_sp<SkColorSpace> cs) {
+bool LazyYUVImage::reset(sk_sp<SkData> data, GrMipmapped mipmapped) {
     fMipmapped = mipmapped;
     auto codec = SkCodecImageGenerator::MakeFromEncodedCodec(data);
     if (!codec) {
@@ -174,87 +60,78 @@
         return false;
     }
 
-    fColorSpace = std::move(cs);
-
-    // The SkPixmap data is fully configured now for MakeFromYUVAPixmaps once we get a GrContext
-    return true;
-}
-
-bool LazyYUVImage::reset(SkYUVAPixmaps pixmaps, GrMipmapped mipmapped, sk_sp<SkColorSpace> cs) {
-    if (!pixmaps.isValid()) {
+    if (!fPixmaps.toLegacy(&fSizeInfo, fComponents)) {
         return false;
     }
-    fMipmapped = mipmapped;
-    if (pixmaps.ownsStorage()) {
-        fPixmaps = std::move(pixmaps);
-    } else {
-        fPixmaps = SkYUVAPixmaps::MakeCopy(std::move(pixmaps));
-    }
-    fColorSpace = std::move(cs);
     // The SkPixmap data is fully configured now for MakeFromYUVAPixmaps once we get a GrContext
     return true;
 }
 
-bool LazyYUVImage::ensureYUVImage(GrRecordingContext* rContext, Type type) {
-    size_t idx = static_cast<size_t>(type);
-    SkASSERT(idx >= 0 && idx < SK_ARRAY_COUNT(fYUVImage));
-    if (fYUVImage[idx] && fYUVImage[idx]->isValid(rContext)) {
-        return true;  // Have already made a YUV image valid for this context.
+bool LazyYUVImage::ensureYUVImage(GrRecordingContext* rContext) {
+    if (!rContext) {
+        return false; // Cannot make a YUV image from planes
+    }
+    if (fYUVImage && fYUVImage->isValid(rContext)) {
+        return true; // Have already made a YUV image valid for this context.
     }
     // Try to make a new YUV image for this context.
-    switch (type) {
-        case Type::kFromPixmaps:
-            if (!rContext || rContext->abandoned()) {
-                return false;
-            }
-            fYUVImage[idx] = SkImage::MakeFromYUVAPixmaps(rContext,
-                                                          fPixmaps,
-                                                          fMipmapped,
-                                                          /*limit to max tex size*/ false,
-                                                          fColorSpace);
-            break;
-        case Type::kFromGenerator: {
-            // Make sure the generator has ownership of its backing planes.
-            auto generator = std::make_unique<Generator>(fPixmaps, fColorSpace);
-            fYUVImage[idx] = SkImage::MakeFromGenerator(std::move(generator));
-            break;
-        }
-        case Type::kFromTextures:
-            if (!rContext || rContext->abandoned()) {
-                return false;
-            }
-            if (auto direct = rContext->asDirectContext()) {
-                sk_sp<sk_gpu_test::ManagedBackendTexture> mbets[SkYUVAInfo::kMaxPlanes];
-                GrBackendTexture textures[SkYUVAInfo::kMaxPlanes];
-                uint32_t componentFlags[SkYUVAInfo::kMaxPlanes] = {};
-                for (int i = 0; i < fPixmaps.numPlanes(); ++i) {
-                    mbets[i] = sk_gpu_test::ManagedBackendTexture::MakeWithData(
-                            direct, fPixmaps.plane(i), GrRenderable::kNo, GrProtected::kNo);
-                    if (mbets[i]) {
-                        textures[i] = mbets[i]->texture();
-                        componentFlags[i] = textures[i].getBackendFormat().channelMask();
-                    } else {
-                        return false;
-                    }
-                }
-                SkYUVAIndex indices[SkYUVAIndex::kIndexCount];
-                if (!fPixmaps.yuvaInfo().toYUVAIndices(componentFlags, indices)) {
-                    return false;
-                }
-                void* relContext =
-                        sk_gpu_test::ManagedBackendTexture::MakeYUVAReleaseContext(mbets);
-                fYUVImage[idx] = SkImage::MakeFromYUVATextures(
-                        direct,
-                        fPixmaps.yuvaInfo().yuvColorSpace(),
-                        textures,
-                        indices,
-                        fPixmaps.yuvaInfo().dimensions(),
-                        kTopLeft_GrSurfaceOrigin,
-                        fColorSpace,
-                        sk_gpu_test::ManagedBackendTexture::ReleaseProc,
-                        relContext);
-            }
-    }
-    return fYUVImage[idx] != nullptr;
+    fYUVImage = SkImage::MakeFromYUVAPixmaps(rContext, fPixmaps, fMipmapped, false, nullptr);
+    return fYUVImage != nullptr;
 }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void YUVABackendReleaseContext::Unwind(GrDirectContext* dContext,
+                                       YUVABackendReleaseContext* beContext,
+                                       bool fullFlush) {
+
+    // Some backends (e.g., Vulkan) require that all work associated w/ texture
+    // creation be completed before deleting the textures.
+    if (fullFlush) {
+        // If the release context client performed some operations other than backend texture
+        // creation then we may require a full flush to ensure that all the work is completed.
+        dContext->flush();
+        dContext->submit(true);
+    } else {
+        dContext->submit();
+
+        while (!beContext->creationCompleted()) {
+            dContext->checkAsyncWorkCompletion();
+        }
+    }
+
+    delete beContext;
+}
+
+YUVABackendReleaseContext::YUVABackendReleaseContext(GrDirectContext* dContext)
+        : fDContext(dContext) {
+}
+
+YUVABackendReleaseContext::~YUVABackendReleaseContext() {
+    for (int i = 0; i < 4; ++i) {
+        if (fBETextures[i].isValid()) {
+            SkASSERT(fCreationComplete[i]);
+            fDContext->deleteBackendTexture(fBETextures[i]);
+        }
+    }
+}
+
+template<int I> static void CreationComplete(void* releaseContext) {
+    auto beContext = reinterpret_cast<YUVABackendReleaseContext*>(releaseContext);
+    beContext->setCreationComplete(I);
+}
+
+GrGpuFinishedProc YUVABackendReleaseContext::CreationCompleteProc(int index) {
+    SkASSERT(index >= 0 && index < 4);
+
+    switch (index) {
+        case 0: return CreationComplete<0>;
+        case 1: return CreationComplete<1>;
+        case 2: return CreationComplete<2>;
+        case 3: return CreationComplete<3>;
+    }
+
+    SK_ABORT("Invalid YUVA Index.");
+    return nullptr;
+}
+
 } // namespace sk_gpu_test