Flutter Engine
The Flutter Engine
Functions
CanvasStateTest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkDataTable.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/encode/SkPngEncoder.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTDArray.h"
#include "include/utils/SkCanvasStateUtils.h"
#include "src/base/SkTLazy.h"
#include "tests/Test.h"
#include <array>
#include <cstdint>
#include <cstring>
#include "tests/CanvasStateHelpers.h"

Go to the source code of this file.

Functions

static void write_image (const SkImage *img, const char path[])
 
static void compare (skiatest::Reporter *reporter, SkImage *img0, SkImage *img1)
 
 DEF_TEST (CanvasState_test_complex_layers, reporter)
 
 DEF_TEST (CanvasState_test_complex_clips, reporter)
 
 DEF_TEST (CanvasState_test_soft_clips, reporter)
 
 DEF_TEST (CanvasState_test_saveLayer_clip, reporter)
 

Function Documentation

◆ compare()

static void compare ( skiatest::Reporter reporter,
SkImage img0,
SkImage img1 
)
static

Definition at line 100 of file CanvasStateTest.cpp.

100 {
101 if ((false)) {
102 static int counter;
103
104 SkDebugf("---- counter %d\n", counter);
106 name.printf("no_capture_%d.png", counter);
107 write_image(img0, name.c_str());
108 name.printf("capture_%d.png", counter);
109 write_image(img1, name.c_str());
110 counter++;
111 }
112
113 SkPixmap pm[2];
114 REPORTER_ASSERT(reporter, img0->peekPixels(&pm[0]));
115 REPORTER_ASSERT(reporter, img1->peekPixels(&pm[1]));
116 // now we memcmp the two bitmaps
117 REPORTER_ASSERT(reporter, pm[0].computeByteSize() == pm[1].computeByteSize());
118 REPORTER_ASSERT(reporter, pm[0].rowBytes() == (size_t)pm[0].width() * pm[0].info().bytesPerPixel());
119 REPORTER_ASSERT(reporter, pm[1].rowBytes() == (size_t)pm[1].width() * pm[1].info().bytesPerPixel());
120 if (memcmp(pm[0].addr(0, 0), pm[1].addr(0, 0), pm[0].computeByteSize()) != 0) {
122 }
123}
static void write_image(const SkImage *img, const char path[])
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
reporter
Definition: FontMgrTest.cpp:39
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
bool peekPixels(SkPixmap *pixmap) const
Definition: SkImage.cpp:34
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
int32_t width

◆ DEF_TEST() [1/4]

DEF_TEST ( CanvasState_test_complex_clips  ,
reporter   
)

Definition at line 205 of file CanvasStateTest.cpp.

