зеркало из https://github.com/mozilla/moz-skia.git
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
This commit is contained in:
Родитель
71e21ba2af
Коммит
e21795e277
|
@ -143,6 +143,7 @@
|
|||
'type': 'static_library',
|
||||
'sources': [
|
||||
'../tools/picture_utils.cpp',
|
||||
'../tools/picture_utils.h',
|
||||
],
|
||||
'dependencies': [
|
||||
'core.gyp:core',
|
||||
|
|
|
@ -109,17 +109,21 @@ static void run_single_benchmark(const SkString& inputPath,
|
|||
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,
|
||||
|
|
|
@ -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 @@ namespace sk_tools {
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 @@ namespace sk_tools {
|
|||
// 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
|
||||
|
|
|
@ -89,27 +89,6 @@ 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;
|
||||
|
@ -122,32 +101,16 @@ static void render_picture(const SkString& inputPath, const SkString& outputDir,
|
|||
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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче