Allow async read back GM to YUV to fail. Skip on DDL.

Currently fails on GrContext's that don't support transfer buffers.
TODO: fallback to synchronous read pixels.

Bug: skia:8962
Change-Id: I464ea00519013a371ba29912a0220fa42b252243
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/220299
Commit-Queue: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
Auto-Submit: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/gm/asyncrescaleandread.cpp b/gm/asyncrescaleandread.cpp
index fe26071..2cd4d87 100644
--- a/gm/asyncrescaleandread.cpp
+++ b/gm/asyncrescaleandread.cpp
@@ -33,6 +33,7 @@
     struct Context {
         SkPixmap fPixmap;
         bool fCalled = false;
+        bool fSucceeded = false;
     } context;
     SkAssertResult(bmp.peekPixels(&context.fPixmap));
     auto callback = [](void* c, const void* data, size_t rowBytes) {
@@ -42,6 +43,7 @@
             context->fPixmap.reset();
             return;
         }
+        context->fSucceeded = true;
         SkRectMemcpy(context->fPixmap.writable_addr(), context->fPixmap.rowBytes(), data, rowBytes,
                      context->fPixmap.info().minRowBytes(), context->fPixmap.height());
     };
@@ -51,7 +53,7 @@
         SkASSERT(surface->getCanvas()->getGrContext());
         surface->getCanvas()->getGrContext()->checkAsyncWorkCompletion();
     }
-    return SkImage::MakeFromBitmap(bmp);
+    return context.fSucceeded ? SkImage::MakeFromBitmap(bmp) : nullptr;
 }
 
 static sk_sp<SkImage> do_read_and_scale_yuv(SkSurface* surface, SkYUVColorSpace yuvCS,
@@ -69,6 +71,7 @@
         uint8_t* fUData;
         uint8_t* fVData;
         bool fCalled = false;
+        bool fSucceeded = false;
     } context{dstW, dstH, yData.get(), uData.get(), vData.get()};
     auto callback = [](void* c, const void* data[2], size_t rowBytes[2]) {
         auto context = reinterpret_cast<Context*>(c);
@@ -76,6 +79,7 @@
         if (!data) {
             return;
         }
+        context->fSucceeded = true;
         int w = context->fW;
         int h = context->fH;
         SkRectMemcpy(context->fYData, w, data[0], rowBytes[0], w, h);
@@ -89,6 +93,9 @@
         SkASSERT(surface->getCanvas()->getGrContext());
         surface->getCanvas()->getGrContext()->checkAsyncWorkCompletion();
     }
+    if (!context.fSucceeded) {
+        return nullptr;
+    }
     auto* gr = surface->getCanvas()->getGrContext();
     GrBackendTexture backendTextures[3];
     GrBackendFormat format = gr->priv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
@@ -128,8 +135,8 @@
                                           const SkIRect& srcRect, int newW, int newH, bool doYUV420,
                                           SkString* errorMsg, int pad = 0) {
     if (doYUV420) {
-        if (!canvas->getGrContext()) {
-            errorMsg->printf("YUV420 only supported on GPU for now.");
+        if (!canvas->getGrContext() || !canvas->getGrContext()->priv().asDirectContext()) {
+            errorMsg->printf("YUV420 only supported on direct GPU for now.");
             return skiagm::DrawResult::kSkip;
         }
     }
@@ -149,10 +156,18 @@
             if (doYUV420) {
                 result = do_read_and_scale_yuv(surface, yuvColorSpace, srcRect, newW, newH, gamma,
                                                quality, &cleanup);
+                if (!result) {
+                    errorMsg->printf("YUV420 async call failed. Allowed for now.");
+                    return skiagm::DrawResult::kSkip;
+                }
                 int nextCS = static_cast<int>(yuvColorSpace + 1) % (kLastEnum_SkYUVColorSpace + 1);
                 yuvColorSpace = static_cast<SkYUVColorSpace>(nextCS);
             } else {
                 result = do_read_and_scale(surface, srcRect, ii, gamma, quality);
+                if (!result) {
+                    errorMsg->printf("async read call failed.");
+                    return skiagm::DrawResult::kFail;
+                }
             }
             canvas->drawImage(result, 0, 0);
             canvas->translate(newW + pad, 0);