diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-09-13 17:44:32 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-09-13 17:44:32 +0000 |
commit | e04e92b19f050892c2770da955e4c931e0ef698b (patch) | |
tree | 0b37228d11fb421fdaeaf6d97bc9e5ed19f54d66 /tools | |
parent | 83187a2737e8aec35d572dab09dae5638a3ee3e3 (diff) |
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
Diffstat (limited to 'tools')
-rw-r--r-- | tools/render_pictures_main.cpp | 44 |
1 files changed, 43 insertions, 1 deletions
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); |