123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- /*
- * 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 <cstdio>
- #include <cstdlib>
- #include <sstream>
- #include <string>
- #include "src/core/SkAutoPixmapStorage.h"
- #include "src/core/SkMipMap.h"
- #include "src/core/SkUtils.h"
- #include "tools/flags/CommandLineFlags.h"
- #include "tools/fiddle/fiddle_main.h"
- static DEFINE_double(duration, 1.0,
- "The total duration, in seconds, of the animation we are drawing.");
- static DEFINE_double(frame, 1.0,
- "A double value in [0, 1] that specifies the point in animation to draw.");
- #include "include/gpu/GrBackendSurface.h"
- #include "src/gpu/GrContextPriv.h"
- #include "src/gpu/GrGpu.h"
- #include "tools/gpu/gl/GLTestContext.h"
- // Globals externed in fiddle_main.h
- sk_sp<GrTexture> backingTexture; // not externed
- GrBackendTexture backEndTexture;
- sk_sp<GrRenderTarget> backingRenderTarget; // not externed
- GrBackendRenderTarget backEndRenderTarget;
- sk_sp<GrTexture> backingTextureRenderTarget; // not externed
- GrBackendTexture backEndTextureRenderTarget;
- SkBitmap source;
- sk_sp<SkImage> image;
- double duration; // The total duration of the animation in seconds.
- double frame; // A value in [0, 1] of where we are in the animation.
- // Global used by the local impl of SkDebugf.
- std::ostringstream gTextOutput;
- // Global to record the GL driver info via create_grcontext().
- std::ostringstream gGLDriverInfo;
- void SkDebugf(const char * fmt, ...) {
- va_list args;
- va_start(args, fmt);
- char formatbuffer[1024];
- int n = vsnprintf(formatbuffer, sizeof(formatbuffer), fmt, args);
- va_end(args);
- if (n>=0 && n<=int(sizeof(formatbuffer))) {
- gTextOutput.write(formatbuffer, n);
- }
- }
- 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;
- }
- }
- static void dump_output(const void* data, size_t size,
- const char* name, bool last = true) {
- printf("\t\"%s\": \"", name);
- encode_to_base64(data, size, stdout);
- fputs(last ? "\"\n" : "\",\n", stdout);
- }
- static void dump_output(const sk_sp<SkData>& data,
- const char* name, bool last = true) {
- if (data) {
- dump_output(data->data(), data->size(), name, last);
- }
- }
- static sk_sp<SkData> encode_snapshot(const sk_sp<SkSurface>& surface) {
- sk_sp<SkImage> img(surface->makeImageSnapshot());
- return img ? img->encodeToData() : nullptr;
- }
- static SkCanvas* prepare_canvas(SkCanvas * canvas) {
- canvas->clear(SK_ColorWHITE);
- return canvas;
- }
- static bool setup_backend_objects(GrContext* context,
- const SkBitmap& bm,
- const DrawOptions& options) {
- if (!context) {
- return false;
- }
- auto resourceProvider = context->priv().resourceProvider();
- GrSurfaceDesc backingDesc;
- backingDesc.fWidth = bm.width();
- backingDesc.fHeight = bm.height();
- // This config must match the SkColorType used in draw.cpp in the SkImage and Surface factories
- backingDesc.fConfig = kRGBA_8888_GrPixelConfig;
- if (!bm.empty()) {
- SkPixmap originalPixmap;
- SkPixmap* pixmap = &originalPixmap;
- if (!bm.peekPixels(&originalPixmap)) {
- return false;
- }
- SkAutoPixmapStorage rgbaPixmap;
- if (kN32_SkColorType != kRGBA_8888_SkColorType) {
- if (!rgbaPixmap.tryAlloc(bm.info().makeColorType(kRGBA_8888_SkColorType))) {
- return false;
- }
- if (!bm.readPixels(rgbaPixmap)) {
- return false;
- }
- pixmap = &rgbaPixmap;
- }
- int mipLevelCount = GrMipMapped::kYes == options.fMipMapping
- ? SkMipMap::ComputeLevelCount(bm.width(), bm.height())
- : 1;
- std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
- texels[0].fPixels = pixmap->addr();
- texels[0].fRowBytes = pixmap->rowBytes();
- for (int i = 1; i < mipLevelCount; i++) {
- texels[i].fPixels = nullptr;
- texels[i].fRowBytes = 0;
- }
- backingTexture =
- resourceProvider->createTexture(backingDesc, GrRenderable::kNo, 1, SkBudgeted::kNo,
- GrProtected::kNo, texels.get(), mipLevelCount);
- if (!backingTexture) {
- return false;
- }
- backEndTexture = backingTexture->getBackendTexture();
- if (!backEndTexture.isValid()) {
- return false;
- }
- }
- backingDesc.fWidth = options.fOffScreenWidth;
- backingDesc.fHeight = options.fOffScreenHeight;
- SkAutoTMalloc<uint32_t> data(backingDesc.fWidth * backingDesc.fHeight);
- sk_memset32(data.get(), 0, backingDesc.fWidth * backingDesc.fHeight);
- {
- // This backend object should be renderable but not textureable. Given the limitations
- // of how we're creating it though it will wind up being secretly textureable.
- // We use this fact to initialize it with data but don't allow mipmaps
- GrMipLevel level0 = { data.get(), backingDesc.fWidth*sizeof(uint32_t) };
- sk_sp<GrTexture> tmp = resourceProvider->createTexture(
- backingDesc, GrRenderable::kYes, options.fOffScreenSampleCount, SkBudgeted::kNo,
- GrProtected::kNo, &level0, 1);
- if (!tmp || !tmp->asRenderTarget()) {
- return false;
- }
- backingRenderTarget = sk_ref_sp(tmp->asRenderTarget());
- backEndRenderTarget = backingRenderTarget->getBackendRenderTarget();
- if (!backEndRenderTarget.isValid()) {
- return false;
- }
- }
- {
- int mipLevelCount = GrMipMapped::kYes == options.fOffScreenMipMapping
- ? SkMipMap::ComputeLevelCount(backingDesc.fWidth, backingDesc.fHeight)
- : 1;
- std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
- texels[0].fPixels = data.get();
- texels[0].fRowBytes = backingDesc.fWidth*sizeof(uint32_t);
- for (int i = 1; i < mipLevelCount; i++) {
- texels[i].fPixels = nullptr;
- texels[i].fRowBytes = 0;
- }
- backingTextureRenderTarget =
- resourceProvider->createTexture(backingDesc, GrRenderable::kYes,
- options.fOffScreenSampleCount, SkBudgeted::kNo, GrProtected::kNo,
- texels.get(), mipLevelCount);
- if (!backingTextureRenderTarget || !backingTextureRenderTarget->asRenderTarget()) {
- return false;
- }
- backEndTextureRenderTarget = backingTextureRenderTarget->getBackendTexture();
- if (!backEndTextureRenderTarget.isValid()) {
- return false;
- }
- }
- return true;
- }
- int main(int argc, char** argv) {
- CommandLineFlags::Parse(argc, argv);
- duration = FLAGS_duration;
- frame = FLAGS_frame;
- DrawOptions options = GetDrawOptions();
- // If textOnly then only do one type of image, otherwise the text
- // output is duplicated for each type.
- if (options.textOnly) {
- options.raster = true;
- options.gpu = false;
- options.pdf = false;
- options.skp = false;
- }
- if (options.source) {
- sk_sp<SkData> data(SkData::MakeFromFileName(options.source));
- if (!data) {
- perror(options.source);
- return 1;
- } else {
- image = SkImage::MakeFromEncoded(std::move(data));
- if (!image) {
- perror("Unable to decode the source image.");
- return 1;
- }
- SkAssertResult(image->asLegacyBitmap(&source));
- }
- }
- sk_sp<SkData> rasterData, gpuData, pdfData, skpData;
- SkColorType colorType = kN32_SkColorType;
- sk_sp<SkColorSpace> colorSpace = nullptr;
- if (options.f16) {
- SkASSERT(options.srgb);
- colorType = kRGBA_F16_SkColorType;
- colorSpace = SkColorSpace::MakeSRGBLinear();
- } else if (options.srgb) {
- colorSpace = SkColorSpace::MakeSRGB();
- }
- SkImageInfo info = SkImageInfo::Make(options.size.width(), options.size.height(), colorType,
- kPremul_SkAlphaType, colorSpace);
- if (options.raster) {
- auto rasterSurface = SkSurface::MakeRaster(info);
- srand(0);
- draw(prepare_canvas(rasterSurface->getCanvas()));
- rasterData = encode_snapshot(rasterSurface);
- }
- if (options.gpu) {
- std::unique_ptr<sk_gpu_test::GLTestContext> glContext;
- sk_sp<GrContext> grContext = create_grcontext(gGLDriverInfo, &glContext);
- if (!grContext) {
- fputs("Unable to get GrContext.\n", stderr);
- } else {
- if (!setup_backend_objects(grContext.get(), source, options)) {
- fputs("Unable to create backend objects.\n", stderr);
- exit(1);
- }
- auto surface = SkSurface::MakeRenderTarget(grContext.get(), SkBudgeted::kNo, info);
- if (!surface) {
- fputs("Unable to get render surface.\n", stderr);
- exit(1);
- }
- srand(0);
- draw(prepare_canvas(surface->getCanvas()));
- gpuData = encode_snapshot(surface);
- }
- }
- if (options.pdf) {
- SkDynamicMemoryWStream pdfStream;
- auto document = SkPDF::MakeDocument(&pdfStream);
- if (document) {
- srand(0);
- draw(prepare_canvas(document->beginPage(options.size.width(), options.size.height())));
- document->close();
- pdfData = pdfStream.detachAsData();
- }
- }
- if (options.skp) {
- SkSize size;
- size = options.size;
- SkPictureRecorder recorder;
- srand(0);
- draw(prepare_canvas(recorder.beginRecording(size.width(), size.height())));
- auto picture = recorder.finishRecordingAsPicture();
- SkDynamicMemoryWStream skpStream;
- picture->serialize(&skpStream);
- skpData = skpStream.detachAsData();
- }
- printf("{\n");
- if (!options.textOnly) {
- dump_output(rasterData, "Raster", false);
- dump_output(gpuData, "Gpu", false);
- dump_output(pdfData, "Pdf", false);
- dump_output(skpData, "Skp", false);
- } else {
- std::string textoutput = gTextOutput.str();
- dump_output(textoutput.c_str(), textoutput.length(), "Text", false);
- }
- std::string glinfo = gGLDriverInfo.str();
- dump_output(glinfo.c_str(), glinfo.length(), "GLInfo", true);
- printf("}\n");
- return 0;
- }
|