blob: 1bebe6b3c2ddfd8ae55aa8e4f11462bcbd40e95c [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00007
reed@android.com00dae862009-06-10 15:38:48 +00008#ifndef skiagm_DEFINED
9#define skiagm_DEFINED
10
Tyler Denniston45f94f82020-02-04 16:09:08 -050011#include "gm/verifiers/gmverifier.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040012#include "include/core/SkColor.h"
13#include "include/core/SkScalar.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkSize.h"
15#include "include/core/SkString.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040016#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "include/private/SkMacros.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "tools/Registry.h"
reed@android.com00dae862009-06-10 15:38:48 +000019
Hal Canaryedda5652019-08-05 10:28:09 -040020#include <memory>
21
Ben Wagner7fde8e12019-05-01 17:28:53 -040022class GrContext;
23class GrRenderTargetContext;
24class SkCanvas;
Mike Reed88f56712019-02-04 16:50:10 -050025class SkMetaData;
bsalomon4ee6bd82015-05-27 13:23:23 -070026struct GrContextOptions;
mtklein@google.com62b50b72013-09-16 20:42:15 +000027
Hal Canaryedda5652019-08-05 10:28:09 -040028#define DEF_GM(CODE) \
29 static skiagm::GMRegistry SK_MACRO_APPEND_LINE(REG_)(\
30 [](){return std::unique_ptr<skiagm::GM>([](){ CODE ; }());});
reed@google.com4117a242012-10-30 20:26:58 +000031
Chris Dalton3a778372019-02-07 15:23:36 -070032// A Simple GM is a rendering test that does not store state between rendering calls or make use of
33// the onOnceBeforeDraw() virtual; it consists of:
halcanary2a243382015-09-09 08:16:41 -070034// * A name.
35// * Prefered width and height.
36// * Optionally, a background color (default is white).
Chris Dalton3a778372019-02-07 15:23:36 -070037// * A standalone function pointer that implements its onDraw method.
halcanary2a243382015-09-09 08:16:41 -070038#define DEF_SIMPLE_GM(NAME, CANVAS, W, H) \
39 DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, SK_ColorWHITE, SkString(#NAME))
Chris Dalton3a778372019-02-07 15:23:36 -070040#define DEF_SIMPLE_GM_BG(NAME, CANVAS, W, H, BGCOLOR) \
halcanary2a243382015-09-09 08:16:41 -070041 DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, BGCOLOR, SkString(#NAME))
Chris Dalton3a778372019-02-07 15:23:36 -070042#define DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, BGCOLOR, NAME_STR) \
Chris Dalton50e24d72019-02-07 16:20:09 -070043 static void SK_MACRO_CONCAT(NAME,_GM_inner)(SkCanvas*); \
44 DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS,, W, H, BGCOLOR, NAME_STR) { \
45 SK_MACRO_CONCAT(NAME,_GM_inner)(CANVAS); \
46 return skiagm::DrawResult::kOk; \
47 } \
48 void SK_MACRO_CONCAT(NAME,_GM_inner)(SkCanvas* CANVAS)
49
50#define DEF_SIMPLE_GM_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H) \
51 DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, SK_ColorWHITE, SkString(#NAME))
52#define DEF_SIMPLE_GM_BG_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, BGCOLOR) \
53 DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, BGCOLOR, SkString(#NAME))
54#define DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, BGCOLOR, NAME_STR) \
55 static skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)(SkCanvas*, SkString*); \
56 DEF_GM(return new skiagm::SimpleGM(BGCOLOR, NAME_STR, {W,H}, SK_MACRO_CONCAT(NAME,_GM));) \
57 skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)(SkCanvas* CANVAS, SkString* ERR_MSG)
58
halcanary30b83d42014-10-26 05:23:53 -070059
Chris Dalton3a778372019-02-07 15:23:36 -070060// A Simple GpuGM makes direct GPU calls. Its onDraw hook that includes GPU objects as params, and
61// is only invoked on GPU configs. Non-GPU configs automatically draw a GPU-only message and abort.
62#define DEF_SIMPLE_GPU_GM(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, W, H) \
63 DEF_SIMPLE_GPU_GM_BG(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, W, H, SK_ColorWHITE)
Chris Dalton50e24d72019-02-07 16:20:09 -070064#define DEF_SIMPLE_GPU_GM_BG(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, W, H, BGCOLOR) \
65 static void SK_MACRO_CONCAT(NAME,_GM_inner)(GrContext*, GrRenderTargetContext*, SkCanvas*); \
66 DEF_SIMPLE_GPU_GM_BG_CAN_FAIL(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS,, W, H, \
67 BGCOLOR) { \
68 SK_MACRO_CONCAT(NAME,_GM_inner)(GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS); \
69 return skiagm::DrawResult::kOk; \
70 } \
71 void SK_MACRO_CONCAT(NAME,_GM_inner)( \
Chris Dalton3a778372019-02-07 15:23:36 -070072 GrContext* GR_CONTEXT, GrRenderTargetContext* RENDER_TARGET_CONTEXT, SkCanvas* CANVAS)
73
Chris Dalton50e24d72019-02-07 16:20:09 -070074#define DEF_SIMPLE_GPU_GM_CAN_FAIL(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, ERR_MSG, W, H) \
75 DEF_SIMPLE_GPU_GM_BG_CAN_FAIL(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, \
76 ERR_MSG, W, H, SK_ColorWHITE)
77#define DEF_SIMPLE_GPU_GM_BG_CAN_FAIL(NAME, GR_CONTEXT, RENDER_TARGET_CONTEXT, CANVAS, ERR_MSG, W, \
78 H, BGCOLOR) \
79 static skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)( \
80 GrContext*, GrRenderTargetContext*, SkCanvas*, SkString*); \
81 DEF_GM(return new skiagm::SimpleGpuGM(BGCOLOR, SkString(#NAME), {W,H}, \
82 SK_MACRO_CONCAT(NAME,_GM));) \
83 skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)( \
84 GrContext* GR_CONTEXT, GrRenderTargetContext* RENDER_TARGET_CONTEXT, SkCanvas* CANVAS, \
85 SkString* ERR_MSG)
86
reed@android.com00dae862009-06-10 15:38:48 +000087namespace skiagm {
rmistry@google.comd6176b02012-08-23 18:14:13 +000088
Chris Dalton50e24d72019-02-07 16:20:09 -070089 enum class DrawResult {
90 kOk, // Test drew successfully.
91 kFail, // Test failed to draw.
92 kSkip // Test is not applicable in this context and should be skipped.
93 };
94
reed@android.com00dae862009-06-10 15:38:48 +000095 class GM {
96 public:
Chris Dalton50e24d72019-02-07 16:20:09 -070097 using DrawResult = skiagm::DrawResult;
98
Chris Dalton3a778372019-02-07 15:23:36 -070099 GM(SkColor backgroundColor = SK_ColorWHITE);
reed@android.com00dae862009-06-10 15:38:48 +0000100 virtual ~GM();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000101
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000102 enum Mode {
103 kGM_Mode,
104 kSample_Mode,
105 kBench_Mode,
106 };
107
108 void setMode(Mode mode) { fMode = mode; }
109 Mode getMode() const { return fMode; }
110
Chris Dalton50e24d72019-02-07 16:20:09 -0700111 static constexpr char kErrorMsg_DrawSkippedGpuOnly[] = "This test is for GPU configs only.";
112
113 DrawResult draw(SkCanvas* canvas) {
114 SkString errorMsg;
115 return this->draw(canvas, &errorMsg);
116 }
117 DrawResult draw(SkCanvas*, SkString* errorMsg);
118
bsalomon@google.com48dd1a22011-10-31 14:18:20 +0000119 void drawBackground(SkCanvas*);
Chris Dalton50e24d72019-02-07 16:20:09 -0700120 DrawResult drawContent(SkCanvas* canvas) {
121 SkString errorMsg;
122 return this->drawContent(canvas, &errorMsg);
123 }
124 DrawResult drawContent(SkCanvas*, SkString* errorMsg);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000125
mtkleinf4ba3212015-01-28 15:32:24 -0800126 SkISize getISize() { return this->onISize(); }
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000127 const char* getName();
reed@android.com00dae862009-06-10 15:38:48 +0000128
Mike Klein9707e902019-02-07 16:18:22 -0500129 virtual bool runAsBench() const;
mtkleincf5d9c92015-01-23 10:31:45 -0800130
reed@google.com487b5602013-02-01 15:01:24 +0000131 SkScalar width() {
132 return SkIntToScalar(this->getISize().width());
133 }
134 SkScalar height() {
scroggo@google.comab026272013-04-12 22:14:03 +0000135 return SkIntToScalar(this->getISize().height());
reed@google.com487b5602013-02-01 15:01:24 +0000136 }
137
reed@google.comb4b49cc2011-12-06 16:15:42 +0000138 SkColor getBGColor() const { return fBGColor; }
bsalomon@google.com48dd1a22011-10-31 14:18:20 +0000139 void setBGColor(SkColor);
reed@google.com30db5992011-08-29 17:41:02 +0000140
Chris Dalton3a778372019-02-07 15:23:36 -0700141 // helper: fill a rect in the specified color based on the GM's getISize bounds.
reed@google.com2d6ef522012-01-03 17:20:38 +0000142 void drawSizeBounds(SkCanvas*, SkColor);
143
Hal Canary41248072019-07-11 16:32:53 -0400144 bool animate(double /*nanos*/);
Hal Canaryc74a5502019-07-08 14:55:15 -0400145 virtual bool onChar(SkUnichar);
reedd9adfe62015-02-01 19:01:04 -0800146
Mike Reed81f60ec2018-05-15 10:09:52 -0400147 bool getControls(SkMetaData* controls) { return this->onGetControls(controls); }
148 void setControls(const SkMetaData& controls) { this->onSetControls(controls); }
149
Chris Dalton5b5403e2019-06-05 11:54:39 -0600150 virtual void modifyGrContextOptions(GrContextOptions*);
bsalomon4ee6bd82015-05-27 13:23:23 -0700151
Tyler Denniston45f94f82020-02-04 16:09:08 -0500152 virtual std::unique_ptr<verifiers::VerifierList> getVerifiers() const;
153
halcanary2a243382015-09-09 08:16:41 -0700154 protected:
Mike Klein9707e902019-02-07 16:18:22 -0500155 virtual void onOnceBeforeDraw();
156 virtual DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg);
157 virtual void onDraw(SkCanvas*);
158
robertphillips@google.com8570b5c2012-03-20 17:40:58 +0000159 virtual SkISize onISize() = 0;
reed@android.com8015dd82009-06-21 00:49:18 +0000160 virtual SkString onShortName() = 0;
mtklein1c402922015-01-23 11:07:07 -0800161
Hal Canary41248072019-07-11 16:32:53 -0400162 virtual bool onAnimate(double /*nanos*/);
Mike Klein9707e902019-02-07 16:18:22 -0500163 virtual bool onGetControls(SkMetaData*);
164 virtual void onSetControls(const SkMetaData&);
vandebo@chromium.org79d3cb42012-03-21 17:34:30 +0000165
reed@android.com8015dd82009-06-21 00:49:18 +0000166 private:
commit-bot@chromium.orgb21fac12014-02-07 21:13:11 +0000167 Mode fMode;
reed@android.com8015dd82009-06-21 00:49:18 +0000168 SkString fShortName;
bsalomon@google.com48dd1a22011-10-31 14:18:20 +0000169 SkColor fBGColor;
reed@google.com7775d662012-11-27 15:15:58 +0000170 bool fHaveCalledOnceBeforeDraw;
reed@android.com00dae862009-06-10 15:38:48 +0000171 };
172
Hal Canaryedda5652019-08-05 10:28:09 -0400173 using GMFactory = std::unique_ptr<skiagm::GM> (*)();
174 using GMRegistry = sk_tools::Registry<GMFactory>;
halcanaryf62c6342015-01-12 15:27:46 -0800175
Chris Dalton3a778372019-02-07 15:23:36 -0700176 // A GpuGM replaces the onDraw method with one that also accepts GPU objects alongside the
177 // SkCanvas. Its onDraw is only invoked on GPU configs; on non-GPU configs it will automatically
178 // draw a GPU-only message and abort.
179 class GpuGM : public GM {
halcanaryf62c6342015-01-12 15:27:46 -0800180 public:
Chris Dalton3a778372019-02-07 15:23:36 -0700181 GpuGM(SkColor backgroundColor = SK_ColorWHITE) : GM(backgroundColor) {}
Tyler Denniston45f94f82020-02-04 16:09:08 -0500182
183 // TODO(tdenniston): Currently GpuGMs don't have verifiers (because they do not render on
184 // CPU), but we may want to be able to verify the output images standalone, without
185 // requiring a gold image for comparison.
186 std::unique_ptr<verifiers::VerifierList> getVerifiers() const override { return nullptr; }
187
Chris Dalton382b1222019-02-07 10:05:55 +0000188 private:
Chris Dalton50e24d72019-02-07 16:20:09 -0700189 using GM::onDraw;
190 DrawResult onDraw(SkCanvas*, SkString* errorMsg) final;
Mike Klein9707e902019-02-07 16:18:22 -0500191
Chris Dalton50e24d72019-02-07 16:20:09 -0700192 virtual DrawResult onDraw(GrContext* ctx, GrRenderTargetContext* rtc, SkCanvas* canvas,
Mike Klein9707e902019-02-07 16:18:22 -0500193 SkString* errorMsg);
194 virtual void onDraw(GrContext*, GrRenderTargetContext*, SkCanvas*);
Chris Daltonf5efa782019-02-05 17:42:14 -0700195 };
Chris Dalton3a778372019-02-07 15:23:36 -0700196
197 // SimpleGM is intended for basic GMs that can define their entire implementation inside a
198 // single "draw" function pointer.
199 class SimpleGM : public GM {
200 public:
Chris Dalton50e24d72019-02-07 16:20:09 -0700201 using DrawProc = DrawResult(*)(SkCanvas*, SkString*);
Chris Dalton3a778372019-02-07 15:23:36 -0700202 SimpleGM(SkColor bgColor, const SkString& name, const SkISize& size, DrawProc drawProc)
203 : GM(bgColor), fName(name), fSize(size), fDrawProc(drawProc) {}
204
205 private:
Mike Klein9707e902019-02-07 16:18:22 -0500206 SkISize onISize() override;
207 SkString onShortName() override;
208 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override;
Chris Dalton3a778372019-02-07 15:23:36 -0700209
210 const SkString fName;
211 const SkISize fSize;
212 const DrawProc fDrawProc;
213 };
214
215 class SimpleGpuGM : public GpuGM {
216 public:
Chris Dalton50e24d72019-02-07 16:20:09 -0700217 using DrawProc = DrawResult(*)(GrContext*, GrRenderTargetContext*, SkCanvas*, SkString*);
Chris Dalton3a778372019-02-07 15:23:36 -0700218 SimpleGpuGM(SkColor bgColor, const SkString& name, const SkISize& size, DrawProc drawProc)
219 : GpuGM(bgColor), fName(name), fSize(size), fDrawProc(drawProc) {}
220
221 private:
Mike Klein9707e902019-02-07 16:18:22 -0500222 SkISize onISize() override;
223 SkString onShortName() override;
Chris Dalton50e24d72019-02-07 16:20:09 -0700224 DrawResult onDraw(GrContext* ctx, GrRenderTargetContext* rtc, SkCanvas* canvas,
Mike Klein9707e902019-02-07 16:18:22 -0500225 SkString* errorMsg) override;
Chris Dalton3a778372019-02-07 15:23:36 -0700226
227 const SkString fName;
228 const SkISize fSize;
229 const DrawProc fDrawProc;
230 };
reed@android.com00dae862009-06-10 15:38:48 +0000231}
232
Mike Kleinc9eace82018-10-31 10:49:38 -0400233void MarkGMGood(SkCanvas*, SkScalar x, SkScalar y);
234void MarkGMBad (SkCanvas*, SkScalar x, SkScalar y);
235
reed@android.com00dae862009-06-10 15:38:48 +0000236#endif