From a5aaa7998fc18489701660f781d7daa33ffc6f6e Mon Sep 17 00:00:00 2001 From: "edisonn@google.com" Date: Thu, 11 Jul 2013 12:27:21 +0000 Subject: pdfviewer: measure mem usage, command line flags library. Review URL: https://codereview.chromium.org/18562010 git-svn-id: http://skia.googlecode.com/svn/trunk@9996 2bbb7eff-a529-9590-31e7-b0007b416f81 --- experimental/PdfViewer/SkPdfRenderer.cpp | 6 +- experimental/PdfViewer/pdf_viewer_main.cpp | 96 ++++++++-------------- .../pdfparser/native/SkNativeParsedPDF.cpp | 8 ++ .../PdfViewer/pdfparser/native/SkNativeParsedPDF.h | 5 +- .../pdfparser/native/SkPdfNativeTokenizer.cpp | 2 + .../pdfparser/native/SkPdfNativeTokenizer.h | 7 ++ 6 files changed, 58 insertions(+), 66 deletions(-) (limited to 'experimental') diff --git a/experimental/PdfViewer/SkPdfRenderer.cpp b/experimental/PdfViewer/SkPdfRenderer.cpp index 7c4b47465d..37867b42b7 100644 --- a/experimental/PdfViewer/SkPdfRenderer.cpp +++ b/experimental/PdfViewer/SkPdfRenderer.cpp @@ -16,7 +16,6 @@ #include "SkStream.h" #include "SkTypeface.h" #include "SkTArray.h" -#include "picture_utils.h" #include #include @@ -2013,3 +2012,8 @@ SkRect SkPdfRenderer::MediaBox(int page) const { SkASSERT(fPdfDoc); return fPdfDoc->MediaBox(page); } + +size_t SkPdfRenderer::bytesUsed() { + return fPdfDoc ? fPdfDoc->bytesUsed() : 0; +} + diff --git a/experimental/PdfViewer/pdf_viewer_main.cpp b/experimental/PdfViewer/pdf_viewer_main.cpp index cd95d7f0c5..0b3b1aa017 100644 --- a/experimental/PdfViewer/pdf_viewer_main.cpp +++ b/experimental/PdfViewer/pdf_viewer_main.cpp @@ -1,6 +1,6 @@ #include "SkCanvas.h" +#include "SkCommandLineFlags.h" #include "SkDevice.h" -#include "SkForceLinking.h" #include "SkGraphics.h" #include "SkImageDecoder.h" #include "SkImageEncoder.h" @@ -13,6 +13,11 @@ #include "SkPdfRenderer.h" +DEFINE_string2(readPath, r, "", "pdf files or directories of pdf files to process."); +DEFINE_string2(writePath, w, "", "Directory to write the rendered pages."); +DEFINE_bool2(noExtensionForOnePagePdf, n, false, "No page extension if only one page."); +DEFINE_bool2(showMemoryUsage, m, false, "Show Memory usage."); + /** * Given list of directories and files to use as input, expects to find .pdf * files and it will convert them to .png files writing them in the same directory @@ -25,24 +30,6 @@ static const char PDF_FILE_EXTENSION[] = "pdf"; static const char PNG_FILE_EXTENSION[] = "png"; -// TODO(edisonn): add ability to write to a new directory. -static void usage(const char* argv0) { - SkDebugf("PDF to PNG rendering tool\n"); - SkDebugf("\n" -"Usage: \n" -" %s ... [-w ] [-n | --no-page-ext] \n" -, argv0); - SkDebugf("\n\n"); - SkDebugf( -" input: A list of directories and files to use as input. Files are\n" -" expected to have the .skp extension.\n\n"); - SkDebugf( -" outputDir: directory to write the rendered pdfs.\n\n"); - SkDebugf( -" -n: no page extension if only one page.\n\n"); - SkDebugf("\n"); -} - /** Replaces the extension of a file. * @param path File name whose extension will be changed. * @param old_extension The old extension. @@ -144,7 +131,7 @@ static bool render_page(const SkString& outputDir, * @param renderer The object responsible to render the skp object into pdf. */ static bool process_pdf(const SkString& inputPath, const SkString& outputDir, - SkPdfRenderer& renderer, bool noPageExt) { + SkPdfRenderer& renderer, bool noPageExt, bool showMemoryUsage) { SkDebugf("Loading PDF: %s\n", inputPath.c_str()); SkString inputFilename; @@ -162,6 +149,9 @@ static bool process_pdf(const SkString& inputPath, const SkString& outputDir, success = renderer.load(inputPath); if (success) { + if (showMemoryUsage) { + SkDebugf("Memory usage after load: %u\n", (unsigned int)renderer.bytesUsed()); + } if (!renderer.pages()) { SkDebugf("ERROR: Empty PDF Document %s\n", inputPath.c_str()); @@ -169,6 +159,7 @@ static bool process_pdf(const SkString& inputPath, const SkString& outputDir, } else { for (int pn = 0; pn < renderer.pages(); ++pn) { success = render_page(outputDir, inputFilename, renderer, noPageExt && renderer.pages() == 1 ? -1 : pn) && success; + SkDebugf("Memory usage after page %i rendered: %u\n", pn, (unsigned int)renderer.bytesUsed()); } } } @@ -182,73 +173,52 @@ static bool process_pdf(const SkString& inputPath, const SkString& outputDir, * @param outputDir Output dir. * @param renderer The object responsible to render the skp object into pdf. */ -static int process_input(const SkString& input, const SkString& outputDir, - SkPdfRenderer& renderer, bool noPageExt) { +static int process_input(const char* input, const SkString& outputDir, + SkPdfRenderer& renderer, bool noPageExt, bool showMemoryUsage) { int failures = 0; - if (sk_isdir(input.c_str())) { - SkOSFile::Iter iter(input.c_str(), PDF_FILE_EXTENSION); + if (sk_isdir(input)) { + SkOSFile::Iter iter(input, PDF_FILE_EXTENSION); SkString inputFilename; while (iter.next(&inputFilename)) { SkString inputPath; - sk_tools::make_filepath(&inputPath, input, inputFilename); - if (!process_pdf(inputPath, outputDir, renderer, noPageExt)) { + SkString _input; + _input.append(input); + sk_tools::make_filepath(&inputPath, _input, inputFilename); + if (!process_pdf(inputPath, outputDir, renderer, noPageExt, showMemoryUsage)) { ++failures; } } } else { SkString inputPath(input); - if (!process_pdf(inputPath, outputDir, renderer, noPageExt)) { + if (!process_pdf(inputPath, outputDir, renderer, noPageExt, showMemoryUsage)) { ++failures; } } return failures; } -static void parse_commandline(int argc, char* const argv[], - SkTArray* inputs, - SkString* outputDir, bool* noPageExt) { - const char* argv0 = argv[0]; - char* const* stop = argv + argc; - - for (++argv; argv < stop; ++argv) { - if ((0 == strcmp(*argv, "-h")) || (0 == strcmp(*argv, "--help"))) { - usage(argv0); - exit(-1); - } else if ((0 == strcmp(*argv, "-n")) || (0 == strcmp(*argv, "--no-page-ext"))) { - *noPageExt = true; - } else if (0 == strcmp(*argv, "-w")) { - ++argv; - if (argv >= stop) { - SkDebugf("Missing outputDir for -w\n"); - usage(argv0); - exit(-1); - } - *outputDir = SkString(*argv); - } else { - inputs->push_back(SkString(*argv)); - } - } +int tool_main(int argc, char** argv); +int tool_main(int argc, char** argv) { + SkCommandLineFlags::SetUsage("Parse and Render .pdf files (pdf viewer)."); + SkCommandLineFlags::Parse(argc, argv); - if (inputs->count() < 1) { - usage(argv0); + if (FLAGS_readPath.isEmpty()) { + SkDebugf(".pdf files or directories are required.\n"); exit(-1); } -} - -int tool_main(int argc, char** argv); -int tool_main(int argc, char** argv) { - SkAutoGraphics ag; - SkTArray inputs; SkPdfRenderer renderer; SkString outputDir; - bool noPageExt = false; - parse_commandline(argc, argv, &inputs, &outputDir, &noPageExt); + if (FLAGS_writePath.count() == 1) { + outputDir.set(FLAGS_writePath[0]); + } int failures = 0; - for (int i = 0; i < inputs.count(); i ++) { - failures += process_input(inputs[i], outputDir, renderer, noPageExt); + for (int i = 0; i < FLAGS_readPath.count(); i ++) { + failures += process_input(FLAGS_readPath[i], outputDir, renderer, + FLAGS_noExtensionForOnePagePdf, + FLAGS_showMemoryUsage); renderer.unload(); } diff --git a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp index 8bd14ccfd1..bd46577322 100644 --- a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp +++ b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp @@ -416,3 +416,11 @@ SkPdfObject* SkNativeParsedPDF::resolveReference(const SkPdfObject* ref) { // TODO(edisonn): fix the mess with const, probably we need to remove it pretty much everywhere return (SkPdfObject*)ref; } + +size_t SkNativeParsedPDF::bytesUsed() { + return fAllocator->bytesUsed() + + fContentLength + + fObjects.count() * sizeof(PublicObjectEntry) + + fPages.count() * sizeof(SkPdfPageObjectDictionary*) + + sizeof(*this); +} diff --git a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h index f61114b9e1..48442fd2cb 100644 --- a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h +++ b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h @@ -17,8 +17,6 @@ class SkPdfCatalogDictionary; class SkPdfPageObjectDictionary; class SkPdfPageTreeNodeDictionary; - - class SkPdfNativeTokenizer; class SkNativeParsedPDF { @@ -63,6 +61,9 @@ public: SkPdfObject* resolveReference(const SkPdfObject* ref); + // Reports an approximation of all the memory usage. + size_t bytesUsed(); + private: unsigned char* readCrossReferenceSection(unsigned char* xrefStart, unsigned char* trailerEnd); diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp index 6caca8f295..de49e35f11 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp @@ -651,6 +651,7 @@ unsigned char* nextObject(unsigned char* start, unsigned char* end, SkPdfObject* } SkPdfObject* SkPdfAllocator::allocBlock() { + fSizeInBytes += BUFFER_SIZE * sizeof(SkPdfObject); return new SkPdfObject[BUFFER_SIZE]; } @@ -675,6 +676,7 @@ SkPdfObject* SkPdfAllocator::allocObject() { fHistory.push(fCurrent); fCurrent = allocBlock(); fCurrentUsed = 0; + fSizeInBytes += sizeof(SkPdfObject*); } fCurrentUsed++; return &fCurrent[fCurrentUsed - 1]; diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h index 333d9dc265..f544ff3bc1 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h @@ -83,9 +83,11 @@ class SkPdfAllocator { int fCurrentUsed; SkPdfObject* allocBlock(); + size_t fSizeInBytes; public: SkPdfAllocator() { + fSizeInBytes = sizeof(*this); fCurrent = allocBlock(); fCurrentUsed = 0; } @@ -98,8 +100,13 @@ public: void* alloc(size_t bytes) { void* data = malloc(bytes); fHandles.push(data); + fSizeInBytes += bytes; return data; } + + size_t bytesUsed() { + return fSizeInBytes; + } }; class SkNativeParsedPDF; -- cgit v1.2.3