aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-13 17:44:32 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-13 17:44:32 +0000
commite04e92b19f050892c2770da955e4c931e0ef698b (patch)
tree0b37228d11fb421fdaeaf6d97bc9e5ed19f54d66 /tools
parent83187a2737e8aec35d572dab09dae5638a3ee3e3 (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.cpp44
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);