Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
NdkDecodeTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google LLC
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
9#ifdef SK_ENABLE_NDK_IMAGES
18
19#include "tests/Test.h"
20#include "tools/Resources.h"
21#include "tools/ToolUtils.h"
22
23#include <vector>
24
25static std::unique_ptr<SkImageGenerator> make_generator(const char* path, skiatest::Reporter* r) {
26 auto data = GetResourceAsData(path);
27 if (data) {
28 auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(std::move(data));
29 if (gen) {
30 return gen;
31 }
32 ERRORF(r, "Failed to create NDK generator from %s\n", path);
33 } else {
34 // Silently fail so developers can skip using --resources
35 }
36 return nullptr;
37}
38
39DEF_TEST(NdkDecode, r) {
40 static const struct {
41 const char* fPath;
42 SkISize fSize;
43 } recs[] = {
44 {"images/CMYK.jpg", {642, 516}},
45 {"images/arrow.png", {187, 312}},
46 {"images/baby_tux.webp", {386, 395}},
47 {"images/color_wheel.gif", {128, 128}},
48 {"images/rle.bmp", {320, 240}},
49 {"images/color_wheel.ico", {128, 128}},
50 {"images/google_chrome.ico", {256, 256}},
51 {"images/mandrill.wbmp", {512, 512}},
52 };
53 for (auto& rec : recs) {
54 auto gen = make_generator(rec.fPath, r);
55 if (!gen) continue;
56
57 const auto& info = gen->getInfo();
58 REPORTER_ASSERT(r, info.dimensions() == rec.fSize);
59
60 SkBitmap bm;
61 bm.allocPixels(info);
62 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
63
65 auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
66 bm.allocPixels(unpremulInfo);
67 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
68 }
69}
70
71DEF_TEST(NdkDecode_nullData, r) {
72 auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(nullptr);
74}
75
76static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
77
78static constexpr skcms_Matrix3x3 kDCIP3 = {{
79 {0.486143, 0.323835, 0.154234},
80 {0.226676, 0.710327, 0.0629966},
81 {0.000800549, 0.0432385, 0.78275},
82}};
83
84DEF_TEST(NdkDecode_reportedColorSpace, r) {
85 for (sk_sp<SkColorSpace> cs : {
86 sk_sp<SkColorSpace>(nullptr),
94 }) {
95 SkBitmap bm;
98
105 opts.fQuality = 80;
106 REPORTER_ASSERT(r, SkJpegEncoder::Encode(&stream, bm.pixmap(), opts));
107 } else if (format == SkEncodedImageFormat::kPNG) {
108 REPORTER_ASSERT(r, SkPngEncoder::Encode(&stream, bm.pixmap(), {}));
109 } else {
111 opts.fQuality = 80;
112 REPORTER_ASSERT(r, SkWebpEncoder::Encode(&stream, bm.pixmap(), opts));
113 }
114
115 auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(stream.detachAsData());
116 if (!gen) {
117 ERRORF(r, "Failed to encode!");
118 return;
119 }
120
121 if (!cs) cs = SkColorSpace::MakeSRGB();
122 REPORTER_ASSERT(r, SkColorSpace::Equals(gen->getInfo().colorSpace(), cs.get()));
123 }
124 }
125}
126
127DEF_TEST(NdkDecode_ColorSpace, r) {
128 for (const char* path: {
129 "images/CMYK.jpg",
130 "images/arrow.png",
131 "images/baby_tux.webp",
132 "images/color_wheel.gif",
133 "images/rle.bmp",
134 "images/color_wheel.ico",
135 "images/google_chrome.ico",
136 "images/mandrill.wbmp",
137 }) {
138 auto gen = make_generator(path, r);
139 if (!gen) continue;
140
141 for (sk_sp<SkColorSpace> cs : {
142 sk_sp<SkColorSpace>(nullptr),
150 }) {
151 auto info = gen->getInfo().makeColorSpace(cs);
152
153 SkBitmap bm;
154 bm.allocPixels(info);
155 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
156 }
157
158 std::vector<sk_sp<SkColorSpace>> unsupportedCs;
161 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, gamut));
162 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, gamut));
163 unsupportedCs.push_back(SkColorSpace::MakeRGB(k2Dot6, gamut));
164 }
165
168 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, gamut));
169 }
170
173 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, gamut));
174 }
175
178 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut));
179 }
180
181 for (auto gamut : { SkNamedGamut::kAdobeRGB,
183 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut));
184 }
185
188 unsupportedCs.push_back(SkColorSpace::MakeRGB(fn, kDCIP3));
189 }
190
191 for (auto unsupported : unsupportedCs) {
192 auto info = gen->getInfo().makeColorSpace(unsupported);
193
194 SkBitmap bm;
195 bm.allocPixels(info);
196 REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
197 }
198 }
199}
200
201DEF_TEST(NdkDecode_reuseNoColorSpace, r) {
202 static const struct {
203 const char* fPath;
204 sk_sp<SkColorSpace> fCorrectedColorSpace;
205 bool fIsOpaque;
206 } recs[] = {
207 // AImageDecoder defaults to ADATASPACE_UNKNOWN for this image.
208 {"images/wide_gamut_yellow_224_224_64.jpeg", SkColorSpace::MakeSRGB(), true},
209 // This image is SRGB, so convert to a different color space.
210 {"images/example_1.png", SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2,
212 };
213 for (auto& rec : recs) {
214 auto gen = make_generator(rec.fPath, r);
215 if (!gen) continue;
216
217 REPORTER_ASSERT(r, gen->getInfo().colorSpace()->isSRGB());
218 REPORTER_ASSERT(r, gen->getInfo().isOpaque() == rec.fIsOpaque);
219
220 auto noColorCorrection = gen->getInfo().makeColorSpace(nullptr);
221 if (rec.fIsOpaque) {
222 // Use something other than the default color type to verify that the modified color
223 // type is used even when the color space is reset.
224 noColorCorrection = noColorCorrection.makeColorType(kRGB_565_SkColorType);
225 }
226
227 SkBitmap orig;
228 orig.allocPixels(noColorCorrection);
229 REPORTER_ASSERT(r, gen->getPixels(orig.pixmap()));
230
231 SkBitmap corrected;
232 corrected.allocPixels(noColorCorrection.makeColorSpace(rec.fCorrectedColorSpace));
233 REPORTER_ASSERT(r, gen->getPixels(corrected.pixmap()));
234
235 REPORTER_ASSERT(r, !ToolUtils::equal_pixels(orig, corrected));
236
237 SkBitmap reuse;
238 reuse.allocPixels(noColorCorrection);
239 REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap()));
240
242 }
243}
244
245// The NDK supports scaling up to arbitrary dimensions. Skia forces clients to do this in a
246// separate step, so the client is in charge of how to do the upscale.
247DEF_TEST(NdkDecode_noUpscale, r) {
248 for (const char* path: {
249 "images/CMYK.jpg",
250 "images/arrow.png",
251 "images/baby_tux.webp",
252 "images/color_wheel.gif",
253 "images/rle.bmp",
254 "images/color_wheel.ico",
255 "images/google_chrome.ico",
256 "images/mandrill.wbmp",
257 }) {
258 auto gen = make_generator(path, r);
259 if (!gen) continue;
260
261 const auto actualDimensions = gen->getInfo().dimensions();
262 const int width = actualDimensions.width();
263 const int height = actualDimensions.height();
264 for (SkISize dims : {
265 SkISize{width*2, height*2},
266 SkISize{width + 1, height + 1},
267 }) {
268 auto info = gen->getInfo().makeDimensions(dims);
269 SkBitmap bm;
270 bm.allocPixels(info);
271 REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
272 }
273 }
274}
275
276// libwebp supports downscaling to an arbitrary scale factor, and this is supported by the NDK.
277DEF_TEST(NdkDecode_webpArbitraryDownscale, r) {
278 for (const char* path: {
279 "images/baby_tux.webp",
280 "images/yellow_rose.webp",
281 "images/webp-color-profile-lossless.webp",
282 }) {
283 auto gen = make_generator(path, r);
284 if (!gen) continue;
285
286 const auto actualDimensions = gen->getInfo().dimensions();
287 const int width = actualDimensions.width();
288 const int height = actualDimensions.height();
289 for (SkISize dims : {
290 SkISize{width/2, height/2},
291 SkISize{width/4, height/4},
292 SkISize{width/7, height/7},
293 SkISize{width - 1, height - 1},
294 SkISize{1, 1},
295 SkISize{5, 20}
296 }) {
297 auto info = gen->getInfo().makeDimensions(dims);
298 SkBitmap bm;
299 bm.allocPixels(info);
300 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
301
302 REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
303 auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
304 bm.allocPixels(unpremulInfo);
305 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
306 }
307 }
308}
309
310// libjpeg-turbo supports downscaling to some scale factors.
311DEF_TEST(NdkDecode_jpegDownscale, r) {
312 static const struct {
313 const char* fPath;
314 SkISize fSupportedSizes[4];
315 } recs[] = {
316 {"images/CMYK.jpg", {{642,516},{321,258},{161,129},{81,65}}},
317 {"images/dog.jpg", {{180,180},{90,90},{45,45},{23,23}}},
318 {"images/grayscale.jpg", {{128,128},{64,64},{32,32},{16,16}}},
319 {"images/brickwork-texture.jpg", {{512,512},{256,256},{128,128},{64,64}}},
320 {"images/mandrill_h2v1.jpg", {{512,512},{256,256},{128,128},{64,64}}},
321 {"images/ducky.jpg", {{489,537},{245,269},{123,135},{62,68}}},
322 };
323 for (auto& rec : recs) {
324 auto gen = make_generator(rec.fPath, r);
325 if (!gen) continue;
326
327 for (SkISize dims : rec.fSupportedSizes) {
328 auto info = gen->getInfo().makeDimensions(dims);
329 SkBitmap bm;
330 bm.allocPixels(info);
331 if (!gen->getPixels(bm.pixmap())) {
332 ERRORF(r, "failed to decode %s to {%i,%i}\n", rec.fPath, dims.width(),
333 dims.height());
334 }
335
336 REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
337 auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
338 bm.allocPixels(unpremulInfo);
339 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
340 }
341 }
342}
343
344DEF_TEST(NdkDecode_reuseJpeg, r) {
345 auto gen = make_generator("images/CMYK.jpg", r);
346 if (!gen) return;
347
348 SkImageInfo info = gen->getInfo();
349 SkBitmap orig;
350 orig.allocPixels(info);
351 REPORTER_ASSERT(r, gen->getPixels(orig.pixmap()));
352
353 info = info.makeWH(321, 258);
354 SkBitmap downscaled;
355 downscaled.allocPixels(info);
356 REPORTER_ASSERT(r, gen->getPixels(downscaled.pixmap()));
357
358 SkBitmap reuse;
359 reuse.allocPixels(gen->getInfo());
360 REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap()));
361
363}
364
365// The NDK supports scaling down to arbitrary dimensions. Skia forces clients to do this in a
366// separate step, so the client is in charge of how to do the downscale.
367DEF_TEST(NdkDecode_noDownscale, r) {
368 for (const char* path: {
369 "images/arrow.png",
370 "images/color_wheel.gif",
371 "images/rle.bmp",
372 "images/color_wheel.ico",
373 "images/google_chrome.ico",
374 "images/mandrill.wbmp",
375 }) {
376 auto gen = make_generator(path, r);
377 if (!gen) continue;
378
379 const auto actualDimensions = gen->getInfo().dimensions();
380 const int width = actualDimensions.width();
381 const int height = actualDimensions.height();
382 for (SkISize dims : {
383 SkISize{width/2, height/2},
384 SkISize{width/3, height/3},
385 SkISize{width/4, height/4},
386 SkISize{width/8, height/8},
387 SkISize{width - 1, height - 1},
388 }) {
389 auto info = gen->getInfo().makeDimensions(dims);
390 SkBitmap bm;
391 bm.allocPixels(info);
392 REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
393 }
394 }
395}
396
397DEF_TEST(NdkDecode_Gray8, r) {
398 static const struct {
399 const char* fPath;
400 bool fGrayscale;
401 } recs[] = {
402 {"images/CMYK.jpg", false},
403 {"images/arrow.png", false},
404 {"images/baby_tux.webp", false},
405 {"images/color_wheel.gif", false},
406 {"images/rle.bmp", false},
407 {"images/color_wheel.ico", false},
408 {"images/google_chrome.ico", false},
409 {"images/mandrill.wbmp", true},
410 {"images/grayscale.jpg", true},
411 {"images/grayscale.png", true},
412 };
413 for (auto& rec : recs) {
414 auto gen = make_generator(rec.fPath, r);
415 if (!gen) continue;
416
417 SkImageInfo info = gen->getInfo();
418 if (rec.fGrayscale) {
419 REPORTER_ASSERT(r, info.colorType() == kGray_8_SkColorType);
420 REPORTER_ASSERT(r, info.alphaType() == kOpaque_SkAlphaType);
421 } else {
422 info = info.makeColorType(kGray_8_SkColorType);
423 }
424 SkBitmap bm;
425 bm.allocPixels(info);
426 bool success = gen->getPixels(bm.pixmap());
427 if (success != rec.fGrayscale) {
428 ERRORF(r, "Expected decoding %s to Gray8 to %s. Actual: %s\n", rec.fPath,
429 (rec.fGrayscale ? "succeed" : "fail"), (success ? "succeed" : "fail"));
430 }
431 }
432}
433
434DEF_TEST(NdkDecode_Opaque_and_565, r) {
435 for (const char* path: {
436 "images/CMYK.jpg",
437 "images/dog.jpg",
438 "images/ducky.jpg",
439 "images/arrow.png",
440 "images/example_1.png",
441 "images/explosion_sprites.png",
442 "images/lut_identity.png",
443 "images/grayscale.png",
444 "images/baby_tux.webp",
445 "images/yellow_rose.webp",
446 "images/webp-color-profile-lossless.webp",
447 "images/colorTables.gif",
448 "images/color_wheel.gif",
449 "images/flightAnim.gif",
450 "images/randPixels.gif",
451 "images/rle.bmp",
452 "images/color_wheel.ico",
453 "images/google_chrome.ico",
454 "images/mandrill.wbmp",
455 }) {
456 auto gen = make_generator(path, r);
457 if (!gen) continue;
458
459 auto info = gen->getInfo().makeAlphaType(kOpaque_SkAlphaType);
460 SkBitmap bm;
461 bm.allocPixels(info);
462 bool success = gen->getPixels(bm.pixmap());
463 REPORTER_ASSERT(r, success == gen->getInfo().isOpaque());
464
465 info = info.makeColorType(kRGB_565_SkColorType);
466 bm.allocPixels(info);
467 success = gen->getPixels(bm.pixmap());
468 REPORTER_ASSERT(r, success == gen->getInfo().isOpaque());
469 }
470}
471
472DEF_TEST(NdkDecode_AlwaysSupportedColorTypes, r) {
473 for (const char* path: {
474 "images/CMYK.jpg",
475 "images/dog.jpg",
476 "images/ducky.jpg",
477 "images/arrow.png",
478 "images/example_1.png",
479 "images/explosion_sprites.png",
480 "images/lut_identity.png",
481 "images/grayscale.png",
482 "images/baby_tux.webp",
483 "images/yellow_rose.webp",
484 "images/webp-color-profile-lossless.webp",
485 "images/colorTables.gif",
486 "images/color_wheel.gif",
487 "images/flightAnim.gif",
488 "images/randPixels.gif",
489 "images/rle.bmp",
490 "images/color_wheel.ico",
491 "images/google_chrome.ico",
492 "images/mandrill.wbmp",
493 }) {
494 auto gen = make_generator(path, r);
495 if (!gen) continue;
496
497 auto info = gen->getInfo().makeColorType(kRGBA_F16_SkColorType);
498 SkBitmap bm;
499 bm.allocPixels(info);
500 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
501
502 // This also tests that we can reuse the same generator for a different
503 // color type.
504 info = info.makeColorType(kRGBA_8888_SkColorType);
505 bm.allocPixels(info);
506 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
507 }
508}
509
510DEF_TEST(NdkDecode_UnsupportedColorTypes, r) {
511 for (const char* path: {
512 "images/CMYK.jpg",
513 "images/dog.jpg",
514 "images/ducky.jpg",
515 "images/arrow.png",
516 "images/example_1.png",
517 "images/explosion_sprites.png",
518 "images/lut_identity.png",
519 "images/grayscale.png",
520 "images/baby_tux.webp",
521 "images/yellow_rose.webp",
522 "images/webp-color-profile-lossless.webp",
523 "images/colorTables.gif",
524 "images/color_wheel.gif",
525 "images/flightAnim.gif",
526 "images/randPixels.gif",
527 "images/rle.bmp",
528 "images/color_wheel.ico",
529 "images/google_chrome.ico",
530 "images/mandrill.wbmp",
531 }) {
532 auto gen = make_generator(path, r);
533 if (!gen) continue;
534
535 for (SkColorType ct : {
553 }) {
554 auto info = gen->getInfo().makeColorType(ct);
555 SkBitmap bm;
556 bm.allocPixels(info);
557 if (gen->getPixels(bm.pixmap())) {
558 ERRORF(r, "Expected decoding %s to %i to fail!", path, ct);
559 }
560 }
561 }
562}
563#endif // SK_ENABLE_NDK_IMAGES
SkPath fPath
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
kUnpremul_SkAlphaType
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition Resources.cpp:42
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
SkColorType
Definition SkColorType.h:19
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
Definition SkColorType.h:50
@ kBGR_101010x_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word
Definition SkColorType.h:30
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition SkColorType.h:23
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
Definition SkColorType.h:43
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition SkColorType.h:26
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
Definition SkColorType.h:48
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition SkColorType.h:38
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition SkColorType.h:21
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
Definition SkColorType.h:29
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition SkColorType.h:25
@ kBGRA_1010102_SkColorType
10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
Definition SkColorType.h:28
@ kA16_float_SkColorType
pixel with a half float for alpha
Definition SkColorType.h:45
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition SkColorType.h:40
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition SkColorType.h:27
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
Definition SkColorType.h:49
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition SkColorType.h:36
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition SkColorType.h:46
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
static constexpr skcms_TransferFunction k2Dot6
static constexpr skcms_Matrix3x3 kDCIP3
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define ERRORF(r,...)
Definition Test.h:293
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition SkBitmap.cpp:258
const SkPixmap & pixmap() const
Definition SkBitmap.h:133
void eraseColor(SkColor4f) const
Definition SkBitmap.cpp:442
static bool Equals(const SkColorSpace *, const SkColorSpace *)
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
static sk_sp< SkColorSpace > MakeSRGBLinear()
uint32_t uint32_t * format
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
static constexpr skcms_Matrix3x3 kSRGB
static constexpr skcms_Matrix3x3 kAdobeRGB
static constexpr skcms_Matrix3x3 kXYZ
static constexpr skcms_Matrix3x3 kRec2020
static constexpr skcms_Matrix3x3 kDisplayP3
static constexpr skcms_TransferFunction kRec2020
static constexpr skcms_TransferFunction k2Dot2
static constexpr skcms_TransferFunction kSRGB
static constexpr skcms_TransferFunction kHLG
static constexpr skcms_TransferFunction kPQ
static constexpr skcms_TransferFunction kLinear
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
bool equal_pixels(const SkPixmap &a, const SkPixmap &b)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
Definition gen.py:1
int32_t height
int32_t width
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)