Flutter Engine
The Flutter Engine
FlattenDrawableTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 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"
13#include "include/core/SkFont.h"
18#include "include/core/SkRect.h"
26#include "tests/Test.h"
28
29#include <cstdint>
30#include <cstring>
31
32class IntDrawable : public SkDrawable {
33public:
34 IntDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
35 : fA(a)
36 , fB(b)
37 , fC(c)
38 , fD(d)
39 {}
40
41 void flatten(SkWriteBuffer& buffer) const override {
42 buffer.writeUInt(fA);
43 buffer.writeUInt(fB);
44 buffer.writeUInt(fC);
45 buffer.writeUInt(fD);
46 }
47
49 uint32_t a = buffer.readUInt();
50 uint32_t b = buffer.readUInt();
51 uint32_t c = buffer.readUInt();
52 uint32_t d = buffer.readUInt();
53 return sk_sp<IntDrawable>(new IntDrawable(a, b, c, d));
54 }
55
56 Factory getFactory() const override { return CreateProc; }
57
58 uint32_t a() const { return fA; }
59 uint32_t b() const { return fB; }
60 uint32_t c() const { return fC; }
61 uint32_t d() const { return fD; }
62
63 const char* getTypeName() const override { return "IntDrawable"; }
64
65protected:
66 SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
67 void onDraw(SkCanvas*) override {}
68
69private:
70 uint32_t fA;
71 uint32_t fB;
72 uint32_t fC;
73 uint32_t fD;
74};
75
76class PaintDrawable : public SkDrawable {
77public:
79 : fPaint(paint)
80 {}
81
82 void flatten(SkWriteBuffer& buffer) const override {
83 buffer.writePaint(fPaint);
84 }
85
87 return sk_sp<PaintDrawable>(new PaintDrawable(buffer.readPaint()));
88 }
89
90 Factory getFactory() const override { return CreateProc; }
91
92 const SkPaint& paint() const { return fPaint; }
93
94 const char* getTypeName() const override { return "PaintDrawable"; }
95
96protected:
97 SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
98 void onDraw(SkCanvas*) override {}
99
100private:
101 SkPaint fPaint;
102};
103
105public:
106 CompoundDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint)
107 : fIntDrawable(new IntDrawable(a, b, c, d))
108 , fPaintDrawable(new PaintDrawable(paint))
109 {}
110
112 : fIntDrawable(SkRef(intDrawable))
113 , fPaintDrawable(SkRef(paintDrawable))
114 {}
115
116 void flatten(SkWriteBuffer& buffer) const override {
117 buffer.writeFlattenable(fIntDrawable.get());
118 buffer.writeFlattenable(fPaintDrawable.get());
119 }
120
123 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
125 SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName()));
126
128 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
130 SkASSERT(!strcmp("PaintDrawable", paintDrawable->getTypeName()));
131
133 (PaintDrawable*) paintDrawable.get()));
134 }
135
136 Factory getFactory() const override { return CreateProc; }
137
138 IntDrawable* intDrawable() const { return fIntDrawable.get(); }
139 PaintDrawable* paintDrawable() const { return fPaintDrawable.get(); }
140
141 const char* getTypeName() const override { return "CompoundDrawable"; }
142
143protected:
144 SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
145 void onDraw(SkCanvas*) override {}
146
147private:
148 sk_sp<IntDrawable> fIntDrawable;
149 sk_sp<PaintDrawable> fPaintDrawable;
150};
151
152class RootDrawable : public SkDrawable {
153public:
154 RootDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint,
155 uint32_t e, uint32_t f, uint32_t g, uint32_t h, SkDrawable* drawable)
156 : fCompoundDrawable(new CompoundDrawable(a, b, c, d, paint))
157 , fIntDrawable(new IntDrawable(e, f, g, h))
158 , fDrawable(SkRef(drawable))
159 {}
160
163 : fCompoundDrawable(SkRef(compoundDrawable))
164 , fIntDrawable(SkRef(intDrawable))
165 , fDrawable(SkRef(drawable))
166 {}
167
168 void flatten(SkWriteBuffer& buffer) const override {
169 buffer.writeFlattenable(fCompoundDrawable.get());
170 buffer.writeFlattenable(fIntDrawable.get());
171 buffer.writeFlattenable(fDrawable.get());
172 }
173
176 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
178 SkASSERT(!strcmp("CompoundDrawable", compoundDrawable->getTypeName()));
179
181 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
183 SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName()));
184
186 buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
188
190 (IntDrawable*) intDrawable.get(),
191 (SkDrawable*) drawable.get()));
192 }
193
194 Factory getFactory() const override { return CreateProc; }
195
196 CompoundDrawable* compoundDrawable() const { return fCompoundDrawable.get(); }
197 IntDrawable* intDrawable() const { return fIntDrawable.get(); }
198 SkDrawable* drawable() const { return fDrawable.get(); }
199
200 const char* getTypeName() const override { return "RootDrawable"; }
201
202protected:
203 SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
204 void onDraw(SkCanvas*) override {}
205
206private:
207 sk_sp<CompoundDrawable> fCompoundDrawable;
208 sk_sp<IntDrawable> fIntDrawable;
209 sk_sp<SkDrawable> fDrawable;
210};
211
212// Register these drawables for deserialization some time before main().
213static struct Initializer {
219 }
221
222DEF_TEST(FlattenDrawable, r) {
223 // Create and serialize the test drawable
224 sk_sp<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4));
226 paint.setColor(SK_ColorBLUE);
227 sk_sp<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable.get()));
228 SkBinaryWriteBuffer writeBuffer({});
229 writeBuffer.writeFlattenable(root.get());
230
231 // Copy the contents of the write buffer into a read buffer
232 sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
233 writeBuffer.writeToMemory(data->writable_data());
234 SkReadBuffer readBuffer(data->data(), data->size());
235
236 // Deserialize and verify the drawable
239 REPORTER_ASSERT(r, !strcmp("RootDrawable", out->getTypeName()));
240
241 RootDrawable* rootOut = (RootDrawable*) out.get();
242 REPORTER_ASSERT(r, 5 == rootOut->compoundDrawable()->intDrawable()->a());
243 REPORTER_ASSERT(r, 6 == rootOut->compoundDrawable()->intDrawable()->b());
244 REPORTER_ASSERT(r, 7 == rootOut->compoundDrawable()->intDrawable()->c());
245 REPORTER_ASSERT(r, 8 == rootOut->compoundDrawable()->intDrawable()->d());
247 rootOut->compoundDrawable()->paintDrawable()->paint().getColor());
248 REPORTER_ASSERT(r, 9 == rootOut->intDrawable()->a());
249 REPORTER_ASSERT(r, 10 == rootOut->intDrawable()->b());
250 REPORTER_ASSERT(r, 11 == rootOut->intDrawable()->c());
251 REPORTER_ASSERT(r, 12 == rootOut->intDrawable()->d());
252
253 // Note that we can still recognize the generic drawable as an IntDrawable
254 SkDrawable* generic = rootOut->drawable();
255 REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName()));
256 IntDrawable* integer = (IntDrawable*) generic;
257 REPORTER_ASSERT(r, 1 == integer->a());
258 REPORTER_ASSERT(r, 2 == integer->b());
259 REPORTER_ASSERT(r, 3 == integer->c());
260 REPORTER_ASSERT(r, 4 == integer->d());
261}
262
263DEF_TEST(FlattenRecordedDrawable, r) {
264 // Record a set of canvas draw commands
265 SkPictureRecorder recorder;
266 SkCanvas* canvas = recorder.beginRecording(1000.0f, 1000.0f);
268 paint.setColor(SK_ColorGREEN);
269 canvas->drawPoint(42.0f, 17.0f, paint);
270 paint.setColor(SK_ColorRED);
271 canvas->drawPaint(paint);
272 SkPaint textPaint;
273 textPaint.setColor(SK_ColorBLUE);
274 canvas->drawString("TEXT", 467.0f, 100.0f, ToolUtils::DefaultFont(), textPaint);
275
276 // Draw some drawables as well
277 sk_sp<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4));
278 sk_sp<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable.get()));
279 canvas->drawDrawable(root.get(), 747.0f, 242.0f);
280 sk_sp<PaintDrawable> paintDrawable(new PaintDrawable(paint));
281 canvas->drawDrawable(paintDrawable.get(), 500.0, 500.0f);
282 sk_sp<CompoundDrawable> comDrawable(new CompoundDrawable(13, 14, 15, 16, textPaint));
283 canvas->drawDrawable(comDrawable.get(), 10.0f, 10.0f);
284
285 // Serialize the recorded drawable
286 sk_sp<SkDrawable> recordedDrawable = recorder.finishRecordingAsDrawable();
287 SkBinaryWriteBuffer writeBuffer({});
288 writeBuffer.writeFlattenable(recordedDrawable.get());
289
290 // Copy the contents of the write buffer into a read buffer
291 sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
292 writeBuffer.writeToMemory(data->writable_data());
293 SkReadBuffer readBuffer(data->data(), data->size());
294
295 // Deserialize and verify the drawable
298 REPORTER_ASSERT(r, !strcmp("SkRecordedDrawable", out->getTypeName()));
299}
300
301// be sure these constructs compile, don't assert, and return null
302DEF_TEST(Flattenable_EmptyDeserialze, reporter) {
303 auto data = SkData::MakeEmpty();
304
305 #define test(name) REPORTER_ASSERT(reporter, !name::Deserialize(data->data(), data->size()))
308 test(SkShaderBase); // todo: make this just be shader!
311 #undef test
312}
313
#define test(name)
DEF_TEST(FlattenDrawable, r)
static struct Initializer initializer
reporter
Definition: FontMgrTest.cpp:39
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
#define SK_REGISTER_FLATTENABLE(type)
static T * SkRef(T *obj)
Definition: SkRefCnt.h:132
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
CompoundDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint &paint)
static sk_sp< SkFlattenable > CreateProc(SkReadBuffer &buffer)
const char * getTypeName() const override
PaintDrawable * paintDrawable() const
Factory getFactory() const override
void onDraw(SkCanvas *) override
CompoundDrawable(IntDrawable *intDrawable, PaintDrawable *paintDrawable)
void flatten(SkWriteBuffer &buffer) const override
SkRect onGetBounds() override
IntDrawable * intDrawable() const
const char * getTypeName() const override
void flatten(SkWriteBuffer &buffer) const override
uint32_t b() const
void onDraw(SkCanvas *) override
Factory getFactory() const override
static sk_sp< SkFlattenable > CreateProc(SkReadBuffer &buffer)
uint32_t d() const
uint32_t a() const
IntDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
SkRect onGetBounds() override
uint32_t c() const
static sk_sp< SkFlattenable > CreateProc(SkReadBuffer &buffer)
SkRect onGetBounds() override
const char * getTypeName() const override
PaintDrawable(const SkPaint &paint)
void onDraw(SkCanvas *) override
Factory getFactory() const override
const SkPaint & paint() const
void flatten(SkWriteBuffer &buffer) const override
void onDraw(SkCanvas *) override
SkDrawable * drawable() const
SkRect onGetBounds() override
Factory getFactory() const override
const char * getTypeName() const override
CompoundDrawable * compoundDrawable() const
RootDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint &paint, uint32_t e, uint32_t f, uint32_t g, uint32_t h, SkDrawable *drawable)
static sk_sp< SkFlattenable > CreateProc(SkReadBuffer &buffer)
void flatten(SkWriteBuffer &buffer) const override
IntDrawable * intDrawable() const
RootDrawable(CompoundDrawable *compoundDrawable, IntDrawable *intDrawable, SkDrawable *drawable)
void writeFlattenable(const SkFlattenable *flattenable) override
void drawPoint(SkScalar x, SkScalar y, const SkPaint &paint)
Definition: SkCanvas.cpp:2695
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void drawDrawable(SkDrawable *drawable, const SkMatrix *matrix=nullptr)
Definition: SkCanvas.cpp:2574
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition: SkData.cpp:116
static sk_sp< SkData > MakeEmpty()
Definition: SkData.cpp:94
sk_sp< SkFlattenable >(* Factory)(SkReadBuffer &)
Definition: SkFlattenable.h:41
void setColor(SkColor color)
Definition: SkPaint.cpp:119
SkColor getColor() const
Definition: SkPaint.h:225
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkDrawable > finishRecordingAsDrawable()
SkFlattenable * readFlattenable(SkFlattenable::Type)
T * get() const
Definition: SkRefCnt.h:303
const Paint & paint
Definition: color_source.cc:38
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
static bool b
struct MyStruct a[10]
SkFont DefaultFont()
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
string root
Definition: scale_cpu.py:20
SkScalar h
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63