Flutter Engine
The Flutter Engine
gm.cpp
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#include "gm/gm.h"
9
13#include "include/core/SkFont.h"
17#include "include/core/SkRect.h"
19#include "include/core/SkShader.h" // IWYU pragma: keep
22#include "tools/ToolUtils.h"
24
25#if defined(SK_GANESH)
27#endif
28
29#include <cstdarg>
30#include <cstdint>
31
32using namespace skiagm;
33
34static void draw_failure_message(SkCanvas* canvas, const char format[], ...) SK_PRINTF_LIKE(2, 3);
35
36static void draw_failure_message(SkCanvas* canvas, const char format[], ...) {
37 SkString failureMsg;
38
39 va_list argp;
40 va_start(argp, format);
41 failureMsg.appendVAList(format, argp);
42 va_end(argp);
43
44 constexpr SkScalar kOffset = 5.0f;
45 canvas->drawColor(SkColorSetRGB(200,0,0));
48 font.measureText(failureMsg.c_str(), failureMsg.size(), SkTextEncoding::kUTF8, &bounds);
49 SkPaint textPaint(SkColors::kWhite);
50 canvas->drawString(failureMsg, kOffset, bounds.height() + kOffset, font, textPaint);
51}
52
53static void draw_gpu_only_message(SkCanvas* canvas) {
54 SkBitmap bmp;
55 bmp.allocN32Pixels(128, 64);
56 SkCanvas bmpCanvas(bmp);
57 bmpCanvas.drawColor(SK_ColorWHITE);
60 bmpCanvas.drawString("GPU Only", 20, 40, font, paint);
61 SkMatrix localM;
62 localM.setRotate(35.f);
63 localM.postTranslate(10.f, 0.f);
67 localM));
68 canvas->drawPaint(paint);
69}
70
71static void handle_gm_failure(SkCanvas* canvas, DrawResult result, const SkString& errorMsg) {
73 draw_failure_message(canvas, "DRAW FAILED: %s", errorMsg.c_str());
74 } else if (SkString(GM::kErrorMsg_DrawSkippedGpuOnly) == errorMsg) {
76 } else {
77 draw_failure_message(canvas, "DRAW SKIPPED: %s", errorMsg.c_str());
78 }
79}
80
82 fMode = kGM_Mode;
83 fBGColor = bgColor;
84}
85
87
89 SkString* errorMsg,
90 GraphiteTestContext* graphiteTestContext) {
91 TRACE_EVENT1("GM", TRACE_FUNC, "name", TRACE_STR_COPY(this->getName().c_str()));
92 if (!fGpuSetup) {
93 // When drawn in viewer, gpuSetup will be called multiple times with the same
94 // GrContext or graphite::Context.
95 fGpuSetup = true;
96 fGpuSetupResult = this->onGpuSetup(canvas, errorMsg, graphiteTestContext);
97 }
98 if (fGpuSetupResult == DrawResult::kOk) {
99 fGraphiteTestContext = graphiteTestContext;
100 } else {
101 handle_gm_failure(canvas, fGpuSetupResult, *errorMsg);
102 }
103
104 return fGpuSetupResult;
105}
106
108 this->onGpuTeardown();
109
110 // After 'gpuTeardown' a GM can be reused with a different GrContext or graphite::Context. Reset
111 // the flag so 'onGpuSetup' will be called.
112 fGpuSetup = false;
113 fGraphiteTestContext = nullptr;
114}
115
117 TRACE_EVENT1("GM", TRACE_FUNC, "name", TRACE_STR_COPY(this->getName().c_str()));
118 this->drawBackground(canvas);
119 return this->drawContent(canvas, errorMsg);
120}
121
124 this->onceBeforeDraw();
125 SkAutoCanvasRestore acr(canvas, true);
126 DrawResult drawResult = this->onDraw(canvas, errorMsg);
127 if (DrawResult::kOk != drawResult) {
128 handle_gm_failure(canvas, drawResult, *errorMsg);
129 }
130 return drawResult;
131}
132
135 this->onceBeforeDraw();
136 canvas->drawColor(fBGColor, SkBlendMode::kSrc);
137}
138
140 this->onDraw(canvas);
141 return DrawResult::kOk;
142}
143void GM::onDraw(SkCanvas*) { SK_ABORT("Not implemented."); }
144
145SkISize SimpleGM::getISize() { return fSize; }
146SkString SimpleGM::getName() const { return fName; }
147DrawResult SimpleGM::onDraw(SkCanvas* canvas, SkString* errorMsg) {
148 return fDrawProc(canvas, errorMsg);
149}
150
151#if defined(SK_GANESH)
152SkISize SimpleGpuGM::getISize() { return fSize; }
153SkString SimpleGpuGM::getName() const { return fName; }
154DrawResult SimpleGpuGM::onDraw(GrRecordingContext* rContext, SkCanvas* canvas, SkString* errorMsg) {
155 return fDrawProc(rContext, canvas, errorMsg);
156}
157#endif
158
160 fBGColor = color;
161}
162
163bool GM::animate(double nanos) { return this->onAnimate(nanos); }
164
165bool GM::runAsBench() const { return false; }
166
168
169bool GM::onAnimate(double /*nanos*/) { return false; }
170
171bool GM::onChar(SkUnichar uni) { return false; }
172
173bool GM::onGetControls(SkMetaData*) { return false; }
174
176
177/////////////////////////////////////////////////////////////////////////////////////////////
178
180 canvas->drawRect(SkRect::Make(this->getISize()), SkPaint(SkColor4f::FromColor(color)));
181}
182
183// need to explicitly declare this, or we get some weird infinite loop llist
184template GMRegistry* GMRegistry::gHead;
185
186#if defined(SK_GANESH)
187DrawResult GpuGM::onDraw(GrRecordingContext* rContext, SkCanvas* canvas, SkString* errorMsg) {
188 this->onDraw(rContext, canvas);
189 return DrawResult::kOk;
190}
191void GpuGM::onDraw(GrRecordingContext*, SkCanvas*) {
192 SK_ABORT("Not implemented.");
193}
194
195DrawResult GpuGM::onDraw(SkCanvas* canvas, SkString* errorMsg) {
196
197 auto rContext = canvas->recordingContext();
198 if (!rContext) {
199 *errorMsg = kErrorMsg_DrawSkippedGpuOnly;
200 return DrawResult::kSkip;
201 }
202 if (rContext->abandoned()) {
203 *errorMsg = "GrContext abandoned.";
204 return DrawResult::kSkip;
205 }
206 return this->onDraw(rContext, canvas, errorMsg);
207}
208#endif
209
210template <typename Fn>
211static void mark(SkCanvas* canvas, SkScalar x, SkScalar y, Fn&& fn) {
212 SkPaint alpha;
213 alpha.setAlpha(0x50);
214 canvas->saveLayer(nullptr, &alpha);
215 canvas->translate(x,y);
216 canvas->scale(2,2);
217 fn();
218 canvas->restore();
219}
220
222 mark(canvas, x,y, [&]{
223 // A green circle.
224 canvas->drawCircle(0, 0, 12, SkPaint(SkColor4f::FromColor(SkColorSetRGB(27, 158, 119))));
225
226 // Cut out a check mark.
228 paint.setBlendMode(SkBlendMode::kSrc);
229 paint.setStrokeWidth(2);
231 canvas->drawLine(-6, 0,
232 -1, 5, paint);
233 canvas->drawLine(-1, +5,
234 +7, -5, paint);
235 });
236}
237
239 mark(canvas, x,y, [&] {
240 // A red circle.
241 canvas->drawCircle(0,0, 12, SkPaint(SkColor4f::FromColor(SkColorSetRGB(231, 41, 138))));
242
243 // Cut out an 'X'.
245 paint.setBlendMode(SkBlendMode::kSrc);
246 paint.setStrokeWidth(2);
248 canvas->drawLine(-5,-5,
249 +5,+5, paint);
250 canvas->drawLine(+5,-5,
251 -5,+5, paint);
252 });
253}
254
255namespace skiagm {
257 // The skiagm::GMRegistry class is a subclass of sk_tools::Registry. Instances of
258 // sk_tools::Registry form a linked list (there is one such list for each subclass), where each
259 // instance holds a value and a pointer to the next sk_tools::Registry instance. The head of
260 // this linked list is stored in a global variable. The sk_tools::Registry constructor
261 // automatically pushes a new instance to the head of said linked list. Therefore, in order to
262 // register a value in the GM registry, it suffices to just instantiate skiagm::GMRegistry with
263 // the value we wish to register.
264 new skiagm::GMRegistry([=]() { return std::unique_ptr<skiagm::GM>(gm); });
265}
266} // namespace skiagm
static const SkColor bgColor
Definition: BlurTest.cpp:59
static constexpr uint64_t kOffset
Definition: DrawPass.cpp:53
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SK_PRINTF_LIKE(A, B)
Definition: SkAttributes.h:52
uint32_t SkColor
Definition: SkColor.h:37
#define SkColorSetRGB(r, g, b)
Definition: SkColor.h:57
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
@ kUTF8
uses bytes to represent UTF-8 or ASCII
#define TRACE_STR_COPY(str)
Definition: SkTraceEvent.h:63
#define TRACE_FUNC
Definition: SkTraceEvent.h:30
int32_t SkUnichar
Definition: SkTypes.h:175
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkBitmap.cpp:669
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition: SkBitmap.cpp:232
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition: SkCanvas.cpp:496
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
Definition: SkFont.h:35
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:452
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
void setAlpha(U8CPU a)
Definition: SkPaint.h:279
void void void void appendVAList(const char format[], va_list) SK_PRINTF_LIKE(2
Definition: SkString.cpp:557
size_t size() const
Definition: SkString.h:131
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
DrawResult drawContent(SkCanvas *canvas)
Definition: gm.h:147
virtual bool onChar(SkUnichar)
Definition: gm.cpp:171
virtual SkISize getISize()=0
virtual void onSetControls(const SkMetaData &)
Definition: gm.cpp:175
virtual void onOnceBeforeDraw()
Definition: gm.cpp:167
void drawSizeBounds(SkCanvas *, SkColor)
Definition: gm.cpp:179
GraphiteTestContext * graphiteTestContext() const
Definition: gm.h:228
@ kGM_Mode
Definition: gm.h:119
virtual bool runAsBench() const
Definition: gm.cpp:165
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 onAnimate(double)
Definition: gm.cpp:169
DrawResult draw(SkCanvas *canvas)
Definition: gm.h:140
virtual bool onGetControls(SkMetaData *)
Definition: gm.cpp:173
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
SkISize getISize() override
Definition: gm.cpp:145
SkString getName() const override
Definition: gm.cpp:146
const Paint & paint
Definition: color_source.cc:38
DlColor color
float SkScalar
Definition: extension.cpp:12
GAsyncResult * result
uint32_t uint32_t * format
void MarkGMGood(SkCanvas *canvas, SkScalar x, SkScalar y)
Definition: gm.cpp:221
static void handle_gm_failure(SkCanvas *canvas, DrawResult result, const SkString &errorMsg)
Definition: gm.cpp:71
static void draw_failure_message(SkCanvas *canvas, const char format[],...) SK_PRINTF_LIKE(2
Definition: gm.cpp:36
void MarkGMBad(SkCanvas *canvas, SkScalar x, SkScalar y)
Definition: gm.cpp:238
static void draw_gpu_only_message(SkCanvas *canvas)
Definition: gm.cpp:53
static void mark(SkCanvas *canvas, SkScalar x, SkScalar y, Fn &&fn)
Definition: gm.cpp:211
double y
double x
constexpr SkColor4f kRed
Definition: SkColor.h:440
constexpr SkColor4f kWhite
Definition: SkColor.h:439
constexpr SkColor4f kTransparent
Definition: SkColor.h:434
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< SkTypeface > DefaultPortableTypeface()
SkFont DefaultPortableFont()
va_start(args, format)
va_end(args)
font
Font Metadata and Metrics.
const char * fName
void Register(skiagm::GM *gm)
Definition: gm.cpp:256
sk_tools::Registry< GMFactory > GMRegistry
Definition: gm.h:240
DrawResult
Definition: gm.h:104
Definition: SkSize.h:16
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:141