Flutter Engine
The Flutter Engine
SerialProcsTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 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
10#include "include/core/SkData.h"
12#include "include/core/SkFont.h"
18#include "include/core/SkRect.h"
28#include "tests/Test.h"
29#include "tools/DecodeUtils.h"
30#include "tools/Resources.h"
31#include "tools/ToolUtils.h"
33
34#include <algorithm>
35#include <cstring>
36#include <functional>
37#include <iterator>
38
40 SkIRect r = pic->cullRect().round();
42 surf->getCanvas()->drawPicture(pic);
43 return surf->makeImageSnapshot();
44}
45
46struct State {
47 const char* fStr;
49};
50
51DEF_TEST(serial_procs_image, reporter) {
52 auto src_img = ToolUtils::GetResourceAsImage("images/mandrill_128.png");
53 const char magic_str[] = "magic signature";
54
55 const SkSerialImageProc sprocs[] = {
56 [](SkImage* img, void* ctx) -> sk_sp<SkData> { return nullptr; },
57 [](SkImage* img, void* ctx) { return SkPngEncoder::Encode(nullptr, img, {}); },
58 [](SkImage* img, void* ctx) { return SkData::MakeWithCString(((State*)ctx)->fStr); },
59 };
60 const SkDeserialImageProc dprocs[] = {
61 [](const void* data, size_t length, void*) -> sk_sp<SkImage> { return nullptr; },
62 [](const void* data, size_t length, void*) {
64 },
65 [](const void* data, size_t length, void* ctx) -> sk_sp<SkImage> {
66 State* state = (State*)ctx;
67 if (length != strlen(state->fStr) + 1 || 0 != memcmp(data, state->fStr, length)) {
68 return nullptr;
69 }
70 return sk_ref_sp(state->fImg);
71 },
72 };
73
75 {
77 SkCanvas* canvas = rec.beginRecording(128, 128);
78 canvas->drawImage(src_img, 0, 0);
79 pic = rec.finishRecordingAsPicture();
80 }
81
82 State state = { magic_str, src_img.get() };
83
84 SkSerialProcs sproc;
85 sproc.fImageCtx = &state;
86 SkDeserialProcs dproc;
87 dproc.fImageCtx = &state;
88
89 for (size_t i = 0; i < std::size(sprocs); ++i) {
90 sproc.fImageProc = sprocs[i];
91 auto data = pic->serialize(&sproc);
93
94 dproc.fImageProc = dprocs[i];
95 auto new_pic = SkPicture::MakeFromData(data.get(), &dproc);
97
98 auto dst_img = picture_to_image(new_pic);
99 REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(src_img.get(), dst_img.get()));
100 }
101}
102
103///////////////////////////////////////////////////////////////////////////////////////////////////
104
105static sk_sp<SkPicture> make_pic(const std::function<void(SkCanvas*)>& drawer) {
107 drawer(rec.beginRecording(128, 128));
108 return rec.finishRecordingAsPicture();
109}
110
111static SkSerialProcs makes(SkSerialPictureProc proc, void* ctx = nullptr) {
112 SkSerialProcs procs;
113 procs.fPictureProc = proc;
114 procs.fPictureCtx = ctx;
115 return procs;
116}
117
118static SkDeserialProcs maked(SkDeserialPictureProc proc, const void* ctx = nullptr) {
119 SkDeserialProcs procs;
120 procs.fPictureProc = proc;
121 procs.fPictureCtx = const_cast<void*>(ctx);
122 return procs;
123}
124
125// packages the picture's point in the skdata, and records it in the ctx as an array
126struct Context {
128 SkPicture* fSkipMe = nullptr;
129};
130
132 Context* c = (Context*)ctx;
133 if (c->fSkipMe == pic) {
134 return nullptr;
135 }
136 *c->fArray.append() = pic;
137 return SkData::MakeWithCopy(&pic, sizeof(pic));
138}
139
140static sk_sp<SkPicture> array_deserial_proc(const void* data, size_t size, void* ctx) {
141 SkASSERT(sizeof(SkPicture*) == size);
142
143 Context* c = (Context*)ctx;
144 SkPicture* pic;
145 memcpy(&pic, data, size);
146
147 auto found = std::find(c->fArray.begin(), c->fArray.end(), pic);
148 SkASSERT(found != c->fArray.end());
149 if (found != c->fArray.end()) {
151 }
152
153 return sk_ref_sp(pic);
154}
155
157 bool skipRoot) {
158 Context ctx;
159 if (skipRoot) {
160 ctx.fSkipMe = p0.get();
161 }
162
163 SkSerialProcs sprocs = makes(array_serial_proc, &ctx);
164 auto d0 = p0->serialize(&sprocs);
167 p0 = SkPicture::MakeFromData(d0.get(), &dprocs);
168 REPORTER_ASSERT(reporter, ctx.fArray.size() == 0);
169}
170
171DEF_TEST(serial_procs_picture, reporter) {
172
173 auto p1 = make_pic([](SkCanvas* c) {
174 // need to be large enough that drawPictures doesn't "unroll" us
175 for (int i = 0; i < 20; ++i) {
177 }
178 });
179
180 // now use custom serialization
181 auto p0 = make_pic([](SkCanvas* c) { c->drawColor(SK_ColorBLUE); });
182 test_pictures(reporter, p0, 1, false);
183
184 // test inside effect
185 p0 = make_pic([p1](SkCanvas* c) {
188 paint.setShader(p1->makeShader(tm, tm, SkFilterMode::kNearest));
189 c->drawPaint(paint);
190 });
191 test_pictures(reporter, p0, 1, true);
192
193 // test nested picture
194 p0 = make_pic([p1](SkCanvas* c) {
196 c->drawPicture(p1);
198 });
199 test_pictures(reporter, p0, 1, true);
200}
201
204 SkCanvas* canvas = rec.beginRecording(100, 100);
206 SkFont font;
207 font.setTypeface(tf0); canvas->drawString("hello", 0, 0, font, paint);
208 font.setTypeface(tf1); canvas->drawString("hello", 0, 0, font, paint);
209 font.setTypeface(tf0); canvas->drawString("hello", 0, 0, font, paint);
210 font.setTypeface(tf1); canvas->drawString("hello", 0, 0, font, paint);
211 return rec.finishRecordingAsPicture();
212}
213
214DEF_TEST(serial_typeface, reporter) {
215 auto tf0 = ToolUtils::CreateTypefaceFromResource("fonts/hintgasp.ttf");
216 auto tf1 = ToolUtils::CreateTypefaceFromResource("fonts/Roboto2-Regular_NoEmbed.ttf");
217 if (!tf0 || !tf1 || tf0.get() == tf1.get()) {
218 return; // need two different typefaces for this test to make sense.
219 }
220
221 auto pic = make_picture(tf0, tf1);
222
223 int counter = 0;
224 SkSerialProcs procs;
225 procs.fTypefaceProc = [](SkTypeface* tf, void* ctx) -> sk_sp<SkData> {
226 *(int*)ctx += 1;
227 return nullptr;
228 };
229 procs.fTypefaceCtx = &counter;
230 auto data = pic->serialize(&procs);
231
232 // The picture has 2 references to each typeface, but we want the serialized picture to
233 // only have written the data 1 time per typeface.
234 REPORTER_ASSERT(reporter, counter == 2);
235}
236
reporter
Definition: FontMgrTest.cpp:39
int count
Definition: FontMgrTest.cpp:50
const char * fStr
static sk_sp< SkData > array_serial_proc(SkPicture *pic, void *ctx)
static sk_sp< SkPicture > make_pic(const std::function< void(SkCanvas *)> &drawer)
static sk_sp< SkPicture > array_deserial_proc(const void *data, size_t size, void *ctx)
static void test_pictures(skiatest::Reporter *reporter, sk_sp< SkPicture > p0, int count, bool skipRoot)
static SkSerialProcs makes(SkSerialPictureProc proc, void *ctx=nullptr)
static sk_sp< SkImage > picture_to_image(const sk_sp< SkPicture > &pic)
static sk_sp< SkPicture > make_picture(const sk_sp< SkTypeface > &tf0, const sk_sp< SkTypeface > &tf1)
DEF_TEST(serial_procs_image, reporter)
static SkDeserialProcs maked(SkDeserialPictureProc proc, const void *ctx=nullptr)
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
SkTileMode
Definition: SkTileMode.h:13
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
int find(T *array, int N, T item)
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
void drawPicture(const SkPicture *picture)
Definition: SkCanvas.h:1961
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
static sk_sp< SkData > MakeWithCString(const char cstr[])
Definition: SkData.cpp:195
static sk_sp< SkData > MakeWithCopy(const void *data, size_t length)
Definition: SkData.cpp:111
Definition: SkFont.h:35
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkData > serialize(const SkSerialProcs *procs=nullptr) const
Definition: SkPicture.cpp:249
virtual SkRect cullRect() const =0
static sk_sp< SkPicture > MakeFromData(const SkData *data, const SkDeserialProcs *procs=nullptr)
Definition: SkPicture.cpp:160
T * end()
Definition: SkTDArray.h:152
int size() const
Definition: SkTDArray.h:138
T * begin()
Definition: SkTDArray.h:150
T * append()
Definition: SkTDArray.h:191
void removeShuffle(int index)
Definition: SkTDArray.h:214
T * get() const
Definition: SkRefCnt.h:303
const Paint & paint
Definition: color_source.cc:38
AtkStateType state
Dart_NativeFunction function
Definition: fuchsia.cc:51
size_t length
SK_API sk_sp< SkImage > DeferredFromEncodedData(sk_sp< SkData > encoded, std::optional< SkAlphaType > alphaType=std::nullopt)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition: DecodeUtils.h:25
bool equal_pixels(const SkPixmap &a, const SkPixmap &b)
Definition: ToolUtils.cpp:456
sk_sp< SkTypeface > CreateTypefaceFromResource(const char *resource, int ttcIndex)
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
font
Font Metadata and Metrics.
SkPicture * fSkipMe
SkTDArray< SkPicture * > fArray
SkDeserialPictureProc fPictureProc
Definition: SkSerialProcs.h:98
SkDeserialImageProc fImageProc
Definition: SkRect.h:32
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158
static SkImageInfo MakeN32Premul(int width, int height)
void round(SkIRect *dst) const
Definition: SkRect.h:1228
void * fPictureCtx
Definition: SkSerialProcs.h:88
void * fImageCtx
Definition: SkSerialProcs.h:91
SkSerialImageProc fImageProc
Definition: SkSerialProcs.h:90
void * fTypefaceCtx
Definition: SkSerialProcs.h:94
SkSerialTypefaceProc fTypefaceProc
Definition: SkSerialProcs.h:93
SkSerialPictureProc fPictureProc
Definition: SkSerialProcs.h:87
const char * fStr
SkImage * fImg
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63