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 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 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 59 static SkData* encode_snapshot(SkSurface* surface) { 60 SkAutoTUnref<SkImage> img(surface->newImageSnapshot()); 61 return img ? img->encode() : nullptr; 62 } 63 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 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 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