1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include <cstdio>
9*c8dee2aaSAndroid Build Coastguard Worker #include <cstdlib>
10*c8dee2aaSAndroid Build Coastguard Worker #include <sstream>
11*c8dee2aaSAndroid Build Coastguard Worker #include <string>
12*c8dee2aaSAndroid Build Coastguard Worker
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkAutoPixmapStorage.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMemset.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMipmap.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "tools/flags/CommandLineFlags.h"
17*c8dee2aaSAndroid Build Coastguard Worker
18*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fiddle/fiddle_main.h"
19*c8dee2aaSAndroid Build Coastguard Worker
20*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_double(duration, 1.0,
21*c8dee2aaSAndroid Build Coastguard Worker "The total duration, in seconds, of the animation we are drawing.");
22*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_double(frame, 1.0,
23*c8dee2aaSAndroid Build Coastguard Worker "A double value in [0, 1] that specifies the point in animation to draw.");
24*c8dee2aaSAndroid Build Coastguard Worker
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkJpegDecoder.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkPngDecoder.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/encode/SkPngEncoder.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpu.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTarget.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProvider.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTexture.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ManagedBackendTexture.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/gl/GLTestContext.h"
38*c8dee2aaSAndroid Build Coastguard Worker
39*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
40*c8dee2aaSAndroid Build Coastguard Worker #include "include/ports/SkFontMgr_fontconfig.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "include/ports/SkFontScanner_FreeType.h"
42*c8dee2aaSAndroid Build Coastguard Worker #endif
43*c8dee2aaSAndroid Build Coastguard Worker
44*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
45*c8dee2aaSAndroid Build Coastguard Worker
46*c8dee2aaSAndroid Build Coastguard Worker // Globals externed in fiddle_main.h
47*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture backEndTexture;
48*c8dee2aaSAndroid Build Coastguard Worker GrBackendRenderTarget backEndRenderTarget;
49*c8dee2aaSAndroid Build Coastguard Worker GrBackendTexture backEndTextureRenderTarget;
50*c8dee2aaSAndroid Build Coastguard Worker SkBitmap source;
51*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> image;
52*c8dee2aaSAndroid Build Coastguard Worker double duration; // The total duration of the animation in seconds.
53*c8dee2aaSAndroid Build Coastguard Worker double frame; // A value in [0, 1] of where we are in the animation.
54*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFontMgr> fontMgr;
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker // Global used by the local impl of SkDebugf.
57*c8dee2aaSAndroid Build Coastguard Worker std::ostringstream gTextOutput;
58*c8dee2aaSAndroid Build Coastguard Worker
59*c8dee2aaSAndroid Build Coastguard Worker // Global to record the GL driver info via create_direct_context().
60*c8dee2aaSAndroid Build Coastguard Worker std::ostringstream gGLDriverInfo;
61*c8dee2aaSAndroid Build Coastguard Worker
62*c8dee2aaSAndroid Build Coastguard Worker sk_sp<sk_gpu_test::ManagedBackendTexture> managedBackendTextureRenderTarget;
63*c8dee2aaSAndroid Build Coastguard Worker sk_sp<sk_gpu_test::ManagedBackendTexture> managedBackendTexture;
64*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrRenderTarget> backingRenderTarget;
65*c8dee2aaSAndroid Build Coastguard Worker
SkDebugf(const char * fmt,...)66*c8dee2aaSAndroid Build Coastguard Worker void SkDebugf(const char * fmt, ...) {
67*c8dee2aaSAndroid Build Coastguard Worker va_list args;
68*c8dee2aaSAndroid Build Coastguard Worker va_start(args, fmt);
69*c8dee2aaSAndroid Build Coastguard Worker char formatbuffer[1024];
70*c8dee2aaSAndroid Build Coastguard Worker int n = vsnprintf(formatbuffer, sizeof(formatbuffer), fmt, args);
71*c8dee2aaSAndroid Build Coastguard Worker va_end(args);
72*c8dee2aaSAndroid Build Coastguard Worker if (n>=0 && n<=int(sizeof(formatbuffer))) {
73*c8dee2aaSAndroid Build Coastguard Worker gTextOutput.write(formatbuffer, n);
74*c8dee2aaSAndroid Build Coastguard Worker }
75*c8dee2aaSAndroid Build Coastguard Worker }
76*c8dee2aaSAndroid Build Coastguard Worker
encode_to_base64(const void * data,size_t size,FILE * out)77*c8dee2aaSAndroid Build Coastguard Worker static void encode_to_base64(const void* data, size_t size, FILE* out) {
78*c8dee2aaSAndroid Build Coastguard Worker const uint8_t* input = reinterpret_cast<const uint8_t*>(data);
79*c8dee2aaSAndroid Build Coastguard Worker const uint8_t* end = &input[size];
80*c8dee2aaSAndroid Build Coastguard Worker static const char codes[] =
81*c8dee2aaSAndroid Build Coastguard Worker "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
82*c8dee2aaSAndroid Build Coastguard Worker "abcdefghijklmnopqrstuvwxyz0123456789+/";
83*c8dee2aaSAndroid Build Coastguard Worker while (input != end) {
84*c8dee2aaSAndroid Build Coastguard Worker uint8_t b = (*input & 0xFC) >> 2;
85*c8dee2aaSAndroid Build Coastguard Worker fputc(codes[b], out);
86*c8dee2aaSAndroid Build Coastguard Worker b = (*input & 0x03) << 4;
87*c8dee2aaSAndroid Build Coastguard Worker ++input;
88*c8dee2aaSAndroid Build Coastguard Worker if (input == end) {
89*c8dee2aaSAndroid Build Coastguard Worker fputc(codes[b], out);
90*c8dee2aaSAndroid Build Coastguard Worker fputs("==", out);
91*c8dee2aaSAndroid Build Coastguard Worker return;
92*c8dee2aaSAndroid Build Coastguard Worker }
93*c8dee2aaSAndroid Build Coastguard Worker b |= (*input & 0xF0) >> 4;
94*c8dee2aaSAndroid Build Coastguard Worker fputc(codes[b], out);
95*c8dee2aaSAndroid Build Coastguard Worker b = (*input & 0x0F) << 2;
96*c8dee2aaSAndroid Build Coastguard Worker ++input;
97*c8dee2aaSAndroid Build Coastguard Worker if (input == end) {
98*c8dee2aaSAndroid Build Coastguard Worker fputc(codes[b], out);
99*c8dee2aaSAndroid Build Coastguard Worker fputc('=', out);
100*c8dee2aaSAndroid Build Coastguard Worker return;
101*c8dee2aaSAndroid Build Coastguard Worker }
102*c8dee2aaSAndroid Build Coastguard Worker b |= (*input & 0xC0) >> 6;
103*c8dee2aaSAndroid Build Coastguard Worker fputc(codes[b], out);
104*c8dee2aaSAndroid Build Coastguard Worker b = *input & 0x3F;
105*c8dee2aaSAndroid Build Coastguard Worker fputc(codes[b], out);
106*c8dee2aaSAndroid Build Coastguard Worker ++input;
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker
110*c8dee2aaSAndroid Build Coastguard Worker
dump_output(const void * data,size_t size,const char * name,bool last=true)111*c8dee2aaSAndroid Build Coastguard Worker static void dump_output(const void* data, size_t size,
112*c8dee2aaSAndroid Build Coastguard Worker const char* name, bool last = true) {
113*c8dee2aaSAndroid Build Coastguard Worker printf("\t\"%s\": \"", name);
114*c8dee2aaSAndroid Build Coastguard Worker encode_to_base64(data, size, stdout);
115*c8dee2aaSAndroid Build Coastguard Worker fputs(last ? "\"\n" : "\",\n", stdout);
116*c8dee2aaSAndroid Build Coastguard Worker }
117*c8dee2aaSAndroid Build Coastguard Worker
dump_output(const sk_sp<SkData> & data,const char * name,bool last=true)118*c8dee2aaSAndroid Build Coastguard Worker static void dump_output(const sk_sp<SkData>& data,
119*c8dee2aaSAndroid Build Coastguard Worker const char* name, bool last = true) {
120*c8dee2aaSAndroid Build Coastguard Worker if (data) {
121*c8dee2aaSAndroid Build Coastguard Worker dump_output(data->data(), data->size(), name, last);
122*c8dee2aaSAndroid Build Coastguard Worker }
123*c8dee2aaSAndroid Build Coastguard Worker }
124*c8dee2aaSAndroid Build Coastguard Worker
encode_snapshot(GrDirectContext * ctx,const sk_sp<SkSurface> & surface)125*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkData> encode_snapshot(GrDirectContext* ctx, const sk_sp<SkSurface>& surface) {
126*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> img(surface->makeImageSnapshot());
127*c8dee2aaSAndroid Build Coastguard Worker return SkPngEncoder::Encode(ctx, img.get(), {});
128*c8dee2aaSAndroid Build Coastguard Worker }
129*c8dee2aaSAndroid Build Coastguard Worker
prepare_canvas(SkCanvas * canvas)130*c8dee2aaSAndroid Build Coastguard Worker static SkCanvas* prepare_canvas(SkCanvas * canvas) {
131*c8dee2aaSAndroid Build Coastguard Worker canvas->clear(SK_ColorWHITE);
132*c8dee2aaSAndroid Build Coastguard Worker return canvas;
133*c8dee2aaSAndroid Build Coastguard Worker }
134*c8dee2aaSAndroid Build Coastguard Worker
135*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
setup_backend_objects(GrDirectContext * dContext,const SkBitmap & bm,const DrawOptions & options)136*c8dee2aaSAndroid Build Coastguard Worker static bool setup_backend_objects(GrDirectContext* dContext,
137*c8dee2aaSAndroid Build Coastguard Worker const SkBitmap& bm,
138*c8dee2aaSAndroid Build Coastguard Worker const DrawOptions& options) {
139*c8dee2aaSAndroid Build Coastguard Worker if (!dContext) {
140*c8dee2aaSAndroid Build Coastguard Worker fputs("Context is null.\n", stderr);
141*c8dee2aaSAndroid Build Coastguard Worker return false;
142*c8dee2aaSAndroid Build Coastguard Worker }
143*c8dee2aaSAndroid Build Coastguard Worker
144*c8dee2aaSAndroid Build Coastguard Worker // This config must match the SkColorType used in draw.cpp in the SkImage and Surface factories
145*c8dee2aaSAndroid Build Coastguard Worker GrBackendFormat renderableFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
146*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes);
147*c8dee2aaSAndroid Build Coastguard Worker
148*c8dee2aaSAndroid Build Coastguard Worker if (!bm.empty()) {
149*c8dee2aaSAndroid Build Coastguard Worker SkPixmap originalPixmap;
150*c8dee2aaSAndroid Build Coastguard Worker SkPixmap* pixmap = &originalPixmap;
151*c8dee2aaSAndroid Build Coastguard Worker if (!bm.peekPixels(&originalPixmap)) {
152*c8dee2aaSAndroid Build Coastguard Worker fputs("Unable to peekPixels.\n", stderr);
153*c8dee2aaSAndroid Build Coastguard Worker return false;
154*c8dee2aaSAndroid Build Coastguard Worker }
155*c8dee2aaSAndroid Build Coastguard Worker
156*c8dee2aaSAndroid Build Coastguard Worker SkAutoPixmapStorage rgbaPixmap;
157*c8dee2aaSAndroid Build Coastguard Worker constexpr bool kRGBAIsNative = kN32_SkColorType == kRGBA_8888_SkColorType;
158*c8dee2aaSAndroid Build Coastguard Worker if ((!kRGBAIsNative)) {
159*c8dee2aaSAndroid Build Coastguard Worker if (!rgbaPixmap.tryAlloc(bm.info().makeColorType(kRGBA_8888_SkColorType))) {
160*c8dee2aaSAndroid Build Coastguard Worker fputs("Unable to alloc rgbaPixmap.\n", stderr);
161*c8dee2aaSAndroid Build Coastguard Worker return false;
162*c8dee2aaSAndroid Build Coastguard Worker }
163*c8dee2aaSAndroid Build Coastguard Worker if (!bm.readPixels(rgbaPixmap)) {
164*c8dee2aaSAndroid Build Coastguard Worker fputs("Unable to read rgbaPixmap.\n", stderr);
165*c8dee2aaSAndroid Build Coastguard Worker return false;
166*c8dee2aaSAndroid Build Coastguard Worker }
167*c8dee2aaSAndroid Build Coastguard Worker pixmap = &rgbaPixmap;
168*c8dee2aaSAndroid Build Coastguard Worker }
169*c8dee2aaSAndroid Build Coastguard Worker
170*c8dee2aaSAndroid Build Coastguard Worker managedBackendTexture = sk_gpu_test::ManagedBackendTexture::MakeFromPixmap(
171*c8dee2aaSAndroid Build Coastguard Worker dContext,
172*c8dee2aaSAndroid Build Coastguard Worker *pixmap,
173*c8dee2aaSAndroid Build Coastguard Worker options.fMipMapping,
174*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kNo,
175*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo);
176*c8dee2aaSAndroid Build Coastguard Worker if (!managedBackendTexture) {
177*c8dee2aaSAndroid Build Coastguard Worker fputs("Failed to create backEndTexture.\n", stderr);
178*c8dee2aaSAndroid Build Coastguard Worker return false;
179*c8dee2aaSAndroid Build Coastguard Worker }
180*c8dee2aaSAndroid Build Coastguard Worker backEndTexture = managedBackendTexture->texture();
181*c8dee2aaSAndroid Build Coastguard Worker }
182*c8dee2aaSAndroid Build Coastguard Worker
183*c8dee2aaSAndroid Build Coastguard Worker {
184*c8dee2aaSAndroid Build Coastguard Worker auto resourceProvider = dContext->priv().resourceProvider();
185*c8dee2aaSAndroid Build Coastguard Worker
186*c8dee2aaSAndroid Build Coastguard Worker SkISize offscreenDims = {options.fOffScreenWidth, options.fOffScreenHeight};
187*c8dee2aaSAndroid Build Coastguard Worker AutoTMalloc<uint32_t> data(offscreenDims.area());
188*c8dee2aaSAndroid Build Coastguard Worker SkOpts::memset32(data.get(), 0, offscreenDims.area());
189*c8dee2aaSAndroid Build Coastguard Worker
190*c8dee2aaSAndroid Build Coastguard Worker // This backend object should be renderable but not textureable. Given the limitations
191*c8dee2aaSAndroid Build Coastguard Worker // of how we're creating it though it will wind up being secretly textureable.
192*c8dee2aaSAndroid Build Coastguard Worker // We use this fact to initialize it with data but don't allow mipmaps
193*c8dee2aaSAndroid Build Coastguard Worker GrMipLevel level0 = {data.get(), offscreenDims.width()*sizeof(uint32_t), nullptr};
194*c8dee2aaSAndroid Build Coastguard Worker
195*c8dee2aaSAndroid Build Coastguard Worker constexpr int kSampleCnt = 1;
196*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrTexture> tmp =
197*c8dee2aaSAndroid Build Coastguard Worker resourceProvider->createTexture(offscreenDims,
198*c8dee2aaSAndroid Build Coastguard Worker renderableFormat,
199*c8dee2aaSAndroid Build Coastguard Worker GrTextureType::k2D,
200*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
201*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes,
202*c8dee2aaSAndroid Build Coastguard Worker kSampleCnt,
203*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kNo,
204*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped::kNo,
205*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo,
206*c8dee2aaSAndroid Build Coastguard Worker &level0,
207*c8dee2aaSAndroid Build Coastguard Worker /*label=*/"Fiddle_SetupBackendObjects");
208*c8dee2aaSAndroid Build Coastguard Worker if (!tmp || !tmp->asRenderTarget()) {
209*c8dee2aaSAndroid Build Coastguard Worker fputs("GrTexture is invalid.\n", stderr);
210*c8dee2aaSAndroid Build Coastguard Worker return false;
211*c8dee2aaSAndroid Build Coastguard Worker }
212*c8dee2aaSAndroid Build Coastguard Worker
213*c8dee2aaSAndroid Build Coastguard Worker backingRenderTarget = sk_ref_sp(tmp->asRenderTarget());
214*c8dee2aaSAndroid Build Coastguard Worker
215*c8dee2aaSAndroid Build Coastguard Worker backEndRenderTarget = backingRenderTarget->getBackendRenderTarget();
216*c8dee2aaSAndroid Build Coastguard Worker if (!backEndRenderTarget.isValid()) {
217*c8dee2aaSAndroid Build Coastguard Worker fputs("BackEndRenderTarget is invalid.\n", stderr);
218*c8dee2aaSAndroid Build Coastguard Worker return false;
219*c8dee2aaSAndroid Build Coastguard Worker }
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker
222*c8dee2aaSAndroid Build Coastguard Worker {
223*c8dee2aaSAndroid Build Coastguard Worker managedBackendTextureRenderTarget = sk_gpu_test::ManagedBackendTexture::MakeWithData(
224*c8dee2aaSAndroid Build Coastguard Worker dContext,
225*c8dee2aaSAndroid Build Coastguard Worker options.fOffScreenWidth,
226*c8dee2aaSAndroid Build Coastguard Worker options.fOffScreenHeight,
227*c8dee2aaSAndroid Build Coastguard Worker renderableFormat,
228*c8dee2aaSAndroid Build Coastguard Worker SkColors::kTransparent,
229*c8dee2aaSAndroid Build Coastguard Worker options.fOffScreenMipMapping,
230*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kYes,
231*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo);
232*c8dee2aaSAndroid Build Coastguard Worker if (!managedBackendTextureRenderTarget) {
233*c8dee2aaSAndroid Build Coastguard Worker fputs("Failed to create backendTextureRenderTarget.\n", stderr);
234*c8dee2aaSAndroid Build Coastguard Worker return false;
235*c8dee2aaSAndroid Build Coastguard Worker }
236*c8dee2aaSAndroid Build Coastguard Worker backEndTextureRenderTarget = managedBackendTextureRenderTarget->texture();
237*c8dee2aaSAndroid Build Coastguard Worker }
238*c8dee2aaSAndroid Build Coastguard Worker
239*c8dee2aaSAndroid Build Coastguard Worker return true;
240*c8dee2aaSAndroid Build Coastguard Worker }
241*c8dee2aaSAndroid Build Coastguard Worker #endif
242*c8dee2aaSAndroid Build Coastguard Worker
main(int argc,char ** argv)243*c8dee2aaSAndroid Build Coastguard Worker int main(int argc, char** argv) {
244*c8dee2aaSAndroid Build Coastguard Worker CommandLineFlags::Parse(argc, argv);
245*c8dee2aaSAndroid Build Coastguard Worker duration = FLAGS_duration;
246*c8dee2aaSAndroid Build Coastguard Worker frame = FLAGS_frame;
247*c8dee2aaSAndroid Build Coastguard Worker DrawOptions options = GetDrawOptions();
248*c8dee2aaSAndroid Build Coastguard Worker // If textOnly then only do one type of image, otherwise the text
249*c8dee2aaSAndroid Build Coastguard Worker // output is duplicated for each type.
250*c8dee2aaSAndroid Build Coastguard Worker if (options.textOnly) {
251*c8dee2aaSAndroid Build Coastguard Worker options.raster = true;
252*c8dee2aaSAndroid Build Coastguard Worker options.gpu = false;
253*c8dee2aaSAndroid Build Coastguard Worker options.pdf = false;
254*c8dee2aaSAndroid Build Coastguard Worker options.skp = false;
255*c8dee2aaSAndroid Build Coastguard Worker }
256*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)
257*c8dee2aaSAndroid Build Coastguard Worker fontMgr = SkFontMgr_New_FontConfig(nullptr, SkFontScanner_Make_FreeType());
258*c8dee2aaSAndroid Build Coastguard Worker #else
259*c8dee2aaSAndroid Build Coastguard Worker fontMgr = SkFontMgr::RefEmpty();
260*c8dee2aaSAndroid Build Coastguard Worker #endif
261*c8dee2aaSAndroid Build Coastguard Worker if (options.source) {
262*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data(SkData::MakeFromFileName(options.source));
263*c8dee2aaSAndroid Build Coastguard Worker if (!data) {
264*c8dee2aaSAndroid Build Coastguard Worker perror(options.source);
265*c8dee2aaSAndroid Build Coastguard Worker return 1;
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCodec> codec = nullptr;
268*c8dee2aaSAndroid Build Coastguard Worker if (SkPngDecoder::IsPng(data->data(), data->size())) {
269*c8dee2aaSAndroid Build Coastguard Worker codec = SkPngDecoder::Decode(data, nullptr);
270*c8dee2aaSAndroid Build Coastguard Worker } else if (SkJpegDecoder::IsJpeg(data->data(), data->size())) {
271*c8dee2aaSAndroid Build Coastguard Worker codec = SkJpegDecoder::Decode(data, nullptr);
272*c8dee2aaSAndroid Build Coastguard Worker } else {
273*c8dee2aaSAndroid Build Coastguard Worker perror("Unsupported file format\n");
274*c8dee2aaSAndroid Build Coastguard Worker return 1;
275*c8dee2aaSAndroid Build Coastguard Worker }
276*c8dee2aaSAndroid Build Coastguard Worker if (!codec) {
277*c8dee2aaSAndroid Build Coastguard Worker perror("Corrupt source image file\n");
278*c8dee2aaSAndroid Build Coastguard Worker return 1;
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker image = std::get<0>(codec->getImage());
281*c8dee2aaSAndroid Build Coastguard Worker if (!image) {
282*c8dee2aaSAndroid Build Coastguard Worker perror("Unable to decode the source image.\n");
283*c8dee2aaSAndroid Build Coastguard Worker return 1;
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker SkAssertResult(image->asLegacyBitmap(&source));
286*c8dee2aaSAndroid Build Coastguard Worker }
287*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> rasterData, gpuData, pdfData, skpData;
288*c8dee2aaSAndroid Build Coastguard Worker SkColorType colorType = kN32_SkColorType;
289*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace = nullptr;
290*c8dee2aaSAndroid Build Coastguard Worker if (options.f16) {
291*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(options.srgb);
292*c8dee2aaSAndroid Build Coastguard Worker colorType = kRGBA_F16_SkColorType;
293*c8dee2aaSAndroid Build Coastguard Worker colorSpace = SkColorSpace::MakeSRGBLinear();
294*c8dee2aaSAndroid Build Coastguard Worker } else if (options.srgb) {
295*c8dee2aaSAndroid Build Coastguard Worker colorSpace = SkColorSpace::MakeSRGB();
296*c8dee2aaSAndroid Build Coastguard Worker }
297*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo info = SkImageInfo::Make(options.size.width(), options.size.height(), colorType,
298*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType, colorSpace);
299*c8dee2aaSAndroid Build Coastguard Worker if (options.raster) {
300*c8dee2aaSAndroid Build Coastguard Worker auto rasterSurface = SkSurfaces::Raster(info);
301*c8dee2aaSAndroid Build Coastguard Worker srand(0);
302*c8dee2aaSAndroid Build Coastguard Worker draw(prepare_canvas(rasterSurface->getCanvas()));
303*c8dee2aaSAndroid Build Coastguard Worker rasterData = encode_snapshot(nullptr, rasterSurface);
304*c8dee2aaSAndroid Build Coastguard Worker }
305*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
306*c8dee2aaSAndroid Build Coastguard Worker if (options.gpu) {
307*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<sk_gpu_test::GLTestContext> glContext;
308*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrDirectContext> direct = create_direct_context(gGLDriverInfo, &glContext);
309*c8dee2aaSAndroid Build Coastguard Worker if (!direct) {
310*c8dee2aaSAndroid Build Coastguard Worker fputs("Unable to get GrContext.\n", stderr);
311*c8dee2aaSAndroid Build Coastguard Worker } else {
312*c8dee2aaSAndroid Build Coastguard Worker if (!setup_backend_objects(direct.get(), source, options)) {
313*c8dee2aaSAndroid Build Coastguard Worker fputs("Unable to create backend objects.\n", stderr);
314*c8dee2aaSAndroid Build Coastguard Worker exit(1);
315*c8dee2aaSAndroid Build Coastguard Worker }
316*c8dee2aaSAndroid Build Coastguard Worker
317*c8dee2aaSAndroid Build Coastguard Worker auto surface = SkSurfaces::RenderTarget(direct.get(), skgpu::Budgeted::kNo, info);
318*c8dee2aaSAndroid Build Coastguard Worker if (!surface) {
319*c8dee2aaSAndroid Build Coastguard Worker fputs("Unable to get render surface.\n", stderr);
320*c8dee2aaSAndroid Build Coastguard Worker exit(1);
321*c8dee2aaSAndroid Build Coastguard Worker }
322*c8dee2aaSAndroid Build Coastguard Worker srand(0);
323*c8dee2aaSAndroid Build Coastguard Worker draw(prepare_canvas(surface->getCanvas()));
324*c8dee2aaSAndroid Build Coastguard Worker gpuData = encode_snapshot(direct.get(), surface);
325*c8dee2aaSAndroid Build Coastguard Worker }
326*c8dee2aaSAndroid Build Coastguard Worker }
327*c8dee2aaSAndroid Build Coastguard Worker #endif
328*c8dee2aaSAndroid Build Coastguard Worker
329*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_SUPPORT_PDF
330*c8dee2aaSAndroid Build Coastguard Worker if (options.pdf) {
331*c8dee2aaSAndroid Build Coastguard Worker SkDynamicMemoryWStream pdfStream;
332*c8dee2aaSAndroid Build Coastguard Worker auto document = SkPDF::MakeDocument(&pdfStream);
333*c8dee2aaSAndroid Build Coastguard Worker if (document) {
334*c8dee2aaSAndroid Build Coastguard Worker srand(0);
335*c8dee2aaSAndroid Build Coastguard Worker draw(prepare_canvas(document->beginPage(options.size.width(), options.size.height())));
336*c8dee2aaSAndroid Build Coastguard Worker document->close();
337*c8dee2aaSAndroid Build Coastguard Worker pdfData = pdfStream.detachAsData();
338*c8dee2aaSAndroid Build Coastguard Worker }
339*c8dee2aaSAndroid Build Coastguard Worker }
340*c8dee2aaSAndroid Build Coastguard Worker #endif
341*c8dee2aaSAndroid Build Coastguard Worker
342*c8dee2aaSAndroid Build Coastguard Worker if (options.skp) {
343*c8dee2aaSAndroid Build Coastguard Worker auto size = SkSize::Make(options.size);
344*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder;
345*c8dee2aaSAndroid Build Coastguard Worker srand(0);
346*c8dee2aaSAndroid Build Coastguard Worker draw(prepare_canvas(recorder.beginRecording(size.width(), size.height())));
347*c8dee2aaSAndroid Build Coastguard Worker auto picture = recorder.finishRecordingAsPicture();
348*c8dee2aaSAndroid Build Coastguard Worker SkDynamicMemoryWStream skpStream;
349*c8dee2aaSAndroid Build Coastguard Worker picture->serialize(&skpStream);
350*c8dee2aaSAndroid Build Coastguard Worker skpData = skpStream.detachAsData();
351*c8dee2aaSAndroid Build Coastguard Worker }
352*c8dee2aaSAndroid Build Coastguard Worker
353*c8dee2aaSAndroid Build Coastguard Worker printf("{\n");
354*c8dee2aaSAndroid Build Coastguard Worker if (!options.textOnly) {
355*c8dee2aaSAndroid Build Coastguard Worker dump_output(rasterData, "Raster", false);
356*c8dee2aaSAndroid Build Coastguard Worker dump_output(gpuData, "Gpu", false);
357*c8dee2aaSAndroid Build Coastguard Worker dump_output(pdfData, "Pdf", false);
358*c8dee2aaSAndroid Build Coastguard Worker dump_output(skpData, "Skp", false);
359*c8dee2aaSAndroid Build Coastguard Worker } else {
360*c8dee2aaSAndroid Build Coastguard Worker std::string textoutput = gTextOutput.str();
361*c8dee2aaSAndroid Build Coastguard Worker dump_output(textoutput.c_str(), textoutput.length(), "Text", false);
362*c8dee2aaSAndroid Build Coastguard Worker }
363*c8dee2aaSAndroid Build Coastguard Worker std::string glinfo = gGLDriverInfo.str();
364*c8dee2aaSAndroid Build Coastguard Worker dump_output(glinfo.c_str(), glinfo.length(), "GLInfo", true);
365*c8dee2aaSAndroid Build Coastguard Worker printf("}\n");
366*c8dee2aaSAndroid Build Coastguard Worker
367*c8dee2aaSAndroid Build Coastguard Worker return 0;
368*c8dee2aaSAndroid Build Coastguard Worker }
369