Flutter Engine
The Flutter Engine
fiddle_main.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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 <cstdio>
9#include <cstdlib>
10#include <sstream>
11#include <string>
12
14#include "src/core/SkMemset.h"
15#include "src/core/SkMipmap.h"
17
19
21 "The total duration, in seconds, of the animation we are drawing.");
22static DEFINE_double(frame, 1.0,
23 "A double value in [0, 1] that specifies the point in animation to draw.");
24
38
39#if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
41#endif
42
43using namespace skia_private;
44
45// Globals externed in fiddle_main.h
51double duration; // The total duration of the animation in seconds.
52double frame; // A value in [0, 1] of where we are in the animation.
54
55// Global used by the local impl of SkDebugf.
56std::ostringstream gTextOutput;
57
58// Global to record the GL driver info via create_direct_context().
59std::ostringstream gGLDriverInfo;
60
64
65void SkDebugf(const char * fmt, ...) {
66 va_list args;
68 char formatbuffer[1024];
69 int n = vsnprintf(formatbuffer, sizeof(formatbuffer), fmt, args);
70 va_end(args);
71 if (n>=0 && n<=int(sizeof(formatbuffer))) {
72 gTextOutput.write(formatbuffer, n);
73 }
74}
75
76static void encode_to_base64(const void* data, size_t size, FILE* out) {
77 const uint8_t* input = reinterpret_cast<const uint8_t*>(data);
78 const uint8_t* end = &input[size];
79 static const char codes[] =
80 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
81 "abcdefghijklmnopqrstuvwxyz0123456789+/";
82 while (input != end) {
83 uint8_t b = (*input & 0xFC) >> 2;
84 fputc(codes[b], out);
85 b = (*input & 0x03) << 4;
86 ++input;
87 if (input == end) {
88 fputc(codes[b], out);
89 fputs("==", out);
90 return;
91 }
92 b |= (*input & 0xF0) >> 4;
93 fputc(codes[b], out);
94 b = (*input & 0x0F) << 2;
95 ++input;
96 if (input == end) {
97 fputc(codes[b], out);
98 fputc('=', out);
99 return;
100 }
101 b |= (*input & 0xC0) >> 6;
102 fputc(codes[b], out);
103 b = *input & 0x3F;
104 fputc(codes[b], out);
105 ++input;
106 }
107}
108
109
110static void dump_output(const void* data, size_t size,
111 const char* name, bool last = true) {
112 printf("\t\"%s\": \"", name);
113 encode_to_base64(data, size, stdout);
114 fputs(last ? "\"\n" : "\",\n", stdout);
115}
116
117static void dump_output(const sk_sp<SkData>& data,
118 const char* name, bool last = true) {
119 if (data) {
120 dump_output(data->data(), data->size(), name, last);
121 }
122}
123
125 sk_sp<SkImage> img(surface->makeImageSnapshot());
126 return SkPngEncoder::Encode(ctx, img.get(), {});
127}
128
130 canvas->clear(SK_ColorWHITE);
131 return canvas;
132}
133
134#ifdef SK_GL
135static bool setup_backend_objects(GrDirectContext* dContext,
136 const SkBitmap& bm,
137 const DrawOptions& options) {
138 if (!dContext) {
139 fputs("Context is null.\n", stderr);
140 return false;
141 }
142
143 // This config must match the SkColorType used in draw.cpp in the SkImage and Surface factories
146
147 if (!bm.empty()) {
148 SkPixmap originalPixmap;
149 SkPixmap* pixmap = &originalPixmap;
150 if (!bm.peekPixels(&originalPixmap)) {
151 fputs("Unable to peekPixels.\n", stderr);
152 return false;
153 }
154
155 SkAutoPixmapStorage rgbaPixmap;
156 constexpr bool kRGBAIsNative = kN32_SkColorType == kRGBA_8888_SkColorType;
157 if ((!kRGBAIsNative)) {
158 if (!rgbaPixmap.tryAlloc(bm.info().makeColorType(kRGBA_8888_SkColorType))) {
159 fputs("Unable to alloc rgbaPixmap.\n", stderr);
160 return false;
161 }
162 if (!bm.readPixels(rgbaPixmap)) {
163 fputs("Unable to read rgbaPixmap.\n", stderr);
164 return false;
165 }
166 pixmap = &rgbaPixmap;
167 }
168
169 managedBackendTexture = sk_gpu_test::ManagedBackendTexture::MakeFromPixmap(
170 dContext,
171 *pixmap,
172 options.fMipMapping,
176 fputs("Failed to create backEndTexture.\n", stderr);
177 return false;
178 }
180 }
181
182 {
183 auto resourceProvider = dContext->priv().resourceProvider();
184
185 SkISize offscreenDims = {options.fOffScreenWidth, options.fOffScreenHeight};
186 AutoTMalloc<uint32_t> data(offscreenDims.area());
187 SkOpts::memset32(data.get(), 0, offscreenDims.area());
188
189 // This backend object should be renderable but not textureable. Given the limitations
190 // of how we're creating it though it will wind up being secretly textureable.
191 // We use this fact to initialize it with data but don't allow mipmaps
192 GrMipLevel level0 = {data.get(), offscreenDims.width()*sizeof(uint32_t), nullptr};
193
194 constexpr int kSampleCnt = 1;
195 sk_sp<GrTexture> tmp =
196 resourceProvider->createTexture(offscreenDims,
197 renderableFormat,
201 kSampleCnt,
205 &level0,
206 /*label=*/"Fiddle_SetupBackendObjects");
207 if (!tmp || !tmp->asRenderTarget()) {
208 fputs("GrTexture is invalid.\n", stderr);
209 return false;
210 }
211
213
214 backEndRenderTarget = backingRenderTarget->getBackendRenderTarget();
216 fputs("BackEndRenderTarget is invalid.\n", stderr);
217 return false;
218 }
219 }
220
221 {
223 dContext,
224 options.fOffScreenWidth,
225 options.fOffScreenHeight,
226 renderableFormat,
228 options.fOffScreenMipMapping,
232 fputs("Failed to create backendTextureRenderTarget.\n", stderr);
233 return false;
234 }
236 }
237
238 return true;
239}
240#endif
241
242int main(int argc, char** argv) {
244 duration = FLAGS_duration;
245 frame = FLAGS_frame;
247 // If textOnly then only do one type of image, otherwise the text
248 // output is duplicated for each type.
249 if (options.textOnly) {
250 options.raster = true;
251 options.gpu = false;
252 options.pdf = false;
253 options.skp = false;
254 }
255#if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
257#else
259#endif
260 if (options.source) {
262 if (!data) {
263 perror(options.source);
264 return 1;
265 }
266 std::unique_ptr<SkCodec> codec = nullptr;
267 if (SkPngDecoder::IsPng(data->data(), data->size())) {
268 codec = SkPngDecoder::Decode(data, nullptr);
269 } else if (SkJpegDecoder::IsJpeg(data->data(), data->size())) {
270 codec = SkJpegDecoder::Decode(data, nullptr);
271 } else {
272 perror("Unsupported file format\n");
273 return 1;
274 }
275 if (!codec) {
276 perror("Corrupt source image file\n");
277 return 1;
278 }
279 image = std::get<0>(codec->getImage());
280 if (!image) {
281 perror("Unable to decode the source image.\n");
282 return 1;
283 }
285 }
286 sk_sp<SkData> rasterData, gpuData, pdfData, skpData;
287 SkColorType colorType = kN32_SkColorType;
288 sk_sp<SkColorSpace> colorSpace = nullptr;
289 if (options.f16) {
290 SkASSERT(options.srgb);
292 colorSpace = SkColorSpace::MakeSRGBLinear();
293 } else if (options.srgb) {
294 colorSpace = SkColorSpace::MakeSRGB();
295 }
296 SkImageInfo info = SkImageInfo::Make(options.size.width(), options.size.height(), colorType,
297 kPremul_SkAlphaType, colorSpace);
298 if (options.raster) {
299 auto rasterSurface = SkSurfaces::Raster(info);
300 srand(0);
301 draw(prepare_canvas(rasterSurface->getCanvas()));
302 rasterData = encode_snapshot(nullptr, rasterSurface);
303 }
304#ifdef SK_GL
305 if (options.gpu) {
306 std::unique_ptr<sk_gpu_test::GLTestContext> glContext;
308 if (!direct) {
309 fputs("Unable to get GrContext.\n", stderr);
310 } else {
311 if (!setup_backend_objects(direct.get(), source, options)) {
312 fputs("Unable to create backend objects.\n", stderr);
313 exit(1);
314 }
315
317 if (!surface) {
318 fputs("Unable to get render surface.\n", stderr);
319 exit(1);
320 }
321 srand(0);
322 draw(prepare_canvas(surface->getCanvas()));
323 gpuData = encode_snapshot(direct.get(), surface);
324 }
325 }
326#endif
327
328#ifdef SK_SUPPORT_PDF
329 if (options.pdf) {
330 SkDynamicMemoryWStream pdfStream;
331 auto document = SkPDF::MakeDocument(&pdfStream);
332 if (document) {
333 srand(0);
334 draw(prepare_canvas(document->beginPage(options.size.width(), options.size.height())));
335 document->close();
336 pdfData = pdfStream.detachAsData();
337 }
338 }
339#endif
340
341 if (options.skp) {
342 auto size = SkSize::Make(options.size);
343 SkPictureRecorder recorder;
344 srand(0);
345 draw(prepare_canvas(recorder.beginRecording(size.width(), size.height())));
346 auto picture = recorder.finishRecordingAsPicture();
347 SkDynamicMemoryWStream skpStream;
348 picture->serialize(&skpStream);
349 skpData = skpStream.detachAsData();
350 }
351
352 printf("{\n");
353 if (!options.textOnly) {
354 dump_output(rasterData, "Raster", false);
355 dump_output(gpuData, "Gpu", false);
356 dump_output(pdfData, "Pdf", false);
357 dump_output(skpData, "Skp", false);
358 } else {
359 std::string textoutput = gTextOutput.str();
360 dump_output(textoutput.c_str(), textoutput.length(), "Text", false);
361 }
362 std::string glinfo = gGLDriverInfo.str();
363 dump_output(glinfo.c_str(), glinfo.length(), "GLInfo", true);
364 printf("}\n");
365
366 return 0;
367}
const char * options
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorType
Definition: SkColorType.h:19
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
SK_API sk_sp< SkFontMgr > SkFontMgr_New_FontConfig(FcConfig *fc)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
static void Parse(int argc, const char *const *argv)
SK_API GrBackendFormat defaultBackendFormat(SkColorType, GrRenderable) const
GrResourceProvider * resourceProvider()
GrDirectContextPriv priv()
virtual GrRenderTarget * asRenderTarget()
Definition: GrSurface.h:65
bool tryAlloc(const SkImageInfo &)
bool empty() const
Definition: SkBitmap.h:210
const SkImageInfo & info() const
Definition: SkBitmap.h:139
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY) const
Definition: SkBitmap.cpp:488
bool peekPixels(SkPixmap *pixmap) const
Definition: SkBitmap.cpp:635
void clear(SkColor color)
Definition: SkCanvas.h:1199
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkColorSpace > MakeSRGBLinear()
static sk_sp< SkData > MakeFromFileName(const char path[])
Definition: SkData.cpp:148
sk_sp< SkData > detachAsData()
Definition: SkStream.cpp:707
static sk_sp< SkFontMgr > RefEmpty()
Definition: SkFontMgr.cpp:154
bool asLegacyBitmap(SkBitmap *bitmap, LegacyBitmapMode legacyBitmapMode=kRO_LegacyBitmapMode) const
Definition: SkImage.cpp:233
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
T * get() const
Definition: SkRefCnt.h:303
DrawOptions GetDrawOptions()
Definition: draw.cpp:16
sk_sp< GrDirectContext > create_direct_context(std::ostringstream &driverinfo, std::unique_ptr< sk_gpu_test::GLTestContext > *glContext)
Definition: egl_context.cpp:20
VkSurfaceKHR surface
Definition: main.cc:49
static bool b
sk_sp< SkFontMgr > fontMgr
Definition: fiddle_main.cpp:53
GrBackendTexture backEndTextureRenderTarget
Definition: fiddle_main.cpp:48
static sk_sp< SkData > encode_snapshot(GrDirectContext *ctx, const sk_sp< SkSurface > &surface)
static SkCanvas * prepare_canvas(SkCanvas *canvas)
static void dump_output(const void *data, size_t size, const char *name, bool last=true)
sk_sp< SkImage > image
Definition: fiddle_main.cpp:50
int main(int argc, char **argv)
std::ostringstream gTextOutput
Definition: fiddle_main.cpp:56
sk_sp< sk_gpu_test::ManagedBackendTexture > managedBackendTexture
Definition: fiddle_main.cpp:62
SkBitmap source
Definition: fiddle_main.cpp:49
void SkDebugf(const char *fmt,...)
Definition: fiddle_main.cpp:65
GrBackendRenderTarget backEndRenderTarget
Definition: fiddle_main.cpp:47
sk_sp< GrRenderTarget > backingRenderTarget
Definition: fiddle_main.cpp:63
GrBackendTexture backEndTexture
Definition: fiddle_main.cpp:46
sk_sp< sk_gpu_test::ManagedBackendTexture > managedBackendTextureRenderTarget
Definition: fiddle_main.cpp:61
double duration
Definition: fiddle_main.cpp:51
static DEFINE_double(duration, 1.0, "The total duration, in seconds, of the animation we are drawing.")
std::ostringstream gGLDriverInfo
Definition: fiddle_main.cpp:59
double frame
Definition: fiddle_main.cpp:52
static void encode_to_base64(const void *data, size_t size, FILE *out)
Definition: fiddle_main.cpp:76
glong glong end
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
char ** argv
Definition: library.h:9
constexpr SkColor4f kTransparent
Definition: SkColor.h:434
SK_API bool IsJpeg(const void *, size_t)
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
SK_API sk_sp< SkPixelRef > MakeWithData(const SkImageInfo &, size_t rowBytes, sk_sp< SkData > data)
void(* memset32)(uint32_t[], uint32_t, int)
SK_API sk_sp< SkDocument > MakeDocument(SkWStream *stream, const Metadata &metadata)
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
SK_API bool IsPng(const void *, size_t)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
sk_sp< const SkPicture > picture
Definition: SkRecords.h:299
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: SkSLString.cpp:83
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
va_start(args, format)
exit(kErrorExitCode)
va_end(args)
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
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< 0 >(const myers::Segment &s)
Definition: Myers.h:80
static SkString fmt(SkColor4f c)
Definition: p3.cpp:43
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int64_t area() const
Definition: SkSize.h:39
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkImageInfo makeColorType(SkColorType newColorType) const
Definition: SkImageInfo.h:475
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition: SkSize.h:56
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63