2015-12-10 15:52:45 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2015 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2016-05-23 16:02:38 +00:00
|
|
|
#include <stdlib.h>
|
2016-08-02 18:13:48 +00:00
|
|
|
#include "SkForceLinking.h"
|
|
|
|
|
|
|
|
__SK_FORCE_IMAGE_DECODER_LINKING;
|
2015-12-10 15:52:45 +00:00
|
|
|
|
|
|
|
#include "fiddle_main.h"
|
|
|
|
|
|
|
|
// Globals externed in fiddle_main.h
|
|
|
|
SkBitmap source;
|
2016-04-18 15:17:56 +00:00
|
|
|
sk_sp<SkImage> image;
|
2015-12-10 15:52:45 +00:00
|
|
|
|
|
|
|
static void encode_to_base64(const void* data, size_t size, FILE* out) {
|
|
|
|
const uint8_t* input = reinterpret_cast<const uint8_t*>(data);
|
|
|
|
const uint8_t* end = &input[size];
|
|
|
|
static const char codes[] =
|
|
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
"abcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
while (input != end) {
|
|
|
|
uint8_t b = (*input & 0xFC) >> 2;
|
|
|
|
fputc(codes[b], out);
|
|
|
|
b = (*input & 0x03) << 4;
|
|
|
|
++input;
|
|
|
|
if (input == end) {
|
|
|
|
fputc(codes[b], out);
|
|
|
|
fputs("==", out);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
b |= (*input & 0xF0) >> 4;
|
|
|
|
fputc(codes[b], out);
|
|
|
|
b = (*input & 0x0F) << 2;
|
|
|
|
++input;
|
|
|
|
if (input == end) {
|
|
|
|
fputc(codes[b], out);
|
|
|
|
fputc('=', out);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
b |= (*input & 0xC0) >> 6;
|
|
|
|
fputc(codes[b], out);
|
|
|
|
b = *input & 0x3F;
|
|
|
|
fputc(codes[b], out);
|
|
|
|
++input;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-25 18:29:34 +00:00
|
|
|
static void dump_output(const sk_sp<SkData>& data,
|
|
|
|
const char* name, bool last = true) {
|
2015-12-10 15:52:45 +00:00
|
|
|
if (data) {
|
|
|
|
printf("\t\"%s\": \"", name);
|
|
|
|
encode_to_base64(data->data(), data->size(), stdout);
|
|
|
|
fputs(last ? "\"\n" : "\",\n", stdout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-25 18:29:34 +00:00
|
|
|
static SkData* encode_snapshot(const sk_sp<SkSurface>& surface) {
|
2016-04-18 15:17:56 +00:00
|
|
|
sk_sp<SkImage> img(surface->makeImageSnapshot());
|
2015-12-10 15:52:45 +00:00
|
|
|
return img ? img->encode() : nullptr;
|
|
|
|
}
|
|
|
|
|
2016-08-25 15:44:49 +00:00
|
|
|
#if defined(__linux) && !defined(__ANDROID__)
|
2016-07-27 18:17:18 +00:00
|
|
|
#include <GL/osmesa.h>
|
|
|
|
static sk_sp<GrContext> create_grcontext() {
|
|
|
|
// We just leak the OSMesaContext... the process will die soon anyway.
|
|
|
|
if (OSMesaContext osMesaContext = OSMesaCreateContextExt(OSMESA_BGRA, 0, 0, 0, nullptr)) {
|
|
|
|
static uint32_t buffer[16 * 16];
|
|
|
|
OSMesaMakeCurrent(osMesaContext, &buffer, GL_UNSIGNED_BYTE, 16, 16);
|
|
|
|
}
|
2015-12-10 15:52:45 +00:00
|
|
|
|
2016-07-27 18:17:18 +00:00
|
|
|
auto osmesa_get = [](void* ctx, const char name[]) {
|
|
|
|
SkASSERT(nullptr == ctx);
|
|
|
|
SkASSERT(OSMesaGetCurrentContext());
|
|
|
|
return OSMesaGetProcAddress(name);
|
|
|
|
};
|
|
|
|
sk_sp<const GrGLInterface> mesa(GrGLAssembleInterface(nullptr, osmesa_get));
|
|
|
|
if (!mesa) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return sk_sp<GrContext>(GrContext::Create(
|
|
|
|
kOpenGL_GrBackend,
|
|
|
|
reinterpret_cast<intptr_t>(mesa.get())));
|
2016-03-31 17:35:13 +00:00
|
|
|
}
|
2016-07-27 18:17:18 +00:00
|
|
|
#else
|
|
|
|
static sk_sp<GrContext> create_grcontext() { return nullptr; }
|
|
|
|
#endif
|
2015-12-10 15:52:45 +00:00
|
|
|
|
|
|
|
int main() {
|
|
|
|
const DrawOptions options = GetDrawOptions();
|
|
|
|
if (options.source) {
|
2016-08-02 21:40:46 +00:00
|
|
|
sk_sp<SkData> data(SkData::MakeFromFileName(options.source));
|
2015-12-10 15:52:45 +00:00
|
|
|
if (!data) {
|
|
|
|
perror(options.source);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2016-04-18 15:17:56 +00:00
|
|
|
image = SkImage::MakeFromEncoded(std::move(data));
|
2015-12-10 15:52:45 +00:00
|
|
|
if (!image) {
|
|
|
|
perror("Unable to decode the source image.");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
SkAssertResult(image->asLegacyBitmap(
|
|
|
|
&source, SkImage::kRO_LegacyBitmapMode));
|
|
|
|
}
|
|
|
|
}
|
2016-03-25 18:29:34 +00:00
|
|
|
sk_sp<SkData> rasterData, gpuData, pdfData, skpData;
|
2015-12-10 15:52:45 +00:00
|
|
|
if (options.raster) {
|
2016-03-25 18:29:34 +00:00
|
|
|
auto rasterSurface =
|
|
|
|
SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(options.size));
|
2016-05-23 16:02:38 +00:00
|
|
|
srand(0);
|
2015-12-10 15:52:45 +00:00
|
|
|
draw(rasterSurface->getCanvas());
|
|
|
|
rasterData.reset(encode_snapshot(rasterSurface));
|
|
|
|
}
|
|
|
|
if (options.gpu) {
|
2016-07-27 18:17:18 +00:00
|
|
|
auto grContext = create_grcontext();
|
2015-12-10 15:52:45 +00:00
|
|
|
if (!grContext) {
|
2016-07-27 18:17:18 +00:00
|
|
|
fputs("Unable to get GrContext.\n", stderr);
|
2015-12-10 15:52:45 +00:00
|
|
|
} else {
|
2016-03-25 18:29:34 +00:00
|
|
|
auto surface = SkSurface::MakeRenderTarget(
|
|
|
|
grContext.get(),
|
|
|
|
SkBudgeted::kNo,
|
|
|
|
SkImageInfo::MakeN32Premul(options.size));
|
2015-12-10 15:52:45 +00:00
|
|
|
if (!surface) {
|
|
|
|
fputs("Unable to get render surface.\n", stderr);
|
|
|
|
exit(1);
|
|
|
|
}
|
2016-05-23 16:02:38 +00:00
|
|
|
srand(0);
|
2015-12-10 15:52:45 +00:00
|
|
|
draw(surface->getCanvas());
|
|
|
|
gpuData.reset(encode_snapshot(surface));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (options.pdf) {
|
|
|
|
SkDynamicMemoryWStream pdfStream;
|
2016-05-03 19:10:04 +00:00
|
|
|
sk_sp<SkDocument> document(SkDocument::MakePDF(&pdfStream));
|
2016-05-23 16:02:38 +00:00
|
|
|
srand(0);
|
2015-12-10 15:52:45 +00:00
|
|
|
draw(document->beginPage(options.size.width(), options.size.height()));
|
|
|
|
document->close();
|
|
|
|
pdfData.reset(pdfStream.copyToData());
|
|
|
|
}
|
|
|
|
if (options.skp) {
|
|
|
|
SkSize size;
|
|
|
|
size = options.size;
|
|
|
|
SkPictureRecorder recorder;
|
2016-05-23 16:02:38 +00:00
|
|
|
srand(0);
|
2015-12-10 15:52:45 +00:00
|
|
|
draw(recorder.beginRecording(size.width(), size.height()));
|
2016-03-25 18:29:34 +00:00
|
|
|
auto picture = recorder.finishRecordingAsPicture();
|
2015-12-10 15:52:45 +00:00
|
|
|
SkDynamicMemoryWStream skpStream;
|
|
|
|
picture->serialize(&skpStream);
|
|
|
|
skpData.reset(skpStream.copyToData());
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("{\n");
|
|
|
|
dump_output(rasterData, "Raster", !gpuData && !pdfData && !skpData);
|
|
|
|
dump_output(gpuData, "Gpu", !pdfData && !skpData);
|
|
|
|
dump_output(pdfData, "Pdf", !skpData);
|
|
|
|
dump_output(skpData, "Skp");
|
|
|
|
printf("}\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|