Home | History | Annotate | Download | only in fiddle
      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