Flutter Engine
The Flutter Engine
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
118 enum Mode {
122 };
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.
217 return DrawResult::kOk;
218 }
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
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)
Definition: BezierBench.cpp:21
static const SkColor bgColor
Definition: BlurTest.cpp:59
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
Definition: gm.h:110
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
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
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
Mode
Definition: gm.h:118
@ 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
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
Dart_NativeFunction function
Definition: fuchsia.cc:51
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
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
std::function< std::unique_ptr< skiagm::GM >()> GMFactory
Definition: gm.h:239
std::function< std::string()> GMRegistererFn
Definition: gm.h:254
const char * fName
void Register(skiagm::GM *gm)
Definition: gm.cpp:256
DrawResult
Definition: gm.h:104
Definition: SkSize.h:16