205 {
206 const int WIDTH = 400;
207 const int HEIGHT = 400;
208 const int SPACER = 10;
209
210 SkIRect layerRect = SkIRect::MakeWH(WIDTH, HEIGHT / 4);
211 layerRect.inset(2*SPACER, 2*SPACER);
212
213 SkIRect clipRect = layerRect;
214 clipRect.fRight = clipRect.fLeft + (clipRect.width() / 2) - (2*SPACER);
215 clipRect.outset(SPACER, SPACER);
216
217 SkIRect regionBounds = clipRect;
218 regionBounds.offset(clipRect.width() + (2*SPACER), 0);
219
220 SkIRect regionInterior = regionBounds;
221 regionInterior.inset(SPACER*3, SPACER*3);
222
223 SkRegion clipRegion;
224 clipRegion.setRect(regionBounds);
225 clipRegion.op(regionInterior, SkRegion::kDifference_Op);
226
227
228 const SkRegion::Op clipOps[] = { SkRegion::kIntersect_Op,
231 };
232
233 bool (*drawFn)(SkCanvasState* state, int32_t l, int32_t t,
234 int32_t r, int32_t b, int32_t clipOp,
235 int32_t regionRects, int32_t* rectCoords);
236
237#if defined(SK_TEST_CANVAS_STATE_CROSS_LIBRARY)
238 OpenLibResult openLibResult(reporter);
239 *(void**) (&drawFn) = openLibResult.procAddress("complex_clips_draw_from_canvas_state");
240#else
242#endif
243
244 REPORTER_ASSERT(reporter, drawFn);
245 if (!drawFn) {
246 return;
247 }
248
250 for (int i = 0; i < 2; ++i) {
252 SkCanvas* canvas = surf->getCanvas();
253
254 canvas->drawColor(SK_ColorRED);
255
256 SkRegion localRegion = clipRegion;
257
259 paint.setAlpha(128);
260 for (size_t j = 0; j < std::size(clipOps); ++j) {
261 SkRect layerBounds = SkRect::Make(layerRect);
262 canvas->saveLayer(SkCanvas::SaveLayerRec(&layerBounds, &paint));
263
264 if (i) {
267
268 SkRegion::Iterator iter(localRegion);
269 SkTDArray<int32_t> rectCoords;
270 for (; !iter.done(); iter.next()) {
271 const SkIRect& rect = iter.rect();
272 *rectCoords.append() = rect.fLeft;
273 *rectCoords.append() = rect.fTop;
274 *rectCoords.append() = rect.fRight;
275 *rectCoords.append() = rect.fBottom;
276 }
277 bool success = drawFn(state, clipRect.fLeft, clipRect.fTop,
278 clipRect.fRight, clipRect.fBottom, clipOps[j],
279 rectCoords.size() / 4, rectCoords.begin());
280 REPORTER_ASSERT(reporter, success);
281
283 } else {
284 complex_clips_draw(canvas, clipRect.fLeft, clipRect.fTop,
285 clipRect.fRight, clipRect.fBottom, clipOps[j],
286 localRegion);
287 }
288
289 canvas->restore();
290
291 // translate the canvas and region for the next iteration
292 canvas->translate(0, SkIntToScalar(2*(layerRect.height() + (SPACER))));
293 localRegion.translate(0, 2*(layerRect.height() + SPACER));
294 }
295 images[i] = surf->makeImageSnapshot();
296 }
297
298 compare(reporter, images[0].get(), images[1].get());
299}
bool complex_clips_draw_from_canvas_state(SkCanvasState *state, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t clipOp, int32_t regionRects, int32_t *rectCoords)
void complex_clips_draw(SkCanvas *canvas, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t clipOp, const SkRegion &localRegion)
static void compare(skiatest::Reporter *reporter, SkImage *img0, SkImage *img1)
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define WIDTH
#define HEIGHT
static SkCanvasState * CaptureCanvasState(SkCanvas *canvas)
static void ReleaseCanvasState(SkCanvasState *state)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition: SkCanvas.cpp:496
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 translate(int dx, int dy)
Definition: SkRegion.h:349
@ kIntersect_Op
target intersected with operand
Definition: SkRegion.h:368
@ kDifference_Op
target minus operand
Definition: SkRegion.h:367
bool op(const SkIRect &rect, Op op)
Definition: SkRegion.h:384
bool setRect(const SkIRect &rect)
Definition: SkRegion.cpp:192
int size() const
Definition: SkTDArray.h:138
T * begin()
Definition: SkTDArray.h:150
T * append()
Definition: SkTDArray.h:191
const Paint & paint
Definition: color_source.cc:38
static bool b
AtkStateType state
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
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
const myers::Point & get(const myers::Segment &)
Definition: SkRect.h:32
void inset(int32_t dx, int32_t dy)
Definition: SkRect.h:411
constexpr int32_t height() const
Definition: SkRect.h:165
void offset(int32_t dx, int32_t dy)
Definition: SkRect.h:367
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
static SkImageInfo MakeN32Premul(int width, int height)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669

◆ DEF_TEST() [2/4]

DEF_TEST ( CanvasState_test_complex_layers  ,
reporter   
)

Definition at line 125 of file CanvasStateTest.cpp.

