Flutter Engine
The Flutter Engine
aaxfermodes.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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"
12#include "include/core/SkFont.h"
16#include "include/core/SkRect.h"
18#include "include/core/SkSize.h"
23#include "tools/ToolUtils.h"
25
26constexpr int kShapeSize = 22;
27constexpr int kShapeSpacing = 36;
28constexpr int kShapeTypeSpacing = 4 * kShapeSpacing / 3;
29constexpr int kPaintSpacing = 4 * kShapeTypeSpacing;
30constexpr int kLabelSpacing = 3 * kShapeSize;
31constexpr int kMargin = kShapeSpacing / 2;
33constexpr int kTitleSpacing = 3 * kShapeSpacing / 4;
34constexpr int kSubtitleSpacing = 5 * kShapeSpacing / 8;
35
36constexpr SkColor kBGColor = 0xc8d2b887;
37
38constexpr SkColor kShapeColors[2] = {
39 0x82ff0080, // input color unknown
40 0xff00ffff, // input color opaque
41};
42
43enum Shape {
48
50};
51
52/**
53 * Verifies AA works properly on all Xfermodes, including arithmetic, with both opaque and unknown
54 * src colors.
55 */
56class AAXfermodesGM : public skiagm::GM {
57public:
59
60protected:
65 };
66
67 SkString getName() const override { return SkString("aaxfermodes"); }
68
69 SkISize getISize() override {
74 }
75
76 void onOnceBeforeDraw() override {
78 fLabelFont.setSize(5 * kShapeSize/8);
79 fLabelFont.setSubpixel(true);
80
81 constexpr SkScalar radius = -1.4f * kShapeSize/2;
82 SkPoint pts[4] = {
83 {-radius, 0},
84 {0, -1.33f * radius},
85 {radius, 0},
86 {0, 1.33f * radius}
87 };
88 fOval = SkPathBuilder().moveTo(pts[0])
89 .quadTo(pts[1], pts[2])
90 .quadTo(pts[3], pts[0])
91 .detach();
92
93 fConcave = SkPathBuilder().moveTo(-radius, 0)
94 .quadTo(0, 0, 0, -radius)
95 .quadTo(0, 0, radius, 0)
96 .quadTo(0, 0, 0, radius)
97 .quadTo(0, 0, -radius, 0)
98 .close()
99 .detach();
100 }
101
102 void draw_pass(SkCanvas* canvas, DrawingPass drawingPass) {
104 { -kShapeSize*11/16, -kShapeSize*11/16, kShapeSize*11/16, kShapeSize*11/16 };
105
106 canvas->save();
107 if (kCheckerboard_Pass == drawingPass) {
108 canvas->translate(kMargin, kMargin);
109 }
110 canvas->translate(0, kTitleSpacing);
111
112 for (size_t xfermodeSet = 0; xfermodeSet < 2; xfermodeSet++) {
113 size_t firstMode = ((size_t)SkBlendMode::kLastCoeffMode + 1) * xfermodeSet;
114 canvas->save();
115
116 if (kShape_Pass == drawingPass) {
117 SkTextUtils::DrawString(canvas, "Src Unknown",
119 kSubtitleSpacing / 2 + fLabelFont.getSize() / 3, fLabelFont, SkPaint(),
121 SkTextUtils::DrawString(canvas, "Src Opaque",
123 kPaintSpacing, kSubtitleSpacing / 2 + fLabelFont.getSize() / 3,
124 fLabelFont, SkPaint(), SkTextUtils::kCenter_Align);
125 }
126
128
129 for (size_t m = 0; m <= (size_t)SkBlendMode::kLastCoeffMode; m++) {
130 if (firstMode + m > (size_t)SkBlendMode::kLastMode) {
131 break;
132 }
133 SkBlendMode mode = static_cast<SkBlendMode>(firstMode + m);
134 canvas->save();
135
136 if (kShape_Pass == drawingPass) {
137 this->drawModeName(canvas, mode);
138 }
139 canvas->translate(kLabelSpacing + kShapeSpacing/2, 0);
140
141 for (size_t colorIdx = 0; colorIdx < std::size(kShapeColors); colorIdx++) {
143 this->setupShapePaint(canvas, kShapeColors[colorIdx], mode, &paint);
144 SkASSERT(colorIdx == 0 || 255 == paint.getAlpha());
145 canvas->save();
146
147 for (size_t shapeIdx = 0; shapeIdx <= kLast_Shape; shapeIdx++) {
148 if (kShape_Pass != drawingPass) {
149 canvas->save();
150 canvas->clipRect(clipRect);
151 if (kCheckerboard_Pass == drawingPass) {
152 ToolUtils::draw_checkerboard(canvas, 0xffffffff, 0xffc6c3c6, 10);
153 } else {
154 SkASSERT(kBackground_Pass == drawingPass);
156 }
157 canvas->restore();
158 } else {
159 this->drawShape(canvas, static_cast<Shape>(shapeIdx), paint, mode);
160 }
161 canvas->translate(kShapeTypeSpacing, 0);
162 }
163
164 canvas->restore();
165 canvas->translate(kPaintSpacing, 0);
166 }
167
168 canvas->restore();
169 canvas->translate(0, kShapeSpacing);
170 }
171
172 canvas->restore();
174 }
175
176 canvas->restore();
177 }
178
179 void onDraw(SkCanvas* canvas) override {
181 canvas->saveLayer(nullptr, nullptr);
182
183 canvas->translate(kMargin, kMargin);
185
186 SkFont titleFont(fLabelFont);
187 titleFont.setSize(9 * titleFont.getSize() / 8);
188 titleFont.setEmbolden(true);
189 SkTextUtils::DrawString(canvas, "Porter Duff",
191 kTitleSpacing / 2 + titleFont.getSize() / 3, titleFont, SkPaint(),
193 SkTextUtils::DrawString(canvas, "Advanced",
195 kTitleSpacing / 2 + titleFont.getSize() / 3, titleFont, SkPaint(),
197
198 draw_pass(canvas, kShape_Pass);
199 canvas->restore();
200 }
201
203 const char* modeName = SkBlendMode_Name(mode);
204 SkTextUtils::DrawString(canvas, modeName, kLabelSpacing - kShapeSize / 4,
205 fLabelFont.getSize() / 4, fLabelFont, SkPaint(),
207 }
208
210 paint->setColor(color);
211
212 if (mode == SkBlendMode::kPlus) {
213 // Check for overflow, otherwise we might get confusing AA artifacts.
218
219 if (maxSum > 255) {
220 SkPaint dimPaint;
221 dimPaint.setAntiAlias(false);
223 if (255 != paint->getAlpha()) {
224 // Dim the src and dst colors.
225 dimPaint.setARGB(255 * 255 / maxSum, 0, 0, 0);
226 paint->setAlpha(255 * paint->getAlpha() / maxSum);
227 } else {
228 // Just clear the dst, we need to preserve the paint's opacity.
229 dimPaint.setARGB(0, 0, 0, 0);
230 }
231 canvas->drawRect({ -kShapeSpacing/2, -kShapeSpacing/2,
233 dimPaint);
234 }
235 }
236 }
237
238 void drawShape(SkCanvas* canvas, Shape shape, const SkPaint& paint, SkBlendMode mode) {
240 SkPaint shapePaint(paint);
241 shapePaint.setAntiAlias(kSquare_Shape != shape);
242 shapePaint.setBlendMode(mode);
243
244 switch (shape) {
245 case kSquare_Shape:
246 canvas->drawRect({ -kShapeSize/2, -kShapeSize/2, kShapeSize/2, kShapeSize/2 },
247 shapePaint);
248 break;
249
250 case kDiamond_Shape:
251 canvas->save();
252 canvas->rotate(45);
253 canvas->drawRect({ -kShapeSize/2, -kShapeSize/2, kShapeSize/2, kShapeSize/2 },
254 shapePaint);
255 canvas->restore();
256 break;
257
258 case kOval_Shape:
259 canvas->save();
260 canvas->rotate(static_cast<SkScalar>((511 * (int)mode + 257) % 360));
261 canvas->drawPath(fOval, shapePaint);
262 canvas->restore();
263 break;
264
265 case kConcave_Shape:
266 canvas->drawPath(fConcave, shapePaint);
267 break;
268
269 default:
270 SK_ABORT("Invalid shape.");
271 }
272 }
273
274private:
275 SkFont fLabelFont;
276 SkPath fOval;
277 SkPath fConcave;
278
279 using INHERITED = skiagm::GM;
280};
281DEF_GM( return new AAXfermodesGM; )
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
SK_API const char * SkBlendMode_Name(SkBlendMode blendMode)
SkBlendMode
Definition: SkBlendMode.h:38
@ kPlus
r = min(s + d, 1)
@ kDstIn
r = d * sa
@ kLastCoeffMode
last porter duff blend mode
@ kLastMode
last valid value
#define SkColorGetR(color)
Definition: SkColor.h:65
#define SkColorGetG(color)
Definition: SkColor.h:69
uint32_t SkColor
Definition: SkColor.h:37
#define SkColorGetA(color)
Definition: SkColor.h:61
#define SkColorGetB(color)
Definition: SkColor.h:73
constexpr SkColor kShapeColors[2]
Definition: aaxfermodes.cpp:38
constexpr int kShapeSpacing
Definition: aaxfermodes.cpp:27
constexpr int kXfermodeTypeSpacing
Definition: aaxfermodes.cpp:32
Shape
Definition: aaxfermodes.cpp:43
@ kSquare_Shape
Definition: aaxfermodes.cpp:44
@ kOval_Shape
Definition: aaxfermodes.cpp:46
@ kConcave_Shape
Definition: aaxfermodes.cpp:47
@ kLast_Shape
Definition: aaxfermodes.cpp:49
@ kDiamond_Shape
Definition: aaxfermodes.cpp:45
constexpr int kTitleSpacing
Definition: aaxfermodes.cpp:33
constexpr int kShapeSize
Definition: aaxfermodes.cpp:26
constexpr int kSubtitleSpacing
Definition: aaxfermodes.cpp:34
constexpr int kShapeTypeSpacing
Definition: aaxfermodes.cpp:28
constexpr int kPaintSpacing
Definition: aaxfermodes.cpp:29
constexpr int kLabelSpacing
Definition: aaxfermodes.cpp:30
constexpr int kMargin
Definition: aaxfermodes.cpp:31
constexpr SkColor kBGColor
Definition: aaxfermodes.cpp:36
void onDraw(SkCanvas *canvas) override
void draw_pass(SkCanvas *canvas, DrawingPass drawingPass)
SkISize getISize() override
Definition: aaxfermodes.cpp:69
void onOnceBeforeDraw() override
Definition: aaxfermodes.cpp:76
void drawShape(SkCanvas *canvas, Shape shape, const SkPaint &paint, SkBlendMode mode)
SkString getName() const override
Definition: aaxfermodes.cpp:67
void setupShapePaint(SkCanvas *canvas, SkColor color, SkBlendMode mode, SkPaint *paint)
void drawModeName(SkCanvas *canvas, SkBlendMode mode)
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 clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
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
void rotate(SkScalar degrees)
Definition: SkCanvas.cpp:1300
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
Definition: SkFont.h:35
void setSubpixel(bool subpixel)
Definition: SkFont.cpp:109
void setTypeface(sk_sp< SkTypeface > tf)
Definition: SkFont.cpp:90
SkScalar getSize() const
Definition: SkFont.h:217
void setSize(SkScalar textSize)
Definition: SkFont.cpp:129
void setEmbolden(bool embolden)
Definition: SkFont.cpp:115
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkPaint.cpp:134
void setBlendMode(SkBlendMode mode)
Definition: SkPaint.cpp:151
SkPathBuilder & close()
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & quadTo(SkPoint pt1, SkPoint pt2)
Definition: SkPath.h:59
static void DrawString(SkCanvas *canvas, const char text[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint, Align align=kLeft_Align)
Definition: SkTextUtils.h:34
Definition: gm.h:110
const Paint & paint
Definition: color_source.cc:38
DlColor color
float SkScalar
Definition: extension.cpp:12
#define DEF_GM(CODE)
Definition: gm.h:40
static float max(float r, float g, float b)
Definition: hsl.cpp:49
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
sk_sp< SkTypeface > DefaultPortableTypeface()
void draw_checkerboard(SkCanvas *canvas, SkColor c1, SkColor c2, int size)
Definition: ToolUtils.cpp:174
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
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20