blob: 6ceffc9b9c7749d23c8ec527e14fd8b49d0b6abc [file] [log] [blame]
halcanarydecb21e2015-12-10 07:52:45 -08001/*
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
Hal Canary169f37f2017-02-15 10:20:30 -05008#include <cstdio>
9#include <cstdlib>
10#include <sstream>
Joe Gregorio1fd18232017-02-13 11:39:43 -050011#include <string>
halcanarydecb21e2015-12-10 07:52:45 -080012
Joe Gregorio1e735c02017-04-19 14:05:14 -040013#include "SkCommandLineFlags.h"
14
halcanarydecb21e2015-12-10 07:52:45 -080015#include "fiddle_main.h"
16
Joe Gregorio1e735c02017-04-19 14:05:14 -040017DEFINE_double(duration, 1.0, "The total duration, in seconds, of the animation we are drawing.");
18DEFINE_double(frame, 1.0, "A double value in [0, 1] that specifies the point in animation to draw.");
19
halcanarydecb21e2015-12-10 07:52:45 -080020// Globals externed in fiddle_main.h
21SkBitmap source;
halcanary7b8b2372016-04-18 08:17:56 -070022sk_sp<SkImage> image;
Joe Gregorio1e735c02017-04-19 14:05:14 -040023double duration; // The total duration of the animation in seconds.
24double frame; // A value in [0, 1] of where we are in the animation.
halcanarydecb21e2015-12-10 07:52:45 -080025
Hal Canary169f37f2017-02-15 10:20:30 -050026// Global used by the local impl of SkDebugf.
27std::ostringstream gTextOutput;
Joe Gregorio1fd18232017-02-13 11:39:43 -050028
Joe Gregorio97b10ac2017-06-01 13:24:11 -040029// Global to record the GL driver info via create_grcontext().
30std::ostringstream gGLDriverInfo;
31
Joe Gregorio1fd18232017-02-13 11:39:43 -050032void SkDebugf(const char * fmt, ...) {
Joe Gregorio1fd18232017-02-13 11:39:43 -050033 va_list args;
34 va_start(args, fmt);
Hal Canary169f37f2017-02-15 10:20:30 -050035 char formatbuffer[1024];
36 int n = vsnprintf(formatbuffer, sizeof(formatbuffer), fmt, args);
Joe Gregorio1fd18232017-02-13 11:39:43 -050037 va_end(args);
38 if (n>=0 && n<=int(sizeof(formatbuffer))) {
Hal Canary169f37f2017-02-15 10:20:30 -050039 gTextOutput.write(formatbuffer, n);
Joe Gregorio1fd18232017-02-13 11:39:43 -050040 }
41}
42
halcanarydecb21e2015-12-10 07:52:45 -080043static void encode_to_base64(const void* data, size_t size, FILE* out) {
44 const uint8_t* input = reinterpret_cast<const uint8_t*>(data);
45 const uint8_t* end = &input[size];
46 static const char codes[] =
47 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
48 "abcdefghijklmnopqrstuvwxyz0123456789+/";
49 while (input != end) {
50 uint8_t b = (*input & 0xFC) >> 2;
51 fputc(codes[b], out);
52 b = (*input & 0x03) << 4;
53 ++input;
54 if (input == end) {
55 fputc(codes[b], out);
56 fputs("==", out);
57 return;
58 }
59 b |= (*input & 0xF0) >> 4;
60 fputc(codes[b], out);
61 b = (*input & 0x0F) << 2;
62 ++input;
63 if (input == end) {
64 fputc(codes[b], out);
65 fputc('=', out);
66 return;
67 }
68 b |= (*input & 0xC0) >> 6;
69 fputc(codes[b], out);
70 b = *input & 0x3F;
71 fputc(codes[b], out);
72 ++input;
73 }
74}
75
Hal Canary169f37f2017-02-15 10:20:30 -050076
77static void dump_output(const void* data, size_t size,
78 const char* name, bool last = true) {
79 printf("\t\"%s\": \"", name);
80 encode_to_base64(data, size, stdout);
81 fputs(last ? "\"\n" : "\",\n", stdout);
82}
83
halcanaryd0964592016-03-25 11:29:34 -070084static void dump_output(const sk_sp<SkData>& data,
85 const char* name, bool last = true) {
halcanarydecb21e2015-12-10 07:52:45 -080086 if (data) {
Hal Canary169f37f2017-02-15 10:20:30 -050087 dump_output(data->data(), data->size(), name, last);
halcanarydecb21e2015-12-10 07:52:45 -080088 }
89}
90
Mike Reed6409f842017-07-11 16:03:13 -040091static sk_sp<SkData> encode_snapshot(const sk_sp<SkSurface>& surface) {
halcanary7b8b2372016-04-18 08:17:56 -070092 sk_sp<SkImage> img(surface->makeImageSnapshot());
Mike Reed6409f842017-07-11 16:03:13 -040093 return img ? img->encodeToData() : nullptr;
halcanarydecb21e2015-12-10 07:52:45 -080094}
95
Joe Gregorio4f12f1e2017-06-14 15:54:32 -040096static SkCanvas* prepare_canvas(SkCanvas * canvas) {
97 canvas->clear(SK_ColorWHITE);
98 return canvas;
99}
100
Joe Gregorio1e735c02017-04-19 14:05:14 -0400101int main(int argc, char** argv) {
102 SkCommandLineFlags::Parse(argc, argv);
103 duration = FLAGS_duration;
104 frame = FLAGS_frame;
Joe Gregorio1fd18232017-02-13 11:39:43 -0500105 DrawOptions options = GetDrawOptions();
106 // If textOnly then only do one type of image, otherwise the text
107 // output is duplicated for each type.
108 if (options.textOnly) {
109 options.raster = true;
110 options.gpu = false;
111 options.pdf = false;
112 options.skp = false;
113 }
halcanarydecb21e2015-12-10 07:52:45 -0800114 if (options.source) {
bungeman38d909e2016-08-02 14:40:46 -0700115 sk_sp<SkData> data(SkData::MakeFromFileName(options.source));
halcanarydecb21e2015-12-10 07:52:45 -0800116 if (!data) {
117 perror(options.source);
118 return 1;
119 } else {
halcanary7b8b2372016-04-18 08:17:56 -0700120 image = SkImage::MakeFromEncoded(std::move(data));
halcanarydecb21e2015-12-10 07:52:45 -0800121 if (!image) {
122 perror("Unable to decode the source image.");
123 return 1;
124 }
125 SkAssertResult(image->asLegacyBitmap(
126 &source, SkImage::kRO_LegacyBitmapMode));
127 }
128 }
halcanaryd0964592016-03-25 11:29:34 -0700129 sk_sp<SkData> rasterData, gpuData, pdfData, skpData;
Matt Saretta2f71262016-11-29 17:14:58 -0500130 SkColorType colorType = kN32_SkColorType;
131 sk_sp<SkColorSpace> colorSpace = nullptr;
132 if (options.f16) {
133 SkASSERT(options.srgb);
134 colorType = kRGBA_F16_SkColorType;
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500135 colorSpace = SkColorSpace::MakeSRGBLinear();
Matt Saretta2f71262016-11-29 17:14:58 -0500136 } else if (options.srgb) {
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500137 colorSpace = SkColorSpace::MakeSRGB();
Matt Saretta2f71262016-11-29 17:14:58 -0500138 }
139 SkImageInfo info = SkImageInfo::Make(options.size.width(), options.size.height(), colorType,
140 kPremul_SkAlphaType, colorSpace);
halcanarydecb21e2015-12-10 07:52:45 -0800141 if (options.raster) {
Matt Saretta2f71262016-11-29 17:14:58 -0500142 auto rasterSurface = SkSurface::MakeRaster(info);
halcanaryf0270c32016-05-23 09:02:38 -0700143 srand(0);
Joe Gregorio4f12f1e2017-06-14 15:54:32 -0400144 draw(prepare_canvas(rasterSurface->getCanvas()));
Mike Reed6409f842017-07-11 16:03:13 -0400145 rasterData = encode_snapshot(rasterSurface);
halcanarydecb21e2015-12-10 07:52:45 -0800146 }
147 if (options.gpu) {
Joe Gregorio97b10ac2017-06-01 13:24:11 -0400148 auto grContext = create_grcontext(gGLDriverInfo);
halcanarydecb21e2015-12-10 07:52:45 -0800149 if (!grContext) {
mtklein7d10b9f2016-07-27 11:17:18 -0700150 fputs("Unable to get GrContext.\n", stderr);
halcanarydecb21e2015-12-10 07:52:45 -0800151 } else {
Matt Saretta2f71262016-11-29 17:14:58 -0500152 auto surface = SkSurface::MakeRenderTarget(grContext.get(), SkBudgeted::kNo, info);
halcanarydecb21e2015-12-10 07:52:45 -0800153 if (!surface) {
154 fputs("Unable to get render surface.\n", stderr);
155 exit(1);
156 }
halcanaryf0270c32016-05-23 09:02:38 -0700157 srand(0);
Joe Gregorio4f12f1e2017-06-14 15:54:32 -0400158 draw(prepare_canvas(surface->getCanvas()));
Mike Reed6409f842017-07-11 16:03:13 -0400159 gpuData = encode_snapshot(surface);
halcanarydecb21e2015-12-10 07:52:45 -0800160 }
halcanarydecb21e2015-12-10 07:52:45 -0800161 }
162 if (options.pdf) {
163 SkDynamicMemoryWStream pdfStream;
halcanary676ab682016-05-03 12:10:04 -0700164 sk_sp<SkDocument> document(SkDocument::MakePDF(&pdfStream));
mtkleincd01b032016-08-31 04:58:19 -0700165 if (document) {
166 srand(0);
Joe Gregorio4f12f1e2017-06-14 15:54:32 -0400167 draw(prepare_canvas(document->beginPage(options.size.width(), options.size.height())));
mtkleincd01b032016-08-31 04:58:19 -0700168 document->close();
reed42943c82016-09-12 12:01:44 -0700169 pdfData = pdfStream.detachAsData();
mtkleincd01b032016-08-31 04:58:19 -0700170 }
halcanarydecb21e2015-12-10 07:52:45 -0800171 }
172 if (options.skp) {
173 SkSize size;
174 size = options.size;
175 SkPictureRecorder recorder;
halcanaryf0270c32016-05-23 09:02:38 -0700176 srand(0);
Joe Gregorio4f12f1e2017-06-14 15:54:32 -0400177 draw(prepare_canvas(recorder.beginRecording(size.width(), size.height())));
halcanaryd0964592016-03-25 11:29:34 -0700178 auto picture = recorder.finishRecordingAsPicture();
halcanarydecb21e2015-12-10 07:52:45 -0800179 SkDynamicMemoryWStream skpStream;
180 picture->serialize(&skpStream);
reed42943c82016-09-12 12:01:44 -0700181 skpData = skpStream.detachAsData();
halcanarydecb21e2015-12-10 07:52:45 -0800182 }
183
184 printf("{\n");
Joe Gregorio0236cba2017-02-13 13:55:17 -0500185 if (!options.textOnly) {
Joe Gregorio97b10ac2017-06-01 13:24:11 -0400186 dump_output(rasterData, "Raster", false);
187 dump_output(gpuData, "Gpu", false);
188 dump_output(pdfData, "Pdf", false);
189 dump_output(skpData, "Skp", false);
Joe Gregorio0236cba2017-02-13 13:55:17 -0500190 } else {
Hal Canary169f37f2017-02-15 10:20:30 -0500191 std::string textoutput = gTextOutput.str();
Joe Gregorio97b10ac2017-06-01 13:24:11 -0400192 dump_output(textoutput.c_str(), textoutput.length(), "Text", false);
Joe Gregorio0236cba2017-02-13 13:55:17 -0500193 }
Joe Gregorio97b10ac2017-06-01 13:24:11 -0400194 std::string glinfo = gGLDriverInfo.str();
195 dump_output(glinfo.c_str(), glinfo.length(), "GLInfo", true);
halcanarydecb21e2015-12-10 07:52:45 -0800196 printf("}\n");
197
halcanarydecb21e2015-12-10 07:52:45 -0800198 return 0;
199}