• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdio.h>
9 
10 #include <GL/osmesa.h>
11 
12 #include "fiddle_main.h"
13 
14 // Globals externed in fiddle_main.h
15 SkBitmap source;
16 SkImage* image(nullptr);
17 
encode_to_base64(const void * data,size_t size,FILE * out)18 static void encode_to_base64(const void* data, size_t size, FILE* out) {
19     const uint8_t* input = reinterpret_cast<const uint8_t*>(data);
20     const uint8_t* end = &input[size];
21     static const char codes[] =
22             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
23             "abcdefghijklmnopqrstuvwxyz0123456789+/";
24     while (input != end) {
25         uint8_t b = (*input & 0xFC) >> 2;
26         fputc(codes[b], out);
27         b = (*input & 0x03) << 4;
28         ++input;
29         if (input == end) {
30             fputc(codes[b], out);
31             fputs("==", out);
32             return;
33         }
34         b |= (*input & 0xF0) >> 4;
35         fputc(codes[b], out);
36         b = (*input & 0x0F) << 2;
37         ++input;
38         if (input == end) {
39             fputc(codes[b], out);
40             fputc('=', out);
41             return;
42         }
43         b |= (*input & 0xC0) >> 6;
44         fputc(codes[b], out);
45         b = *input & 0x3F;
46         fputc(codes[b], out);
47         ++input;
48     }
49 }
50 
dump_output(SkData * data,const char * name,bool last=true)51 static void dump_output(SkData* data, const char* name, bool last = true) {
52     if (data) {
53         printf("\t\"%s\": \"", name);
54         encode_to_base64(data->data(), data->size(), stdout);
55         fputs(last ? "\"\n" : "\",\n", stdout);
56     }
57 }
58 
encode_snapshot(SkSurface * surface)59 static SkData* encode_snapshot(SkSurface* surface) {
60     SkAutoTUnref<SkImage> img(surface->newImageSnapshot());
61     return img ? img->encode() : nullptr;
62 }
63 
create_osmesa_context()64 static OSMesaContext create_osmesa_context() {
65     OSMesaContext osMesaContext =
66         OSMesaCreateContextExt(OSMESA_BGRA, 0, 0, 0, nullptr);
67     if (osMesaContext != nullptr) {
68         static uint32_t buffer[16 * 16];
69         OSMesaMakeCurrent(osMesaContext, &buffer, GL_UNSIGNED_BYTE, 16, 16);
70     }
71     return osMesaContext;
72 }
73 
create_mesa_grcontext()74 static GrContext* create_mesa_grcontext() {
75     SkAutoTUnref<const GrGLInterface> mesa(GrGLCreateMesaInterface());
76     intptr_t backend = reinterpret_cast<intptr_t>(mesa.get());
77     return backend ? GrContext::Create(kOpenGL_GrBackend, backend) : nullptr;
78 }
79 
80 
main()81 int main() {
82     const DrawOptions options = GetDrawOptions();
83     fprintf(stderr, "%s\n", options.source);
84     if (options.source) {
85         SkAutoTUnref<SkData> data(SkData::NewFromFileName(options.source));
86         if (!data) {
87             perror(options.source);
88             return 1;
89         } else {
90             image = SkImage::NewFromEncoded(data);
91             if (!image) {
92                 perror("Unable to decode the source image.");
93                 return 1;
94             }
95             SkAssertResult(image->asLegacyBitmap(
96                                    &source, SkImage::kRO_LegacyBitmapMode));
97         }
98     }
99     SkAutoTUnref<SkData> rasterData, gpuData, pdfData, skpData;
100     if (options.raster) {
101         SkAutoTUnref<SkSurface> rasterSurface(
102                 SkSurface::NewRaster(SkImageInfo::MakeN32Premul(options.size)));
103         draw(rasterSurface->getCanvas());
104         rasterData.reset(encode_snapshot(rasterSurface));
105     }
106     if (options.gpu) {
107         OSMesaContext osMesaContext = create_osmesa_context();
108         SkAutoTUnref<GrContext> grContext(create_mesa_grcontext());
109         if (!grContext) {
110             fputs("Unable to get Mesa GrContext.\n", stderr);
111         } else {
112             SkAutoTUnref<SkSurface> surface(
113                     SkSurface::NewRenderTarget(
114                             grContext,
115                             SkBudgeted::kNo,
116                             SkImageInfo::MakeN32Premul(options.size)));
117             if (!surface) {
118                 fputs("Unable to get render surface.\n", stderr);
119                 exit(1);
120             }
121             draw(surface->getCanvas());
122             gpuData.reset(encode_snapshot(surface));
123         }
124         if (osMesaContext) {
125             OSMesaDestroyContext(osMesaContext);
126         }
127     }
128     if (options.pdf) {
129         SkDynamicMemoryWStream pdfStream;
130         SkAutoTUnref<SkDocument> document(SkDocument::CreatePDF(&pdfStream));
131         draw(document->beginPage(options.size.width(), options.size.height()));
132         document->close();
133         pdfData.reset(pdfStream.copyToData());
134     }
135     if (options.skp) {
136         SkSize size;
137         size = options.size;
138         SkPictureRecorder recorder;
139         draw(recorder.beginRecording(size.width(), size.height()));
140         SkAutoTUnref<SkPicture> picture(recorder.endRecordingAsPicture());
141         SkDynamicMemoryWStream skpStream;
142         picture->serialize(&skpStream);
143         skpData.reset(skpStream.copyToData());
144     }
145 
146     printf("{\n");
147     dump_output(rasterData, "Raster", !gpuData && !pdfData && !skpData);
148     dump_output(gpuData, "Gpu", !pdfData && !skpData);
149     dump_output(pdfData, "Pdf", !skpData);
150     dump_output(skpData, "Skp");
151     printf("}\n");
152 
153     SkSafeSetNull(image);
154     return 0;
155 }
156