Enable automatic rescaling in bench_pictures
bench_pictures with "--device gpu" is failing because we're trying to allocate
too much GPU memory. Move the recently-added scaling code into picture_utils
and share it between render_pictures and bench_pictures.
Review URL: https://codereview.appspot.com/6495125
git-svn-id: http://skia.googlecode.com/svn/trunk@5543 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index 8edbb94..93b1cf9 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -109,17 +109,21 @@
return;
}
- SkPicture picture(&inputStream);
+ SkPicture* picture = SkNEW_ARGS(SkPicture, (&inputStream));
+ SkAutoTUnref<SkPicture> aur(picture);
SkString filename;
sk_tools::get_basename(&filename, inputPath);
SkString result;
- result.printf("running bench [%i %i] %s ", picture.width(), picture.height(),
- filename.c_str());
+ result.printf("running bench [%i %i] %s ", picture->width(),
+ picture->height(), filename.c_str());
gLogger.logProgress(result);
- benchmark.run(&picture);
+ // rescale to avoid memory issues allocating a very large offscreen
+ sk_tools::resize_if_needed(&aur);
+
+ benchmark.run(aur);
}
static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
diff --git a/tools/picture_utils.cpp b/tools/picture_utils.cpp
index b9bedbb..2dd1f4e 100644
--- a/tools/picture_utils.cpp
+++ b/tools/picture_utils.cpp
@@ -6,9 +6,11 @@
*/
#include "picture_utils.h"
+#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkBitmap.h"
#include "SkPicture.h"
+#include "SkRefCnt.h"
#include "SkString.h"
#include "SkStream.h"
@@ -90,4 +92,47 @@
bitmap->allocPixels();
bitmap->eraseColor(0);
}
+
+ 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;
+ }
+
+ void resize_if_needed(SkAutoTUnref<SkPicture>* aur) {
+ SkISize newSize;
+ SkPicture* picture = aur->get();
+ if (area_too_big(picture->width(), picture->height(), &newSize)) {
+ SkPicture* pic = SkNEW(SkPicture);
+ picture->ref();
+ 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());
+ picture->unref();
+ }
+ }
}
diff --git a/tools/picture_utils.h b/tools/picture_utils.h
index cca9431..db996ca 100644
--- a/tools/picture_utils.h
+++ b/tools/picture_utils.h
@@ -7,12 +7,15 @@
#ifndef picture_utils_DEFINED
#define picture_utils_DEFINED
-#include "SkTypes.h"
+#include "SkTypes.h"
+#include "SkSize.h"
+
+template <typename T> class SkAutoTUnref;
class SkBitmap;
class SkFILEStream;
-class SkString;
class SkPicture;
+class SkString;
namespace sk_tools {
// since PNG insists on unpremultiplying our alpha, we take no precision
@@ -41,6 +44,14 @@
// Specifically, it configures the bitmap, allocates pixels and then
// erases the pixels to transparent black.
void setup_bitmap(SkBitmap* bitmap, int width, int height);
+
+ // Determines whether the given dimensions are too large and suggests a new
+ // size.
+ bool area_too_big(int w, int h, SkISize* newSize);
+
+ // Determines whether the given SkPicture is too large and, if so, replaces
+ // it with a new, scaled-down SkPicture.
+ void resize_if_needed(SkAutoTUnref<SkPicture>* aur);
}
#endif // picture_utils_DEFINED
diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp
index 87d5d4b..7d54516 100644
--- a/tools/render_pictures_main.cpp
+++ b/tools/render_pictures_main.cpp
@@ -89,27 +89,6 @@
}
}
-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;
@@ -122,32 +101,16 @@
return;
}
- SkPicture picture(&inputStream);
+ SkPicture* picture = SkNEW_ARGS(SkPicture, (&inputStream));
+ SkAutoTUnref<SkPicture> aur(picture);
- SkDebugf("drawing... [%i %i] %s\n", picture.width(), picture.height(),
+ SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(),
inputPath.c_str());
+ // rescale to avoid memory issues allocating a very large offscreen
+ sk_tools::resize_if_needed(&aur);
- // 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.init(aur);
renderer.render(true);