From e04e92b19f050892c2770da955e4c931e0ef698b Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Thu, 13 Sep 2012 17:44:32 +0000 Subject: To avoid running out of memory, we rescale very large pictures before we render them. Review URL: https://codereview.appspot.com/6504045 git-svn-id: http://skia.googlecode.com/svn/trunk@5530 2bbb7eff-a529-9590-31e7-b0007b416f81 --- tools/render_pictures_main.cpp | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'tools/render_pictures_main.cpp') diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp index 5ec2ede3e7..613ec94c03 100644 --- a/tools/render_pictures_main.cpp +++ b/tools/render_pictures_main.cpp @@ -89,6 +89,27 @@ static void write_output(const SkString& outputDir, const SkString& inputFilenam } } +static bool area_too_big(int w, int h, SkISize* newSize) { + // just a guess, based on what seems to fail on smaller android devices + static const int64_t kMaxAreaForMemory = 16 * 1024 * 1024; + + if ((int64_t)w * h > kMaxAreaForMemory) { + do { + w >>= 1; + h >>= 1; + } while ((int64_t)w * h > kMaxAreaForMemory); + if (0 == w) { + w = 1; + } + if (0 == h) { + h = 1; + } + newSize->set(w, h); + return true; + } + return false; +} + static void render_picture(const SkString& inputPath, const SkString& outputDir, sk_tools::PictureRenderer& renderer) { SkString inputFilename; @@ -105,7 +126,28 @@ static void render_picture(const SkString& inputPath, const SkString& outputDir, SkDebugf("drawing... [%i %i] %s\n", picture.width(), picture.height(), inputPath.c_str()); - renderer.init(&picture); + + + // rescale to avoid memory issues allcoating a very large offscreen + SkPicture* pic = &picture; + SkISize newSize; + SkAutoUnref aur(NULL); + + if (area_too_big(picture.width(), picture.height(), &newSize)) { + pic = new SkPicture; + aur.reset(pic); + + SkCanvas* canvas = pic->beginRecording(newSize.width(), newSize.height()); + SkScalar scale = SkIntToScalar(newSize.width()) / picture.width(); + canvas->scale(scale, scale); + canvas->drawPicture(picture); + pic->endRecording(); + + SkDebugf("... rescaling to [%d %d] to avoid overly large allocations\n", + newSize.width(), newSize.height()); + } + + renderer.init(pic); renderer.render(true); -- cgit v1.2.3