Make gpuSetup draw a error message on failure

Since gpuSetup can preempt draw's execution it needs to draw the error message too.

This is pulled out of the gpuSetup refactoring.

Change-Id: Iafe06d924fc1b694c59aa3100e9fbe95c4773222
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/299140
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 494be64..42cc6e3 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -98,7 +98,7 @@
     std::unique_ptr<skiagm::GM> gm(fFactory());
     SkString msg;
 
-    skiagm::DrawResult gpuSetupResult = gm->gpuSetup(context, &msg);
+    skiagm::DrawResult gpuSetupResult = gm->gpuSetup(context, canvas, &msg);
     switch (gpuSetupResult) {
         case skiagm::DrawResult::kOk  : break;
         case skiagm::DrawResult::kFail: return Result(Result::Status::Fatal, msg);
diff --git a/gm/gm.cpp b/gm/gm.cpp
index 8f7d8a8..9438f5c 100644
--- a/gm/gm.cpp
+++ b/gm/gm.cpp
@@ -64,6 +64,16 @@
     canvas->drawPaint(paint);
 }
 
+static void handle_gm_failure(SkCanvas* canvas, DrawResult result, const SkString& errorMsg) {
+    if (DrawResult::kFail == result) {
+        draw_failure_message(canvas, "DRAW FAILED: %s", errorMsg.c_str());
+    } else if (SkString(GM::kErrorMsg_DrawSkippedGpuOnly) == errorMsg) {
+        draw_gpu_only_message(canvas);
+    } else {
+        draw_failure_message(canvas, "DRAW SKIPPED: %s", errorMsg.c_str());
+    }
+}
+
 GM::GM(SkColor bgColor) {
     fMode = kGM_Mode;
     fBGColor = bgColor;
@@ -71,9 +81,13 @@
 
 GM::~GM() {}
 
-DrawResult GM::gpuSetup(GrContext* context, SkString* errorMsg) {
+DrawResult GM::gpuSetup(GrContext* context, SkCanvas* canvas, SkString* errorMsg) {
     TRACE_EVENT1("GM", TRACE_FUNC, "name", TRACE_STR_COPY(this->getName()));
-    return this->onGpuSetup(context, errorMsg);
+    DrawResult gpuSetupResult = this->onGpuSetup(context, errorMsg);
+    if (DrawResult::kOk != gpuSetupResult) {
+        handle_gm_failure(canvas, gpuSetupResult, *errorMsg);
+    }
+    return gpuSetupResult;
 }
 
 void GM::gpuTeardown() {
@@ -92,13 +106,7 @@
     SkAutoCanvasRestore acr(canvas, true);
     DrawResult drawResult = this->onDraw(canvas, errorMsg);
     if (DrawResult::kOk != drawResult) {
-        if (DrawResult::kFail == drawResult) {
-            draw_failure_message(canvas, "DRAW FAILED: %s", errorMsg->c_str());
-        } else if (SkString(kErrorMsg_DrawSkippedGpuOnly) == *errorMsg) {
-            draw_gpu_only_message(canvas);
-        } else {
-            draw_failure_message(canvas, "DRAW SKIPPED: %s", errorMsg->c_str());
-        }
+        handle_gm_failure(canvas, drawResult, *errorMsg);
     }
     return drawResult;
 }
diff --git a/gm/gm.h b/gm/gm.h
index 36d3de3..4bcfccb 100644
--- a/gm/gm.h
+++ b/gm/gm.h
@@ -110,7 +110,11 @@
 
         static constexpr char kErrorMsg_DrawSkippedGpuOnly[] = "This test is for GPU configs only.";
 
-        DrawResult gpuSetup(GrContext*, SkString* errorMsg);
+        DrawResult gpuSetup(GrContext* context, SkCanvas* canvas) {
+            SkString errorMsg;
+            return this->gpuSetup(context, canvas, &errorMsg);
+        }
+        DrawResult gpuSetup(GrContext*, SkCanvas*, SkString* errorMsg);
         void gpuTeardown();
 
         void onceBeforeDraw() {
diff --git a/tools/fm/fm.cpp b/tools/fm/fm.cpp
index b990913..a14425c 100644
--- a/tools/fm/fm.cpp
+++ b/tools/fm/fm.cpp
@@ -132,7 +132,7 @@
     source->tweak = [gm](GrContextOptions* options) { gm->modifyGrContextOptions(options); };
     source->draw  = [gm](SkCanvas* canvas) {
         SkString err;
-        switch (gm->gpuSetup(canvas->getGrContext(), &err)) {
+        switch (gm->gpuSetup(canvas->getGrContext(), canvas, &err)) {
             case skiagm::DrawResult::kOk  : break;
             case skiagm::DrawResult::kSkip: return skip;
             case skiagm::DrawResult::kFail: return fail(err.c_str());
diff --git a/tools/viewer/GMSlide.cpp b/tools/viewer/GMSlide.cpp
index 1f904eb..c31514e 100644
--- a/tools/viewer/GMSlide.cpp
+++ b/tools/viewer/GMSlide.cpp
@@ -15,6 +15,8 @@
 #include "tools/viewer/GMSlide.h"
 
 GMSlide::GMSlide(std::unique_ptr<skiagm::GM> gm) : fGM(std::move(gm)) {
+    fGM->setMode(skiagm::GM::kSample_Mode);
+
     fName.printf("GM_%s", fGM->getName());
 }
 
@@ -23,13 +25,12 @@
 void GMSlide::draw(SkCanvas* canvas) {
     SkString msg;
 
-    fGM->setMode(skiagm::GM::kSample_Mode);
+    auto result = fGM->gpuSetup(canvas->getGrContext(), canvas, &msg);
+    if (result != skiagm::GM::DrawResult::kOk) {
+        return;
+    }
 
-    fGM->gpuSetup(canvas->getGrContext(), &msg);
-    // Do we care about timing the draw of the background (once)?
-    // Does the GM ever rely on drawBackground to lazily compute something?
-    fGM->drawBackground(canvas);
-    fGM->drawContent(canvas, &msg);
+    fGM->draw(canvas, &msg);
 }
 
 bool GMSlide::animate(double nanos) { return fGM->animate(nanos); }