125 {
126 const int WIDTH = 400;
127 const int HEIGHT = 400;
128 const int SPACER = 10;
129
131 SkIntToScalar(WIDTH-(2*SPACER)),
132 SkIntToScalar((HEIGHT-(2*SPACER)) / 7));
133
134 const SkColorType colorTypes[] = {
135 kRGB_565_SkColorType, kN32_SkColorType
136 };
137
138 const int layerAlpha[] = { 255, 255, 0 };
139
140 bool (*drawFn)(SkCanvasState* state, float l, float t,
141 float r, float b, int32_t s);
142
143#if defined(SK_TEST_CANVAS_STATE_CROSS_LIBRARY)
144 OpenLibResult openLibResult(reporter);
145 *(void**) (&drawFn) = openLibResult.procAddress("complex_layers_draw_from_canvas_state");
146#else
148#endif
149
150 REPORTER_ASSERT(reporter, drawFn);
151 if (!drawFn) {
152 return;
153 }
154
155 for (size_t i = 0; i < std::size(colorTypes); ++i) {
157 for (int j = 0; j < 2; ++j) {
158 auto surf = SkSurfaces::Raster(
160 SkCanvas* canvas = surf->getCanvas();
161
162 canvas->drawColor(SK_ColorRED);
163
164 for (size_t k = 0; k < std::size(layerAlpha); ++k) {
166 if (layerAlpha[k] != 0xFF) {
167 paint.init()->setAlpha(layerAlpha[k]);
168 }
169
170 // draw a rect within the layer's bounds and again outside the layer's bounds
171 canvas->saveLayer(SkCanvas::SaveLayerRec(&rect, paint.getMaybeNull()));
172
173 if (j) {
174 // Capture from the first Skia.
177
178 // And draw to it in the second Skia.
180 rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, SPACER);
181 REPORTER_ASSERT(reporter, success);
182
183 // And release it in the *first* Skia.
185 } else {
186 // Draw in the first Skia.
187 complex_layers_draw(canvas, rect.fLeft, rect.fTop,
188 rect.fRight, rect.fBottom, SPACER);
189 }
190
191 canvas->restore();
192
193 // translate the canvas for the next iteration
194 canvas->translate(0, 2*(rect.height() + SPACER));
195 }
196 images[j] = surf->makeImageSnapshot();
197 }
198
199 compare(reporter, images[0].get(), images[1].get());
200 }
201}
bool complex_layers_draw_from_canvas_state(SkCanvasState *state, float left, float top, float right, float bottom, int32_t spacer)
void complex_layers_draw(SkCanvas *canvas, float left, float top, float right, float bottom, int32_t spacer)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
SkColorType
Definition: SkColorType.h:19
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
struct MyStruct s
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659

◆ DEF_TEST() [3/4]

DEF_TEST ( CanvasState_test_saveLayer_clip  ,
reporter   
)

Definition at line 317 of file CanvasStateTest.cpp.

317 {
318 const int WIDTH = 100;
319 const int HEIGHT = 100;
320 const int LAYER_WIDTH = 50;
321 const int LAYER_HEIGHT = 50;
322
324 bitmap.allocN32Pixels(WIDTH, HEIGHT);
325 SkCanvas canvas(bitmap);
326
327 SkRect bounds = SkRect::MakeWH(SkIntToScalar(LAYER_WIDTH), SkIntToScalar(LAYER_HEIGHT));
329
330 // Check that saveLayer sets the clip stack to the layer bounds.
331 canvas.saveLayer(&bounds, nullptr);
332 SkIRect devClip = canvas.getDeviceClipBounds();
333 REPORTER_ASSERT(reporter, canvas.isClipRect());
334 REPORTER_ASSERT(reporter, devClip.width() == LAYER_WIDTH);
335 REPORTER_ASSERT(reporter, devClip.height() == LAYER_HEIGHT);
336 canvas.restore();
337}
Optional< SkRect > bounds
Definition: SkRecords.h:189
Definition: bitmap.py:1
constexpr int32_t width() const
Definition: SkRect.h:158
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609

◆ DEF_TEST() [4/4]

DEF_TEST ( CanvasState_test_soft_clips  ,
reporter   
)

Definition at line 303 of file CanvasStateTest.cpp.

303 {
305 bitmap.allocN32Pixels(10, 10);
306 SkCanvas canvas(bitmap);
307
308 SkRRect roundRect;
309 roundRect.setOval(SkRect::MakeWH(5, 5));
310
311 canvas.clipRRect(roundRect, SkClipOp::kIntersect, true);
312
315}
void setOval(const SkRect &oval)
Definition: SkRRect.cpp:30

◆ write_image()

static void write_image ( const SkImage img,
const char  path[] 
)
static

Definition at line 95 of file CanvasStateTest.cpp.

95 {
96 auto data = SkPngEncoder::Encode(nullptr, img, {});
97 SkFILEWStream(path).write(data->data(), data->size());
98}
bool write(const void *buffer, size_t size) override
Definition: SkStream.cpp:426
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63