Flutter Engine
The Flutter Engine
analytic_gradients.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 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/*
9 * This GM presents a variety of gradients meant to test the correctness of the analytic unrolled
10 * binary gradient colorizer, which can handle arbitrary gradients with 1 to 8 interpolation
11 * intervals. These intervals can be either hardstops or smooth color transitions.
12 *
13 * It produces an image similar to that of GM_hardstop_gradients, but is arranged as follows:
14 *
15 * | Clamp |
16 * |________________|
17 * | M1 M2 M3 M4 |
18 * ___________|________________|
19 * 1 |
20 * 2 |
21 * 3 |
22 * 4 |
23 * 5 |
24 * 6 |
25 * 7 |
26 * 8 |
27 * The M-modes are different ways of interlveaving hardstops with smooth transitions:
28 * - M1 = All smooth transitions
29 * - M2 = All hard stops
30 * - M5 = Alternating smooth then hard
31 * - M6 = Alternating hard then smooth
32 *
33 * Only clamping is tested since this is focused more on within the interpolation region behavior,
34 * compared to overall behavior.
35 */
36
37#include "gm/gm.h"
42#include "include/core/SkRect.h"
46#include "include/core/SkSize.h"
52
53using namespace skia_private;
54
55// All positions must be divided by the target interval count, which will produce the expected
56// normalized position array for that interval number (assuming an appropriate color count is
57// provided).
58const int M1_POSITIONS[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
59const int M2_POSITIONS[] = { 0, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7, 8 };
60const int M3_POSITIONS[] = { 0, 1, 2,2, 3, 4,4, 5, 6,6, 7, 8 };
61const int M4_POSITIONS[] = { 0, 1,1, 2, 3,3, 4, 5,5, 6, 7,7, 8 };
62
63// Color count = index of first occurrence of interval count value in Mx_POSITIONS array.
64const int INT1_COLOR_COUNTS[] = { 2, 2, 2, 2 };
65const int INT2_COLOR_COUNTS[] = { 3, 4, 3, 4 };
66const int INT3_COLOR_COUNTS[] = { 4, 6, 5, 5 };
67const int INT4_COLOR_COUNTS[] = { 5, 8, 6, 7 };
68const int INT5_COLOR_COUNTS[] = { 6, 10, 8, 8 };
69const int INT6_COLOR_COUNTS[] = { 7, 12, 9, 10 };
70const int INT7_COLOR_COUNTS[] = { 8, 14, 11, 11 };
71const int INT8_COLOR_COUNTS[] = { 9, 16, 12, 13 };
72
73// Cycle through defined colors for positions 0 through 8.
74const SkColor COLORS[] = {
84};
85
86const int* INTERVAL_COLOR_COUNTS[] = {
95};
97
98const int* M_POSITIONS[] = {
103};
104
105const int WIDTH = 500;
106const int HEIGHT = 500;
107
108const int NUM_ROWS = 8;
109const int NUM_COLS = 4;
110
113
114const int PAD_WIDTH = 3;
115const int PAD_HEIGHT = 3;
116
117const int RECT_WIDTH = CELL_WIDTH - (2 * PAD_WIDTH);
119
120static void shade_rect(SkCanvas* canvas, sk_sp<SkShader> shader, int cellRow, int cellCol) {
122 paint.setShader(shader);
123
124 canvas->save();
125 canvas->translate(SkIntToScalar(cellCol * CELL_WIDTH + PAD_WIDTH),
127
129 canvas->drawRect(rect, paint);
130 canvas->restore();
131}
132
134public:
136
137 }
138
139protected:
140 SkString getName() const override { return SkString("analytic_gradients"); }
141
142 SkISize getISize() override { return SkISize::Make(1024, 512); }
143
144 void onDraw(SkCanvas* canvas) override {
145 const SkPoint points[2] = { SkPoint::Make(0, 0), SkPoint::Make(RECT_WIDTH, 0.0) };
146
147 for (int cellRow = 0; cellRow < NUM_ROWS; cellRow++) {
148 // Each interval has 4 different color counts, one per mode
149 const int* colorCounts = INTERVAL_COLOR_COUNTS[cellRow]; // Has len = 4
150
151 for (int cellCol = 0; cellCol < NUM_COLS; cellCol++) {
152 // create_gradient_points(cellRow, cellCol, points);
153
154 // Get the color count dependent on interval and mode
155 int colorCount = colorCounts[cellCol];
156 // Get the positions given the mode
157 const int* layout = M_POSITIONS[cellCol];
158
159 // Collect positions and colors specific to the interval+mode normalizing the
160 // position based on the interval count (== cellRow+1)
162 AutoSTMalloc<4, SkScalar> positions(colorCount);
163 int j = 0;
164 for (int i = 0; i < colorCount; i++) {
165 positions[i] = SkIntToScalar(layout[i]) / (cellRow + 1);
166 colors[i] = COLORS[j % COLOR_COUNT];
167 j++;
168 }
169
170 auto shader = SkGradientShader::MakeLinear(
171 points,
172 colors.get(),
173 positions.get(),
174 colorCount,
176 0,
177 nullptr);
178
179 shade_rect(canvas, shader, cellRow, cellCol);
180 }
181 }
182 }
183
184private:
185 using INHERITED = skiagm::GM;
186};
187
static const int points[]
constexpr SkColor SK_ColorYELLOW
Definition: SkColor.h:139
constexpr SkColor SK_ColorLTGRAY
Definition: SkColor.h:118
constexpr SkColor SK_ColorMAGENTA
Definition: SkColor.h:147
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorCYAN
Definition: SkColor.h:143
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorDKGRAY
Definition: SkColor.h:108
#define SkIntToScalar(x)
Definition: SkScalar.h:57
const int M4_POSITIONS[]
const int INT4_COLOR_COUNTS[]
const int RECT_HEIGHT
const int CELL_WIDTH
const int PAD_WIDTH
const int INT3_COLOR_COUNTS[]
const int INT5_COLOR_COUNTS[]
const int INT7_COLOR_COUNTS[]
const int PAD_HEIGHT
const int INT2_COLOR_COUNTS[]
const SkColor COLORS[]
const int INT8_COLOR_COUNTS[]
const int M1_POSITIONS[]
const int M2_POSITIONS[]
const int INT6_COLOR_COUNTS[]
const int INT1_COLOR_COUNTS[]
static void shade_rect(SkCanvas *canvas, sk_sp< SkShader > shader, int cellRow, int cellCol)
const int WIDTH
const int NUM_COLS
const int RECT_WIDTH
const int * M_POSITIONS[]
const int CELL_HEIGHT
const int * INTERVAL_COLOR_COUNTS[]
const int COLOR_COUNT
const int NUM_ROWS
const int M3_POSITIONS[]
const int HEIGHT
void onDraw(SkCanvas *canvas) override
SkString getName() const override
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
int save()
Definition: SkCanvas.cpp:447
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
Definition: gm.h:110
const Paint & paint
Definition: color_source.cc:38
#define DEF_GM(CODE)
Definition: gm.h:40
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
PODArray< SkColor > colors
Definition: SkRecords.h:276
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
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609