Flutter Engine
The Flutter Engine
recordopts.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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"
17#include "include/core/SkRect.h"
23
24constexpr int kTestRectSize = 50;
25constexpr int kDetectorGreenValue = 50;
26
27// Below are few functions to install "detector" color filters. The filter is there to assert that
28// the color value it sees is the expected. It will trigger only with kDetectorGreenValue, and
29// turn that value into full green. The idea is that if an optimization incorrectly changes
30// kDetectorGreenValue and then the incorrect value is observable by some part of the drawing
31// pipeline, that pixel will remain empty.
32
34 uint8_t tableA[256] = { 0, };
35 uint8_t tableR[256] = { 0, };
36 uint8_t tableG[256] = { 0, };
37 uint8_t tableB[256] = { 0, };
38 tableA[255] = 255;
39 tableG[kDetectorGreenValue] = 255;
40 return SkColorFilters::TableARGB(tableA, tableR, tableG, tableB);
41}
42
43// This detector detects that color filter phase of the pixel pipeline receives the correct value.
44static void install_detector_color_filter(SkPaint* drawPaint) {
46}
47
48// This detector detects that image filter phase of the pixel pipeline receives the correct value.
49static void install_detector_image_filter(SkPaint* drawPaint) {
52}
53
55}
56
58
59
60// Draws an pattern that can be optimized by alpha folding outer savelayer alpha value to
61// inner draw. Since we know that folding will happen to the inner draw, install a detector
62// to make sure that optimization does not change anything observable.
64 InstallDetectorFunc installDetector) {
66 SkPaint layerPaint;
67 layerPaint.setColor(SkColorSetARGB(128, 0, 0, 0));
68 canvas->saveLayer(&targetRect, &layerPaint);
69 SkPaint drawPaint;
70 drawPaint.setColor(shapeColor);
71 installDetector(&drawPaint);
72 canvas->drawRect(targetRect, drawPaint);
73 canvas->restore();
74}
75
76// Draws an pattern that can be optimized by alpha folding outer savelayer alpha value to
77// inner draw. A variant where the draw is not uniform color.
79 InstallDetectorFunc installDetector) {
81 bitmap.allocN32Pixels(kTestRectSize, kTestRectSize);
82 bitmap.eraseColor(shapeColor);
83 {
84 // Make the bitmap non-uniform color, so that it can not be optimized as uniform drawRect.
85 SkCanvas bitmapCanvas(bitmap);
86 SkPaint p;
87 p.setColor(SK_ColorWHITE);
88 SkASSERT(shapeColor != SK_ColorWHITE);
90 }
91
93 SkPaint layerPaint;
94 layerPaint.setColor(SkColorSetARGB(129, 0, 0, 0));
95 canvas->saveLayer(&targetRect, &layerPaint);
96 SkPaint drawPaint;
97 installDetector(&drawPaint);
98 canvas->drawImage(bitmap.asImage(), 0, 0, SkSamplingOptions(), &drawPaint);
99 canvas->restore();
100}
101
102// Draws an pattern that can be optimized by alpha folding outer savelayer alpha value to
103// inner savelayer. We know that alpha folding happens to inner savelayer, so add detector there.
105 InstallDetectorFunc installDetector) {
106
108 sk_sp<SkPicture> shape;
109 {
110 SkPictureRecorder recorder;
111 SkCanvas* recordCanvas = recorder.beginRecording(SkIntToScalar(kTestRectSize + 2),
113 SkPaint shapePaint;
114 shapePaint.setColor(shapeColor);
115 recordCanvas->drawRect(targetRect, shapePaint);
116 shape = recorder.finishRecordingAsPicture();
117 }
118
119 SkPaint layerPaint;
120 layerPaint.setColor(SkColorSetARGB(130, 0, 0, 0));
121 canvas->saveLayer(&targetRect, &layerPaint);
122 canvas->save();
123 canvas->clipRect(targetRect);
124 SkPaint drawPaint;
125 drawPaint.setImageFilter(SkImageFilters::Picture(shape));
126 installDetector(&drawPaint);
127 canvas->saveLayer(&targetRect, &drawPaint);
128 canvas->restore();
129 canvas->restore();
130 canvas->restore();
131}
132
133// Draws two columns of rectangles. The test is correct when:
134// - Left and right columns always identical
135// - First 3 rows are green, with a white dent in the middle row
136// - Next 6 rows are green, with a grey dent in the middle row
137// (the grey dent is from the color filter removing everything but the "good" green, see below)
138// - Last 6 rows are grey
139DEF_SIMPLE_GM(recordopts, canvas, (kTestRectSize+1)*2, (kTestRectSize+1)*15) {
140 auto direct = GrAsDirectContext(canvas->recordingContext());
141 canvas->clear(SK_ColorTRANSPARENT);
142
143 typedef void (*TestVariantSequence)(SkCanvas*, SkColor, InstallDetectorFunc);
144 TestVariantSequence funcs[] = {
148 };
149
150 // Draw layer-related sequences that can be optimized by folding the opacity layer alpha to
151 // the inner draw operation. This tries to trigger the optimization, and relies on gm diffs
152 // to keep the color value correct over time.
153
154 // Draws two green rects side by side: one is without the optimization, the other is with
155 // the optimization applied.
156
157 SkColor shapeColor = SkColorSetARGB(255, 0, 255, 0);
158 for (size_t k = 0; k < std::size(funcs); ++k) {
159 canvas->save();
160
161 TestVariantSequence drawTestSequence = funcs[k];
162 drawTestSequence(canvas, shapeColor, no_detector_install);
163 if (direct) {
164 direct->flushAndSubmit();
165 }
166 canvas->translate(SkIntToScalar(kTestRectSize) + SkIntToScalar(1), SkIntToScalar(0));
167 {
168 SkPictureRecorder recorder;
169 drawTestSequence(recorder.beginRecording(SkIntToScalar(kTestRectSize),
171 shapeColor, no_detector_install);
172 recorder.finishRecordingAsPicture()->playback(canvas);
173 if (direct) {
174 direct->flushAndSubmit();
175 }
176 }
177 canvas->restore();
178 canvas->translate(SkIntToScalar(0), SkIntToScalar(kTestRectSize) + SkIntToScalar(1));
179 }
180
181 // Draw the same layer related sequences, but manipulate the sequences so that the result is
182 // incorrect if the alpha is folded or folded incorrectly. These test the observable state
183 // throughout the pixel pipeline, and thus may turn off the optimizations (this is why we
184 // trigger the optimizations above).
185
186 // Draws two green rects side by side: one is without the optimization, the other is with
187 // the possibility that optimization is applied.
188 // At the end, draws the same patterns in translucent black. This tests that the detectors
189 // work, eg. that if the value the detector sees is wrong, the resulting image shows this.
190 SkColor shapeColors[] = {
192 SkColorSetARGB(255, 0, (kDetectorGreenValue + 1), 0) // This tests that detectors work.
193 };
194
195 InstallDetectorFunc detectorInstallFuncs[] = {
198 };
199
200 for (size_t i = 0; i < std::size(shapeColors); ++i) {
201 shapeColor = shapeColors[i];
202 for (size_t j = 0; j < std::size(detectorInstallFuncs); ++j) {
203 InstallDetectorFunc detectorInstallFunc = detectorInstallFuncs[j];
204 for (size_t k = 0; k < std::size(funcs); ++k) {
205 TestVariantSequence drawTestSequence = funcs[k];
206 canvas->save();
207 drawTestSequence(canvas, shapeColor, detectorInstallFunc);
208 if (direct) {
209 direct->flushAndSubmit();
210 }
211 canvas->translate(SkIntToScalar(kTestRectSize + 1), SkIntToScalar(0));
212 {
213 SkPictureRecorder recorder;
214 drawTestSequence(recorder.beginRecording(SkIntToScalar(kTestRectSize),
216 shapeColor, detectorInstallFunc);
217 recorder.finishRecordingAsPicture()->playback(canvas);
218 if (direct) {
219 direct->flushAndSubmit();
220 }
221 }
222
223 canvas->restore();
224 canvas->translate(SkIntToScalar(0), SkIntToScalar(kTestRectSize + 1));
225 }
226
227 }
228 }
229}
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
#define SkASSERT(cond)
Definition: SkAssert.h:116
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
#define SkIntToScalar(x)
Definition: SkScalar.h:57
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
int save()
Definition: SkCanvas.cpp:447
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
static sk_sp< SkColorFilter > TableARGB(const uint8_t tableA[256], const uint8_t tableR[256], const uint8_t tableG[256], const uint8_t tableB[256])
static sk_sp< SkImageFilter > ColorFilter(sk_sp< SkColorFilter > cf, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Picture(sk_sp< SkPicture > pic, const SkRect &targetRect)
void setColor(SkColor color)
Definition: SkPaint.cpp:119
sk_sp< SkImageFilter > refImageFilter() const
void setImageFilter(sk_sp< SkImageFilter > imageFilter)
void setColorFilter(sk_sp< SkColorFilter > colorFilter)
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
virtual void playback(SkCanvas *canvas, AbortCallback *callback=nullptr) const =0
Definition: bitmap.py:1
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
static void install_detector_image_filter(SkPaint *drawPaint)
Definition: recordopts.cpp:49
static sk_sp< SkColorFilter > make_detector_color_filter()
Definition: recordopts.cpp:33
DEF_SIMPLE_GM(recordopts, canvas,(kTestRectSize+1) *2,(kTestRectSize+1) *15)
Definition: recordopts.cpp:139
static void no_detector_install(SkPaint *)
Definition: recordopts.cpp:54
constexpr int kDetectorGreenValue
Definition: recordopts.cpp:25
constexpr int kTestRectSize
Definition: recordopts.cpp:24
static void draw_save_layer_draw_rect_restore_sequence(SkCanvas *canvas, SkColor shapeColor, InstallDetectorFunc installDetector)
Definition: recordopts.cpp:63
static void install_detector_color_filter(SkPaint *drawPaint)
Definition: recordopts.cpp:44
void(* InstallDetectorFunc)(SkPaint *)
Definition: recordopts.cpp:57
static void draw_svg_opacity_and_filter_layer_sequence(SkCanvas *canvas, SkColor shapeColor, InstallDetectorFunc installDetector)
Definition: recordopts.cpp:104
static void draw_save_layer_draw_bitmap_restore_sequence(SkCanvas *canvas, SkColor shapeColor, InstallDetectorFunc installDetector)
Definition: recordopts.cpp:78
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609