diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp index eaa9a7d707..2210c7bdd1 100644 --- a/gm/beziereffects.cpp +++ b/gm/beziereffects.cpp @@ -128,7 +128,7 @@ private: /** * This GM directly exercises effects that draw Bezier curves in the GPU backend. */ -class BezierConicEffects : public GM { +class BezierConicEffects : public GpuGM { public: BezierConicEffects() { this->setBGColor(0xFFFFFFFF); @@ -144,19 +144,8 @@ protected: } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { struct Vertex { SkPoint fPosition; float fKLM[4]; // The last value is ignored. The effect expects a vec4f. @@ -345,7 +334,7 @@ private: /** * This GM directly exercises effects that draw Bezier quad curves in the GPU backend. */ -class BezierQuadEffects : public GM { +class BezierQuadEffects : public GpuGM { public: BezierQuadEffects() { this->setBGColor(0xFFFFFFFF); @@ -361,19 +350,8 @@ protected: } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { struct Vertex { SkPoint fPosition; float fUV[4]; // The last two values are ignored. The effect expects a vec4f. diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp index 6d55c9b507..613cf2d984 100644 --- a/gm/bigrrectaaeffect.cpp +++ b/gm/bigrrectaaeffect.cpp @@ -19,7 +19,7 @@ namespace skiagm { /////////////////////////////////////////////////////////////////////////////// -class BigRRectAAEffectGM : public GM { +class BigRRectAAEffectGM : public GpuGM { public: BigRRectAAEffectGM(const SkRRect& rrect, const char* name) : fRRect(rrect) @@ -48,19 +48,8 @@ protected: SkISize onISize() override { return SkISize::Make(fWidth, fHeight); } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { SkPaint paint; int y = kPad; diff --git a/gm/bitmaptiled.cpp b/gm/bitmaptiled.cpp index 20469360db..053a0b1b38 100644 --- a/gm/bitmaptiled.cpp +++ b/gm/bitmaptiled.cpp @@ -11,13 +11,8 @@ // This test exercises Ganesh's drawing of tiled bitmaps. In particular, that the offsets and the // extents of the tiles don't causes gaps between tiles. -static void draw_tile_bitmap_with_fractional_offset(SkCanvas* canvas, bool vertical) { - GrContext* context = canvas->getGrContext(); - if (!context) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - +static void draw_tile_bitmap_with_fractional_offset(GrContext* context, SkCanvas* canvas, + bool vertical) { // This should match kBmpSmallTileSize in SkGpuDevice.cpp. Note that our canvas size is tuned // to this constant as well. const int kTileSize = 1 << 10; @@ -63,10 +58,12 @@ static void draw_tile_bitmap_with_fractional_offset(SkCanvas* canvas, bool verti context->setResourceCacheLimits(oldMaxResources, oldMaxResourceBytes); } -DEF_SIMPLE_GM_BG(bitmaptiled_fractional_horizontal, canvas, 1124, 365, SK_ColorBLACK) { - draw_tile_bitmap_with_fractional_offset(canvas, false); +DEF_SIMPLE_GPU_GM_BG( + bitmaptiled_fractional_horizontal, context, rtc, canvas, 1124, 365, SK_ColorBLACK) { + draw_tile_bitmap_with_fractional_offset(context, canvas, false); } -DEF_SIMPLE_GM_BG(bitmaptiled_fractional_vertical, canvas, 365, 1124, SK_ColorBLACK) { - draw_tile_bitmap_with_fractional_offset(canvas, true); +DEF_SIMPLE_GPU_GM_BG( + bitmaptiled_fractional_vertical, context, rtc, canvas, 365, 1124, SK_ColorBLACK) { + draw_tile_bitmap_with_fractional_offset(context, canvas, true); } diff --git a/gm/clockwise.cpp b/gm/clockwise.cpp index 9b1ef3fa99..269a5fbcf2 100644 --- a/gm/clockwise.cpp +++ b/gm/clockwise.cpp @@ -30,11 +30,11 @@ static constexpr GrGeometryProcessor::Attribute gVertex = * triangles (sk_Clockwise), in terms of to Skia device space, in all backends and with all render * target origins. We draw clockwise triangles green and counter-clockwise red. */ -class ClockwiseGM : public GM { +class ClockwiseGM : public GpuGM { private: SkString onShortName() final { return SkString("clockwise"); } SkISize onISize() override { return SkISize::Make(300, 200); } - void onDraw(SkCanvas*) override; + void onDraw(GrContext*, GrRenderTargetContext*, SkCanvas*) override; }; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -138,14 +138,7 @@ private: //////////////////////////////////////////////////////////////////////////////////////////////////// // Test. -void ClockwiseGM::onDraw(SkCanvas* canvas) { - GrContext* ctx = canvas->getGrContext(); - GrRenderTargetContext* rtc = canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!ctx || !rtc) { - DrawGpuOnlyMessage(canvas); - return; - } - +void ClockwiseGM::onDraw(GrContext* ctx, GrRenderTargetContext* rtc, SkCanvas* canvas) { rtc->clear(nullptr, { 0, 0, 0, 1 }, GrRenderTargetContext::CanClearFullscreen::kYes); // Draw the test directly to the frame buffer. diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp index 2e676a20b2..af99e60e61 100644 --- a/gm/constcolorprocessor.cpp +++ b/gm/constcolorprocessor.cpp @@ -22,7 +22,7 @@ namespace skiagm { /** * This GM directly exercises GrConstColorProcessor. */ -class ConstColorProcessor : public GM { +class ConstColorProcessor : public GpuGM { public: ConstColorProcessor() { this->setBGColor(0xFFDDDDDD); @@ -44,19 +44,8 @@ protected: SkShader::kClamp_TileMode); } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { constexpr GrColor kColors[] = { 0xFFFFFFFF, 0xFFFF00FF, diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp index 3888891c1f..6f8e64d771 100644 --- a/gm/convexpolyeffect.cpp +++ b/gm/convexpolyeffect.cpp @@ -107,7 +107,7 @@ private: /** * This GM directly exercises a GrProcessor that draws convex polygons. */ -class ConvexPolyEffect : public GM { +class ConvexPolyEffect : public GpuGM { public: ConvexPolyEffect() { this->setBGColor(0xFFFFFFFF); @@ -177,19 +177,8 @@ protected: fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f)); } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { SkScalar y = 0; constexpr SkScalar kDX = 12.f; for (PathList::Iter iter(fPaths, PathList::Iter::kHead_IterStart); diff --git a/gm/crosscontextimage.cpp b/gm/crosscontextimage.cpp index 265331a722..9c948d9e01 100644 --- a/gm/crosscontextimage.cpp +++ b/gm/crosscontextimage.cpp @@ -11,13 +11,7 @@ #include "GrContext.h" #include "SkImage.h" -DEF_SIMPLE_GM(cross_context_image, canvas, 512 * 3 + 60, 512 + 128 + 30) { - GrContext* context = canvas->getGrContext(); - if (!context) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - +DEF_SIMPLE_GPU_GM(cross_context_image, context, rtc, canvas, 512 * 3 + 60, 512 + 128 + 30) { sk_sp encodedData = GetResourceAsData("images/mandrill_512.png"); if (!encodedData) { skiagm::GM::DrawFailureMessage(canvas, "Could not load mandrill_512.png. " diff --git a/gm/discard.cpp b/gm/discard.cpp index d0c17a8bab..b4fe7e7519 100644 --- a/gm/discard.cpp +++ b/gm/discard.cpp @@ -18,7 +18,7 @@ namespace skiagm { * This GM exercises SkCanvas::discard() by creating an offscreen SkSurface and repeatedly * discarding it, drawing to it, and then drawing it to the main canvas. */ -class DiscardGM : public GM { +class DiscardGM : public GpuGM { public: DiscardGM() { @@ -33,12 +33,7 @@ protected: return SkISize::Make(100, 100); } - void onDraw(SkCanvas* canvas) override { - GrContext* context = canvas->getGrContext(); - if (nullptr == context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override { SkISize size = this->getISize(); size.fWidth /= 10; size.fHeight /= 10; diff --git a/gm/etc1.cpp b/gm/etc1.cpp index d9895d815d..4a716f5359 100644 --- a/gm/etc1.cpp +++ b/gm/etc1.cpp @@ -22,7 +22,7 @@ #include "ops/GrFillRectOp.h" // Basic test of Ganesh's ETC1 support -class ETC1GM : public skiagm::GM { +class ETC1GM : public skiagm::GpuGM { public: ETC1GM() { this->setBGColor(0xFFCCCCCC); @@ -62,20 +62,8 @@ protected: } } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context || context->abandoned()) { - DrawFailureMessage(canvas, "GrContext unavailable or abandoned."); - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { sk_sp image = SkImage::MakeFromCompressed(context, fETC1Data, kTexWidth, kTexHeight, SkImage::kETC1_CompressionType); diff --git a/gm/flippity.cpp b/gm/flippity.cpp index 3d51cdd6b6..ccd16f6856 100644 --- a/gm/flippity.cpp +++ b/gm/flippity.cpp @@ -139,7 +139,7 @@ static bool UVMatToGeomMatForImage(SkMatrix* geomMat, const SkMatrix& uvMat) { // This GM exercises drawImage with a set of matrices that use an unusual amount of flips and // rotates. -class FlippityGM : public skiagm::GM { +class FlippityGM : public skiagm::GpuGM { public: FlippityGM() { this->setBGColor(0xFFCCCCCC); @@ -225,13 +225,7 @@ protected: SkASSERT(kNumLabels == fLabels.count()); } - void onDraw(SkCanvas* canvas) override { - GrContext* context = canvas->getGrContext(); - if (!context) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override { this->makeLabels(context); canvas->save(); diff --git a/gm/fontcache.cpp b/gm/fontcache.cpp index 39d3b80bd8..9f637b1d87 100644 --- a/gm/fontcache.cpp +++ b/gm/fontcache.cpp @@ -27,7 +27,7 @@ static SkScalar draw_string(SkCanvas* canvas, const SkString& text, SkScalar x, return x + font.measureText(text.c_str(), text.size(), kUTF8_SkTextEncoding); } -class FontCacheGM : public skiagm::GM { +class FontCacheGM : public skiagm::GpuGM { public: FontCacheGM(GrContextOptions::Enable allowMultipleTextures) : fAllowMultipleTextures(allowMultipleTextures) { @@ -60,14 +60,7 @@ protected: fTypefaces[5] = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Bold()); } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - + void onDraw(GrContext*, GrRenderTargetContext* renderTargetContext, SkCanvas* canvas) override { this->drawText(canvas); // Debugging tool for GPU. static const bool kShowAtlas = false; diff --git a/gm/fontregen.cpp b/gm/fontregen.cpp index fbb555d9d5..ef2f509b43 100644 --- a/gm/fontregen.cpp +++ b/gm/fontregen.cpp @@ -36,7 +36,7 @@ static sk_sp make_blob(const SkString& text, const SkFont& font) { return SkTextBlob::MakeFromPosTextH(text.c_str(), len, pos.get(), 0, font); } -class FontRegenGM : public skiagm::GM { +class FontRegenGM : public skiagm::GpuGM { public: FontRegenGM() { this->setBGColor(SK_ColorLTGRAY); @@ -76,14 +76,7 @@ protected: fBlobs[2] = make_blob(kTexts[2], font); } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - + void onDraw(GrContext*, GrRenderTargetContext* renderTargetContext, SkCanvas* canvas) override { SkPaint paint; paint.setColor(SK_ColorBLACK); canvas->drawTextBlob(fBlobs[0], 10, 80, paint); diff --git a/gm/fwidth_squircle.cpp b/gm/fwidth_squircle.cpp index 76ad2d4ccc..3ae8cbeb91 100644 --- a/gm/fwidth_squircle.cpp +++ b/gm/fwidth_squircle.cpp @@ -21,21 +21,14 @@ #include "glsl/GrGLSLVarying.h" #include "glsl/GrGLSLVertexGeoBuilder.h" +/** + * This test ensures that fwidth() works properly on GPU configs by drawing a squircle. + */ namespace skiagm { static constexpr GrGeometryProcessor::Attribute gVertex = {"bboxcoord", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; -/** - * This ensures that fwidth() works properly on GPU configs by drawing a squircle. - */ -class FwidthSquircleGM : public GM { -private: - SkString onShortName() final { return SkString("fwidth_squircle"); } - SkISize onISize() override { return SkISize::Make(200, 200); } - void onDraw(SkCanvas*) override; -}; - //////////////////////////////////////////////////////////////////////////////////////////////////// // SkSL code. @@ -162,29 +155,17 @@ private: //////////////////////////////////////////////////////////////////////////////////////////////////// // Test. -void FwidthSquircleGM::onDraw(SkCanvas* canvas) { - GrContext* ctx = canvas->getGrContext(); - GrRenderTargetContext* rtc = canvas->internal_private_accessTopLayerRenderTargetContext(); - - canvas->clear(SK_ColorWHITE); - - if (!ctx || !rtc) { - DrawGpuOnlyMessage(canvas); - return; - } - +DEF_SIMPLE_GPU_GM(fwidth_squircle, ctx, rtc, canvas, 200, 200) { if (!ctx->priv().caps()->shaderCaps()->shaderDerivativeSupport()) { - SkFont font(sk_tool_utils::create_portable_typeface(), 15); - DrawFailureMessage(canvas, "Shader derivatives not supported."); + skiagm::GM::DrawFailureMessage(canvas, "Shader derivatives not supported."); return; } // Draw the test directly to the frame buffer. + canvas->clear(SK_ColorWHITE); rtc->priv().testingOnly_addDrawOp(FwidthSquircleTestOp::Make(ctx, canvas->getTotalMatrix())); } -DEF_GM( return new FwidthSquircleGM(); ) - } #endif // SK_SUPPORT_GPU diff --git a/gm/gm.cpp b/gm/gm.cpp index 25ab29afe1..aef7184495 100644 --- a/gm/gm.cpp +++ b/gm/gm.cpp @@ -6,14 +6,16 @@ */ #include "gm.h" + +#include "GrContext.h" #include "sk_tool_utils.h" #include "SkShader.h" #include "SkTraceEvent.h" using namespace skiagm; -GM::GM() { +GM::GM(SkColor bgColor) { fMode = kGM_Mode; - fBGColor = SK_ColorWHITE; + fBGColor = bgColor; fCanvasIsDeferred = false; fHaveCalledOnceBeforeDraw = false; } @@ -113,16 +115,18 @@ void GM::DrawFailureMessage(SkCanvas* canvas, const char format[], ...) { // need to explicitly declare this, or we get some weird infinite loop llist template GMRegistry* GMRegistry::gHead; -void skiagm::SimpleGM::onDraw(SkCanvas* canvas) { - fDrawProc(canvas); -} - -SkISize skiagm::SimpleGM::onISize() { - return fSize; -} - -SkString skiagm::SimpleGM::onShortName() { - return fName; +void GpuGM::onDraw(SkCanvas* canvas) { + GrContext* ctx = canvas->getGrContext(); + GrRenderTargetContext* rtc = canvas->internal_private_accessTopLayerRenderTargetContext(); + if (!ctx || !rtc) { + skiagm::GM::DrawGpuOnlyMessage(canvas); + return; + } + if (ctx->abandoned()) { + skiagm::GM::DrawFailureMessage(canvas, "GrContext abandoned."); + return; + } + this->onDraw(ctx, rtc, canvas); } template diff --git a/gm/gm.h b/gm/gm.h index 5e8d8f6e4e..f7e7b56ab0 100644 --- a/gm/gm.h +++ b/gm/gm.h @@ -25,28 +25,38 @@ struct GrContextOptions; static skiagm::GM* SK_MACRO_APPEND_LINE(F_)(void*) { code; } \ static skiagm::GMRegistry SK_MACRO_APPEND_LINE(R_)(SK_MACRO_APPEND_LINE(F_)); -// a Simple GM is a rendering test that does not store state between -// rendering calls or make use of the onOnceBeforeDraw() virtual; it -// consists of: -// * A single void(*)(SkCanvas*) function. +// A Simple GM is a rendering test that does not store state between rendering calls or make use of +// the onOnceBeforeDraw() virtual; it consists of: // * A name. // * Prefered width and height. // * Optionally, a background color (default is white). +// * A standalone function pointer that implements its onDraw method. #define DEF_SIMPLE_GM(NAME, CANVAS, W, H) \ DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, SK_ColorWHITE, SkString(#NAME)) -#define DEF_SIMPLE_GM_BG(NAME, CANVAS, W, H, BGCOLOR)\ +#define DEF_SIMPLE_GM_BG(NAME, CANVAS, W, H, BGCOLOR) \ DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, BGCOLOR, SkString(#NAME)) -#define DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, BGCOLOR, NAME_STR) \ - static void SK_MACRO_CONCAT(NAME, _GM)(SkCanvas * CANVAS); \ - DEF_GM(return new skiagm::SimpleGM(NAME_STR, SK_MACRO_CONCAT(NAME, _GM), \ - SkISize::Make(W, H), BGCOLOR);) \ +#define DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, BGCOLOR, NAME_STR) \ + static void SK_MACRO_CONCAT(NAME, _GM)(SkCanvas * CANVAS); \ + DEF_GM(return new skiagm::SimpleGM(BGCOLOR, NAME_STR, SkISize::Make(W, H), \ + SK_MACRO_CONCAT(NAME, _GM));) \ void SK_MACRO_CONCAT(NAME, _GM)(SkCanvas * CANVAS) +// A Simple GpuGM makes direct GPU calls. Its onDraw hook that includes GPU objects as params, and +// is only invoked on GPU configs. Non-GPU configs automatically draw a GPU-only message and abort. +#define DEF_SIMPLE_GPU_GM(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, W, H) \ + DEF_SIMPLE_GPU_GM_BG(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, W, H, SK_ColorWHITE) +#define DEF_SIMPLE_GPU_GM_BG(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, W, H, BGCOLOR)\ + static void SK_MACRO_CONCAT(NAME, _GM)(GrContext*, GrRenderTargetContext*, SkCanvas*); \ + DEF_GM(return new skiagm::SimpleGpuGM(BGCOLOR, SkString(#NAME), SkISize::Make(W, H), \ + SK_MACRO_CONCAT(NAME, _GM));) \ + void SK_MACRO_CONCAT(NAME, _GM)( \ + GrContext* GR_CONTEXT, GrRenderTargetContext* RENDER_TARGET_CONTEXT, SkCanvas* CANVAS) + namespace skiagm { class GM { public: - GM(); + GM(SkColor backgroundColor = SK_ColorWHITE); virtual ~GM(); enum Mode { @@ -77,8 +87,7 @@ namespace skiagm { SkColor getBGColor() const { return fBGColor; } void setBGColor(SkColor); - // helper: fill a rect in the specified color based on the - // GM's getISize bounds. + // helper: fill a rect in the specified color based on the GM's getISize bounds. void drawSizeBounds(SkCanvas*, SkColor); bool isCanvasDeferred() const { return fCanvasIsDeferred; } @@ -123,26 +132,53 @@ namespace skiagm { typedef GM*(*GMFactory)(void*) ; typedef sk_tools::Registry GMRegistry; - class SimpleGM : public skiagm::GM { + // A GpuGM replaces the onDraw method with one that also accepts GPU objects alongside the + // SkCanvas. Its onDraw is only invoked on GPU configs; on non-GPU configs it will automatically + // draw a GPU-only message and abort. + class GpuGM : public GM { public: - SimpleGM(const SkString& name, - void (*drawProc)(SkCanvas*), - const SkISize& size, - SkColor backgroundColor) - : fName(name), fDrawProc(drawProc), fSize(size) { - if (backgroundColor != SK_ColorWHITE) { - this->setBGColor(backgroundColor); - } - } - protected: - void onDraw(SkCanvas* canvas) override; - SkISize onISize() override; - SkString onShortName() override; + GpuGM(SkColor backgroundColor = SK_ColorWHITE) : GM(backgroundColor) {} private: - SkString fName; - void (*fDrawProc)(SkCanvas*); - SkISize fSize; + void onDraw(SkCanvas*) final; + virtual void onDraw(GrContext*, GrRenderTargetContext*, SkCanvas*) = 0; }; + + // SimpleGM is intended for basic GMs that can define their entire implementation inside a + // single "draw" function pointer. + class SimpleGM : public GM { + public: + using DrawProc = void(*)(SkCanvas*); + SimpleGM(SkColor bgColor, const SkString& name, const SkISize& size, DrawProc drawProc) + : GM(bgColor), fName(name), fSize(size), fDrawProc(drawProc) {} + + private: + SkISize onISize() override { return fSize; } + SkString onShortName() override { return fName; } + void onDraw(SkCanvas* canvas) override { fDrawProc(canvas); } + + const SkString fName; + const SkISize fSize; + const DrawProc fDrawProc; + }; + + class SimpleGpuGM : public GpuGM { + public: + using DrawProc = void(*)(GrContext*, GrRenderTargetContext*, SkCanvas*); + SimpleGpuGM(SkColor bgColor, const SkString& name, const SkISize& size, DrawProc drawProc) + : GpuGM(bgColor), fName(name), fSize(size), fDrawProc(drawProc) {} + + private: + SkISize onISize() override { return fSize; } + SkString onShortName() override { return fName; } + void onDraw(GrContext* ctx, GrRenderTargetContext* rtc, SkCanvas* canvas) override { + fDrawProc(ctx, rtc, canvas); + } + + const SkString fName; + const SkISize fSize; + const DrawProc fDrawProc; + }; + } void MarkGMGood(SkCanvas*, SkScalar x, SkScalar y); diff --git a/gm/image.cpp b/gm/image.cpp index 743fa220ca..98a579b105 100644 --- a/gm/image.cpp +++ b/gm/image.cpp @@ -263,13 +263,7 @@ DEF_GM( return new ScalePixelsGM; ) /////////////////////////////////////////////////////////////////////////////////////////////////// -DEF_SIMPLE_GM(new_texture_image, canvas, 280, 60) { - GrContext* context = canvas->getGrContext(); - if (!context) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - +DEF_SIMPLE_GPU_GM(new_texture_image, context, rtc, canvas, 280, 60) { auto render_image = [](SkCanvas* canvas) { canvas->clear(SK_ColorBLUE); SkPaint paint; diff --git a/gm/imagefromyuvtextures.cpp b/gm/imagefromyuvtextures.cpp index 7ba86c0995..42cc8d84ea 100644 --- a/gm/imagefromyuvtextures.cpp +++ b/gm/imagefromyuvtextures.cpp @@ -19,7 +19,7 @@ #include "SkTo.h" namespace skiagm { -class ImageFromYUVTextures : public GM { +class ImageFromYUVTextures : public GpuGM { public: ImageFromYUVTextures() { this->setBGColor(0xFFFFFFFF); @@ -94,10 +94,6 @@ protected: } void createYUVTextures(GrContext* context, GrBackendTexture yuvTextures[3]) { - if (context->abandoned()) { - return; - } - GrGpu* gpu = context->priv().getGpu(); if (!gpu) { return; @@ -116,10 +112,6 @@ protected: void createResultTexture(GrContext* context, int width, int height, GrBackendTexture* resultTexture) { - if (context->abandoned()) { - return; - } - GrGpu* gpu = context->priv().getGpu(); if (!gpu) { return; @@ -152,14 +144,7 @@ protected: context->resetContext(); } - void onDraw(SkCanvas* canvas) override { - GrContext* context = canvas->getGrContext(); - if (!context) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - + void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override { constexpr SkScalar kPad = 10.f; SkTArray> images; diff --git a/gm/rectangletexture.cpp b/gm/rectangletexture.cpp index fbc685a4a7..4a3c2f648e 100644 --- a/gm/rectangletexture.cpp +++ b/gm/rectangletexture.cpp @@ -19,7 +19,7 @@ #include "SkImage.h" namespace skiagm { -class RectangleTexture : public GM { +class RectangleTexture : public GpuGM { public: RectangleTexture() { this->setBGColor(0xFFFFFFFF); @@ -54,12 +54,6 @@ protected: sk_sp createRectangleTextureImg(GrContext* context, GrSurfaceOrigin origin, int width, int height, const uint32_t* pixels) { - if (!context) { - return nullptr; - } - if (context->abandoned()) { - return nullptr; - } GrGpu* gpu = context->priv().getGpu(); if (!gpu) { return nullptr; @@ -123,13 +117,7 @@ protected: return nullptr; } - void onDraw(SkCanvas* canvas) override { - GrContext *context = canvas->getGrContext(); - if (!context) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override { constexpr int kWidth = 50; constexpr int kHeight = 50; constexpr SkScalar kPad = 5.f; diff --git a/gm/textblobrandomfont.cpp b/gm/textblobrandomfont.cpp index e0f1cf5a71..581e99d57a 100644 --- a/gm/textblobrandomfont.cpp +++ b/gm/textblobrandomfont.cpp @@ -20,7 +20,7 @@ #include "GrContext.h" namespace skiagm { -class TextBlobRandomFont : public GM { +class TextBlobRandomFont : public GpuGM { public: // This gm tests that textblobs can be translated and scaled with a font that returns random // but deterministic masks @@ -93,15 +93,10 @@ protected: return SkISize::Make(kWidth, kHeight); } - void onDraw(SkCanvas* canvas) override { + void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override { // This GM exists to test a specific feature of the GPU backend. // This GM uses sk_tool_utils::makeSurface which doesn't work well with vias. // This GM uses SkRandomTypeface which doesn't work well with serialization. - if (nullptr == canvas->getGrContext()) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - canvas->drawColor(SK_ColorWHITE); SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, canvas->imageInfo().colorType(), @@ -132,20 +127,14 @@ protected: yOffset += stride; canvas->restore(); - // this will test lcd masks when not requested - // on cpu this currently causes unspecified behavior, so avoid until it is fixed - if (canvas->getGrContext()) { - // Rotate in the surface canvas, not the final canvas, to avoid aliasing - surfaceCanvas->rotate(-0.05f); - surfaceCanvas->drawTextBlob(fBlob, 10, yOffset, paint); - surface->draw(canvas, 0, 0, nullptr); - } + // Rotate in the surface canvas, not the final canvas, to avoid aliasing + surfaceCanvas->rotate(-0.05f); + surfaceCanvas->drawTextBlob(fBlob, 10, yOffset, paint); + surface->draw(canvas, 0, 0, nullptr); yOffset += stride; // free gpu resources and verify - if (canvas->getGrContext()) { - canvas->getGrContext()->freeGpuResources(); - } + context->freeGpuResources(); canvas->rotate(-0.05f); canvas->drawTextBlob(fBlob, 10, yOffset, paint); diff --git a/gm/textblobuseaftergpufree.cpp b/gm/textblobuseaftergpufree.cpp index f3f11d17da..075c934d09 100644 --- a/gm/textblobuseaftergpufree.cpp +++ b/gm/textblobuseaftergpufree.cpp @@ -15,7 +15,7 @@ // This tests that we correctly regenerate textblobs after freeing all gpu resources crbug/491350 namespace skiagm { -class TextBlobUseAfterGpuFree : public GM { +class TextBlobUseAfterGpuFree : public GpuGM { public: TextBlobUseAfterGpuFree() { } @@ -28,13 +28,7 @@ protected: return SkISize::Make(kWidth, kHeight); } - void onDraw(SkCanvas* canvas) override { - // This GM exists to test a specific feature of the GPU backend. - if (nullptr == canvas->getGrContext()) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override { const char text[] = "Hamburgefons"; SkFont font(sk_tool_utils::create_portable_typeface(), 20); @@ -48,7 +42,7 @@ protected: canvas->drawTextBlob(blob, 20, 60, SkPaint()); // This text should look fine - canvas->getGrContext()->freeGpuResources(); + context->freeGpuResources(); canvas->drawTextBlob(blob, 20, 160, SkPaint()); } diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp index 8eeefc2844..e56ee8b075 100644 --- a/gm/texturedomaineffect.cpp +++ b/gm/texturedomaineffect.cpp @@ -25,7 +25,7 @@ namespace skiagm { /** * This GM directly exercises GrTextureDomainEffect. */ -class TextureDomainEffect : public GM { +class TextureDomainEffect : public GpuGM { public: TextureDomainEffect(GrSamplerState::Filter filter) : fFilter(filter) { @@ -82,19 +82,8 @@ protected: fImage = surface->makeImageSnapshot(); } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { GrProxyProvider* proxyProvider = context->priv().proxyProvider(); sk_sp proxy; if (fFilter == GrSamplerState::Filter::kMipMap) { diff --git a/gm/wacky_yuv_formats.cpp b/gm/wacky_yuv_formats.cpp index 371db0ffeb..a98f019167 100644 --- a/gm/wacky_yuv_formats.cpp +++ b/gm/wacky_yuv_formats.cpp @@ -782,10 +782,6 @@ protected: } if (context) { - if (context->abandoned()) { - return; - } - GrGpu* gpu = context->priv().getGpu(); if (!gpu) { return; @@ -876,16 +872,14 @@ protected: } } if (auto context = canvas->getGrContext()) { - if (!context->abandoned()) { - context->flush(); - GrGpu* gpu = context->priv().getGpu(); - SkASSERT(gpu); - gpu->testingOnly_flushGpuAndSync(); - for (const auto& tex : fBackendTextures) { - gpu->deleteTestingOnlyBackendTexture(tex); - } - fBackendTextures.reset(); + context->flush(); + GrGpu* gpu = context->priv().getGpu(); + SkASSERT(gpu); + gpu->testingOnly_flushGpuAndSync(); + for (const auto& tex : fBackendTextures) { + gpu->deleteTestingOnlyBackendTexture(tex); } + fBackendTextures.reset(); } SkASSERT(!fBackendTextures.count()); } diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp index f2993389ff..12d651b504 100644 --- a/gm/yuvtorgbeffect.cpp +++ b/gm/yuvtorgbeffect.cpp @@ -29,7 +29,7 @@ namespace skiagm { /** * This GM directly exercises GrYUVtoRGBEffect. */ -class YUVtoRGBEffect : public GM { +class YUVtoRGBEffect : public GpuGM { public: YUVtoRGBEffect() { this->setBGColor(0xFFFFFFFF); @@ -72,19 +72,8 @@ protected: } } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { GrProxyProvider* proxyProvider = context->priv().proxyProvider(); sk_sp proxies[3]; @@ -149,7 +138,7 @@ DEF_GM(return new YUVtoRGBEffect;) ////////////////////////////////////////////////////////////////////////////// -class YUVNV12toRGBEffect : public GM { +class YUVNV12toRGBEffect : public GpuGM { public: YUVNV12toRGBEffect() { this->setBGColor(0xFFFFFFFF); @@ -200,19 +189,8 @@ protected: } } - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - + void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext, + SkCanvas* canvas) override { GrProxyProvider* proxyProvider = context->priv().proxyProvider(); sk_sp proxies[2];