Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
gm.h
Go to the documentation of this file.
1/*
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 */
7
8#ifndef skiagm_DEFINED
9#define skiagm_DEFINED
10
13#include "include/core/SkSize.h"
17#include "tools/Registry.h"
18
19#include <functional>
20#include <map>
21#include <memory>
22
24class SkCanvas;
25class SkMetaData;
26struct GrContextOptions;
27
28namespace skiagm::verifiers {
29class VerifierList;
30}
31
32namespace skgpu::graphite {
33struct ContextOptions;
34}
35
38}
39
40#define DEF_GM(CODE) \
41 static skiagm::GMRegistry SK_MACRO_APPEND_COUNTER(REG_)( \
42 []() { return std::unique_ptr<skiagm::GM>([]() { CODE; }()); });
43
44// A Simple GM is a rendering test that does not store state between rendering calls or make use of
45// the onOnceBeforeDraw() virtual; it consists of:
46// * A name.
47// * Prefered width and height.
48// * Optionally, a background color (default is white).
49// * A standalone function pointer that implements its onDraw method.
50#define DEF_SIMPLE_GM(NAME, CANVAS, W, H) \
51 DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, SK_ColorWHITE, SkString(#NAME))
52#define DEF_SIMPLE_GM_BG(NAME, CANVAS, W, H, BGCOLOR) \
53 DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, BGCOLOR, SkString(#NAME))
54#define DEF_SIMPLE_GM_BG_NAME(NAME, CANVAS, W, H, BGCOLOR, NAME_STR) \
55 static void SK_MACRO_CONCAT(NAME,_GM_inner)(SkCanvas*); \
56 DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS,, W, H, BGCOLOR, NAME_STR) { \
57 SK_MACRO_CONCAT(NAME,_GM_inner)(CANVAS); \
58 return skiagm::DrawResult::kOk; \
59 } \
60 void SK_MACRO_CONCAT(NAME,_GM_inner)(SkCanvas* CANVAS)
61
62#define DEF_SIMPLE_GM_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H) \
63 DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, SK_ColorWHITE, SkString(#NAME))
64#define DEF_SIMPLE_GM_BG_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, BGCOLOR) \
65 DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, BGCOLOR, SkString(#NAME))
66#define DEF_SIMPLE_GM_BG_NAME_CAN_FAIL(NAME, CANVAS, ERR_MSG, W, H, BGCOLOR, NAME_STR) \
67 static skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)(SkCanvas*, SkString*); \
68 DEF_GM(return new skiagm::SimpleGM(BGCOLOR, NAME_STR, {W,H}, SK_MACRO_CONCAT(NAME,_GM));) \
69 skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)(SkCanvas* CANVAS, SkString* ERR_MSG)
70
71// Declares a function that dynamically registers GMs (e.g. based on some command-line flag). See
72// the GMRegistererFnRegistry definition below for additional context.
73#define DEF_GM_REGISTERER_FN(FN) \
74 static skiagm::GMRegistererFnRegistry SK_MACRO_APPEND_COUNTER(REG_)(FN)
75
76#if defined(SK_GANESH)
77// A Simple GpuGM makes direct GPU calls. Its onDraw hook that includes GPU objects as params, and
78// is only invoked on GPU configs. Non-GPU configs automatically draw a GPU-only message and abort.
79#define DEF_SIMPLE_GPU_GM(NAME, GR_CONTEXT, CANVAS, W, H) \
80 DEF_SIMPLE_GPU_GM_BG(NAME, GR_CONTEXT, CANVAS, W, H, SK_ColorWHITE)
81
82#define DEF_SIMPLE_GPU_GM_BG(NAME, GR_CONTEXT, CANVAS, W, H, BGCOLOR) \
83 static void SK_MACRO_CONCAT(NAME,_GM_inner)(GrRecordingContext*, SkCanvas*); \
84 DEF_SIMPLE_GPU_GM_BG_CAN_FAIL(NAME, GR_CONTEXT, CANVAS, /* ERR_MSG */, W, H, BGCOLOR) { \
85 SK_MACRO_CONCAT(NAME,_GM_inner)(GR_CONTEXT, CANVAS); \
86 return skiagm::DrawResult::kOk; \
87 } \
88 void SK_MACRO_CONCAT(NAME,_GM_inner)(GrRecordingContext* GR_CONTEXT, SkCanvas* CANVAS)
89
90#define DEF_SIMPLE_GPU_GM_CAN_FAIL(NAME, GR_CONTEXT, CANVAS, ERR_MSG, W, H) \
91 DEF_SIMPLE_GPU_GM_BG_CAN_FAIL(NAME, GR_CONTEXT, CANVAS, ERR_MSG, W, H, SK_ColorWHITE)
92
93#define DEF_SIMPLE_GPU_GM_BG_CAN_FAIL(NAME, GR_CONTEXT, CANVAS, ERR_MSG, W, H, BGCOLOR) \
94 static skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)( \
95 GrRecordingContext*, SkCanvas*, SkString*); \
96 DEF_GM(return new skiagm::SimpleGpuGM(BGCOLOR, SkString(#NAME), {W,H}, \
97 SK_MACRO_CONCAT(NAME,_GM));) \
98 skiagm::DrawResult SK_MACRO_CONCAT(NAME,_GM)( \
99 GrRecordingContext* GR_CONTEXT, SkCanvas* CANVAS, SkString* ERR_MSG)
100#endif
101
102namespace skiagm {
103
104 enum class DrawResult {
105 kOk, // Test drew successfully.
106 kFail, // Test failed to draw.
107 kSkip // Test is not applicable in this context and should be skipped.
108 };
109
110 class GM {
111 public:
114
115 GM(SkColor backgroundColor = SK_ColorWHITE);
116 virtual ~GM();
117
123
124 void setMode(Mode mode) { fMode = mode; }
125 Mode getMode() const { return fMode; }
126
127 inline static constexpr char kErrorMsg_DrawSkippedGpuOnly[] =
128 "This test is for GPU configs only.";
129
131 void gpuTeardown();
132
134 if (!fHaveCalledOnceBeforeDraw) {
135 fHaveCalledOnceBeforeDraw = true;
136 this->onOnceBeforeDraw();
137 }
138 }
139
141 SkString errorMsg;
142 return this->draw(canvas, &errorMsg);
143 }
144 DrawResult draw(SkCanvas*, SkString* errorMsg);
145
148 SkString errorMsg;
149 return this->drawContent(canvas, &errorMsg);
150 }
152
153 virtual SkISize getISize() = 0;
154
155 virtual SkString getName() const = 0;
156
157 virtual bool runAsBench() const;
158
160 return SkIntToScalar(this->getISize().width());
161 }
163 return SkIntToScalar(this->getISize().height());
164 }
165
166 SkColor getBGColor() const { return fBGColor; }
167 void setBGColor(SkColor);
168
169 // helper: fill a rect in the specified color based on the GM's getISize bounds.
171
172 bool animate(double /*nanos*/);
173 virtual bool onChar(SkUnichar);
174
175 bool getControls(SkMetaData* controls) { return this->onGetControls(controls); }
176 void setControls(const SkMetaData& controls) { this->onSetControls(controls); }
177
180
181 // Convenience method to skip Bazel-only GMs from DM.
182 //
183 // As of Q3 2023, lovisolo@ is experimenting with reimplementing some DM behaviors as
184 // smaller, independent Bazel targets. For example, file
185 // //tools/testrunners/gm/BazelGMTestRunner.cpp provides a main function that can run GMs.
186 // With this file, one can define multiple small Bazel tests to run groups of related GMs
187 // with Bazel. However, GMs are only one kind of "source" supported by DM (see class
188 // GMSrc). DM supports other kinds of sources as well, such as codecs (CodecSrc class) and
189 // image generators (ImageGenSrc class). One possible strategy to support these sources in
190 // our Bazel build is to turn them into GMs. For example, instead of using the CodecSrc
191 // class from Bazel, we could have a GM subclass that takes an image as an input, decodes
192 // it using a codec, and draws in on a canvas. Given that this overlaps with existing DM
193 // functionality, we would mark such GMs as Bazel-only.
194 //
195 // Another possibility is to slowly replace all existing DM source types with just GMs.
196 // This would lead to a simpler DM architecture where there is only one source type and
197 // multiple sinks, as opposed to the current design with multiple sources and sinks.
198 // Furthermore, it would simplify the migration to Bazel because it would allow us to
199 // leverage existing work to run GMs with Bazel.
200 //
201 // TODO(lovisolo): Delete once it's no longer needed.
202 virtual bool isBazelOnly() const { return false; }
203
204 // Ignored by DM. Returns the set of Gold key/value pairs specific to this GM, such as the
205 // GM name and corpus. GMs may define additional keys. For example, codec GMs define keys
206 // for the parameters utilized to initialize the codec.
207 virtual std::map<std::string, std::string> getGoldKeys() const {
208 return std::map<std::string, std::string>{
209 {"name", getName().c_str()},
210 {"source_type", "gm"},
211 };
212 }
213
214 protected:
215 // onGpuSetup is called once before any other processing with a direct context.
219 virtual void onGpuTeardown() {}
220 virtual void onOnceBeforeDraw();
221 virtual DrawResult onDraw(SkCanvas*, SkString* errorMsg);
222 virtual void onDraw(SkCanvas*);
223
224 virtual bool onAnimate(double /*nanos*/);
225 virtual bool onGetControls(SkMetaData*);
226 virtual void onSetControls(const SkMetaData&);
227
228 GraphiteTestContext* graphiteTestContext() const { return fGraphiteTestContext; }
229
230 private:
231 Mode fMode;
232 SkColor fBGColor;
233 bool fHaveCalledOnceBeforeDraw = false;
234 bool fGpuSetup = false;
235 DrawResult fGpuSetupResult = DrawResult::kOk;
236 GraphiteTestContext* fGraphiteTestContext;
237 };
238
239 using GMFactory = std::function<std::unique_ptr<skiagm::GM>()>;
241
242 // Adds a GM to the GMRegistry.
243 void Register(skiagm::GM* gm);
244
245 // Registry of functions that dynamically register GMs. Useful for GMs that are unknown at
246 // compile time, such as those that are created from images in a directory (see e.g.
247 // //gm/png_codec.cpp).
248 //
249 // A GMRegistererFn may call skiagm::Register() zero or more times to register GMs as needed.
250 // It should return the empty string on success, or a human-friendly message in the case of
251 // errors.
252 //
253 // Only used by //tools/testrunners/gm/BazelGMTestRunner.cpp for now.
254 using GMRegistererFn = std::function<std::string()>;
256
257#if defined(SK_GANESH)
258 // A GpuGM replaces the onDraw method with one that also accepts GPU objects alongside the
259 // SkCanvas. Its onDraw is only invoked on GPU configs; on non-GPU configs it will automatically
260 // draw a GPU-only message and abort.
261 class GpuGM : public GM {
262 public:
263 GpuGM(SkColor backgroundColor = SK_ColorWHITE) : GM(backgroundColor) {}
264
265 private:
266 using GM::onDraw;
267 DrawResult onDraw(SkCanvas*, SkString* errorMsg) final;
268
269 virtual DrawResult onDraw(GrRecordingContext*, SkCanvas*, SkString* errorMsg);
270 virtual void onDraw(GrRecordingContext*, SkCanvas*);
271 };
272#endif
273
274 // SimpleGM is intended for basic GMs that can define their entire implementation inside a
275 // single "draw" function pointer.
276 class SimpleGM : public GM {
277 public:
279
280 SimpleGM(SkColor bgColor, const SkString& name, const SkISize& size, DrawProc drawProc)
281 : GM(bgColor), fName(name), fSize(size), fDrawProc(drawProc) {}
282
283 SkString getName() const override;
284 SkISize getISize() override;
285
286 private:
287 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override;
288
289 const SkString fName;
290 const SkISize fSize;
291 const DrawProc fDrawProc;
292 };
293
294#if defined(SK_GANESH)
295 class SimpleGpuGM : public GpuGM {
296 public:
297 using DrawProc = DrawResult (*)(GrRecordingContext*, SkCanvas*, SkString* errorMsg);
298
299 SimpleGpuGM(SkColor bgColor, const SkString& name, const SkISize& size, DrawProc drawProc)
300 : GpuGM(bgColor), fName(name), fSize(size), fDrawProc(drawProc) {}
301
302 SkString getName() const override;
303 SkISize getISize() override;
304
305 private:
306 DrawResult onDraw(GrRecordingContext*, SkCanvas*, SkString* errorMsg) override;
307
308 const SkString fName;
309 const SkISize fSize;
310 const DrawProc fDrawProc;
311 };
312#endif
313} // namespace skiagm
314
317
318#endif
const char *(* DrawProc)(const BezierRec *, int)
static const SkColor bgColor
Definition BlurTest.cpp:59
const char * fName
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
#define SkIntToScalar(x)
Definition SkScalar.h:57
int32_t SkUnichar
Definition SkTypes.h:175
const char * c_str() const
Definition SkString.h:133
bool animate(double)
Definition gm.cpp:163
DrawResult gpuSetup(SkCanvas *, SkString *errorMsg, GraphiteTestContext *=nullptr)
Definition gm.cpp:88
virtual void onGpuTeardown()
Definition gm.h:219
DrawResult drawContent(SkCanvas *canvas)
Definition gm.h:147
static constexpr char kErrorMsg_DrawSkippedGpuOnly[]
Definition gm.h:127
virtual bool onChar(SkUnichar)
Definition gm.cpp:171
virtual SkISize getISize()=0
virtual std::map< std::string, std::string > getGoldKeys() const
Definition gm.h:207
virtual void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions *) const
Definition gm.h:179
virtual void onSetControls(const SkMetaData &)
Definition gm.cpp:175
virtual void onOnceBeforeDraw()
Definition gm.cpp:167
void drawSizeBounds(SkCanvas *, SkColor)
Definition gm.cpp:179
SkScalar width()
Definition gm.h:159
GraphiteTestContext * graphiteTestContext() const
Definition gm.h:228
@ kBench_Mode
Definition gm.h:121
@ kGM_Mode
Definition gm.h:119
@ kSample_Mode
Definition gm.h:120
SkScalar height()
Definition gm.h:162
bool getControls(SkMetaData *controls)
Definition gm.h:175
SkColor getBGColor() const
Definition gm.h:166
void setMode(Mode mode)
Definition gm.h:124
Mode getMode() const
Definition gm.h:125
void setControls(const SkMetaData &controls)
Definition gm.h:176
virtual bool runAsBench() const
Definition gm.cpp:165
skiagm::DrawResult DrawResult
Definition gm.h:112
virtual DrawResult onGpuSetup(SkCanvas *, SkString *, GraphiteTestContext *)
Definition gm.h:216
void setBGColor(SkColor)
Definition gm.cpp:159
void gpuTeardown()
Definition gm.cpp:107
virtual SkString getName() const =0
virtual bool isBazelOnly() const
Definition gm.h:202
skiatest::graphite::GraphiteTestContext GraphiteTestContext
Definition gm.h:113
virtual bool onAnimate(double)
Definition gm.cpp:169
DrawResult draw(SkCanvas *canvas)
Definition gm.h:140
virtual bool onGetControls(SkMetaData *)
Definition gm.cpp:173
virtual void modifyGrContextOptions(GrContextOptions *)
Definition gm.h:178
void onceBeforeDraw()
Definition gm.h:133
virtual DrawResult onDraw(SkCanvas *, SkString *errorMsg)
Definition gm.cpp:139
void drawBackground(SkCanvas *)
Definition gm.cpp:133
virtual ~GM()
Definition gm.cpp:86
SimpleGM(SkColor bgColor, const SkString &name, const SkISize &size, DrawProc drawProc)
Definition gm.h:280
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
Definition gm.cpp:147
SkISize getISize() override
Definition gm.cpp:145
DrawResult(*)(SkCanvas *, SkString *) DrawProc
Definition gm.h:278
SkString getName() const override
Definition gm.cpp:146
float SkScalar
Definition extension.cpp:12
const char * name
Definition fuchsia.cc:50
void MarkGMBad(SkCanvas *, SkScalar x, SkScalar y)
Definition gm.cpp:238
void MarkGMGood(SkCanvas *, SkScalar x, SkScalar y)
Definition gm.cpp:221
double y
double x
std::function< std::unique_ptr< skiagm::GM >()> GMFactory
Definition gm.h:239
std::function< std::string()> GMRegistererFn
Definition gm.h:254
void Register(skiagm::GM *gm)
Definition gm.cpp:256
DrawResult
Definition gm.h:104