From 84bc52ad26e69c01a694a9d724944507acb64d38 Mon Sep 17 00:00:00 2001 From: halcanary Date: Tue, 2 Dec 2014 14:01:46 -0800 Subject: [PATCH] work in progress Review URL: https://codereview.chromium.org/769423002 --- experimental/tools/PageCachingDocument.cpp | 98 +++++++++++++++++++ experimental/tools/PageCachingDocument.h | 22 +++++ experimental/tools/gmtoskp.cpp | 8 +- experimental/tools/multipage_pdf_profiler.cpp | 19 ++-- gm/smallimage.cpp | 11 +++ gyp/experimental.gyp | 1 + gyp/gmslides.gypi | 1 + 7 files changed, 146 insertions(+), 14 deletions(-) create mode 100644 experimental/tools/PageCachingDocument.cpp create mode 100644 experimental/tools/PageCachingDocument.h create mode 100644 gm/smallimage.cpp diff --git a/experimental/tools/PageCachingDocument.cpp b/experimental/tools/PageCachingDocument.cpp new file mode 100644 index 0000000000..38e883e839 --- /dev/null +++ b/experimental/tools/PageCachingDocument.cpp @@ -0,0 +1,98 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "PageCachingDocument.h" +#include "SkCanvas.h" +#include "SkDocument.h" +#include "SkPictureRecorder.h" +#include "SkRect.h" +#include "SkTDArray.h" + +namespace { + +typedef void (*DoneProc)(SkWStream*, bool); +typedef SkData* (*Encoder)(size_t*, const SkBitmap&); + +// This class allows us to compare the relative memory consumption of +// the PDF and SkPicture backends. +class PageCachingDocument : public SkDocument { +public: + PageCachingDocument(SkWStream*, DoneProc, Encoder, SkScalar rasterDpi); + virtual ~PageCachingDocument(); + virtual SkCanvas* onBeginPage(SkScalar width, + SkScalar height, + const SkRect& content) SK_OVERRIDE; + virtual void onEndPage() SK_OVERRIDE; + virtual bool onClose(SkWStream*) SK_OVERRIDE; + virtual void onAbort() SK_OVERRIDE; + +private: + struct Page { + SkScalar fWidth; + SkScalar fHeight; + SkAutoTUnref fPic; + }; + SkPictureRecorder fRecorder; + SkTDArray fPages; + Encoder fEncoder; + SkScalar fRasterDpi; +}; + +PageCachingDocument::PageCachingDocument(SkWStream* stream, + DoneProc done, + Encoder encoder, + SkScalar rasterDpi) + : SkDocument(stream, done), fEncoder(encoder), fRasterDpi(rasterDpi) { +} + +PageCachingDocument::~PageCachingDocument() { + for (Page* p = fPages.begin(); p != fPages.end(); ++p) { + p->~Page(); + } +} + +SkCanvas* PageCachingDocument::onBeginPage(SkScalar width, + SkScalar height, + const SkRect& content) { + Page* page = fPages.push(); + sk_bzero(page, sizeof(*page)); + page->fWidth = width; + page->fHeight = height; + SkASSERT(!page->fPic.get()); + SkCanvas* canvas = fRecorder.beginRecording(content); + return canvas; +} + +void PageCachingDocument::onEndPage() { + SkASSERT(fPages.count() > 0); + SkASSERT(!fPages[fPages.count() - 1].fPic); + fPages[fPages.count() - 1].fPic.reset(fRecorder.endRecording()); +} + +bool PageCachingDocument::onClose(SkWStream* stream) { + SkAutoTUnref doc( + SkDocument::CreatePDF(stream, NULL, fEncoder, fRasterDpi)); + for (Page* page = fPages.begin(); page != fPages.end(); ++page) { + SkRect cullRect = page->fPic->cullRect(); + SkCanvas* canvas = + doc->beginPage(page->fWidth, page->fHeight, &cullRect); + canvas->drawPicture(page->fPic); + doc->endPage(); + } + return doc->close(); +} + +void PageCachingDocument::onAbort() { +} +} // namespace + +SkDocument* CreatePageCachingDocument(SkWStream* stream, + DoneProc done, + Encoder encoder, + SkScalar rasterDpi) { + return SkNEW_ARGS(PageCachingDocument, (stream, done, encoder, rasterDpi)); +} diff --git a/experimental/tools/PageCachingDocument.h b/experimental/tools/PageCachingDocument.h new file mode 100644 index 0000000000..19be1ae619 --- /dev/null +++ b/experimental/tools/PageCachingDocument.h @@ -0,0 +1,22 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef PageCachingDocument_DEFINED +#define PageCachingDocument_DEFINED + +#include "SkScalar.h" + +class SkBitmap; +class SkData; +class SkDocument; +class SkWStream; + +SkDocument* CreatePageCachingDocument( + SkWStream* stream, + void (*done)(SkWStream*, bool) = NULL, + SkData* (*encoder)(size_t*, const SkBitmap&) = NULL, + SkScalar rasterDpi = 72.0); +#endif // PageCachingDocument_DEFINED diff --git a/experimental/tools/gmtoskp.cpp b/experimental/tools/gmtoskp.cpp index bafd3d3679..124c7f6760 100644 --- a/experimental/tools/gmtoskp.cpp +++ b/experimental/tools/gmtoskp.cpp @@ -28,7 +28,7 @@ DEFINE_string2(match, "If a GM does not match any list entry,\n" "it is skipped unless some list entry starts with ~"); -DEFINE_string2(writePath, w, "", "Write output here as .skps."); +DEFINE_string2(writePath, w, "", "Write output in this directory as .skps."); __SK_FORCE_IMAGE_DECODER_LINKING; @@ -49,11 +49,13 @@ int main(int argc, char** argv) { SkCommandLineFlags::SetUsage(""); SkCommandLineFlags::Parse(argc, argv); if (FLAGS_writePath.isEmpty()) { + SkDebugf("You need to specify a --writePath option"); return 1; } const char* writePath = FLAGS_writePath[0]; if (!sk_mkdir(writePath)) { - return 1; + + return 2; } for (const skiagm::GMRegistry* reg = skiagm::GMRegistry::Head(); reg != NULL; @@ -69,7 +71,7 @@ int main(int argc, char** argv) { SkFILEWStream outputStream(path.c_str()); if (!outputStream.isValid()) { SkDebugf("Could not open file %s\n", path.c_str()); - return 1; + return 3; } gmtoskp(gm, &outputStream); } diff --git a/experimental/tools/multipage_pdf_profiler.cpp b/experimental/tools/multipage_pdf_profiler.cpp index 93c8df9fb4..4f8eae2fb6 100644 --- a/experimental/tools/multipage_pdf_profiler.cpp +++ b/experimental/tools/multipage_pdf_profiler.cpp @@ -12,19 +12,16 @@ #include "SkPicture.h" #include "SkStream.h" #include "SkTemplates.h" +#include "PageCachingDocument.h" #include "ProcStats.h" #include "flags/SkCommandLineFlags.h" -#ifdef SK_ENABLE_NEW_SKPDF_BACKEND -#include "skpdf.h" -#endif - DEFINE_string2(readPath, r, "", "(Required) The path to a .skp Skia Picture file."); DEFINE_string2(writePath, w, "", "If set, write PDF output to this file."); -DEFINE_bool(newPdf, false, "Use the new PDF backend."); +DEFINE_bool(cachePages, false, "Use a PageCachingDocument."); DEFINE_bool(nullCanvas, true, "Render to a SkNullCanvas as a control."); __SK_FORCE_IMAGE_DECODER_LINKING; @@ -45,12 +42,11 @@ public: }; SkDocument* CreatePDFDocument(SkWStream* out) { -#ifdef SK_ENABLE_NEW_SKPDF_BACKEND - if (FLAGS_newPdf) { - return skpdf::CreatePDFDocument(out); + if (FLAGS_cachePages) { + return CreatePageCachingDocument(out); + } else { + return SkDocument::CreatePDF(out); } -#endif - return SkDocument::CreatePDF(out); } } // namespace @@ -119,7 +115,8 @@ int main(int argc, char** argv) { canvas->clipRect(letterRect); canvas->translate(SkIntToScalar(-kLetterWidth * x), SkIntToScalar(-kLetterHeight * y)); - canvas->drawPicture(picture); + picture->playback(canvas); + //canvas->drawPicture(picture); } canvas->flush(); if (!FLAGS_nullCanvas) { diff --git a/gm/smallimage.cpp b/gm/smallimage.cpp new file mode 100644 index 0000000000..6eb48d830d --- /dev/null +++ b/gm/smallimage.cpp @@ -0,0 +1,11 @@ +#include "Resources.h" +#include "gm.h" + +DEF_SIMPLE_GM(small_image, canvas, 8, 8) { + SkBitmap bitmap; + if (GetResourceAsBitmap("randPixels.png", &bitmap)) { + canvas->drawBitmap(bitmap, 0.0f, 0.0f); + } else { + SkDebugf("\nCould not decode resource.\n"); + } +} diff --git a/gyp/experimental.gyp b/gyp/experimental.gyp index 9e4e934744..87fe920371 100644 --- a/gyp/experimental.gyp +++ b/gyp/experimental.gyp @@ -79,6 +79,7 @@ 'type': 'executable', 'sources': [ '../experimental/tools/multipage_pdf_profiler.cpp', + '../experimental/tools/PageCachingDocument.cpp', ], 'dependencies': [ 'skia_lib.gyp:skia_lib', diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 5e1ae47fd0..bba3ea0661 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -170,6 +170,7 @@ '../gm/simpleaaclip.cpp', '../gm/skbug1719.cpp', '../gm/smallarc.cpp', + '../gm/smallimage.cpp', '../gm/stringart.cpp', '../gm/spritebitmap.cpp', '../gm/srcmode.cpp', -- 2.34.1