Adding rtree support to the bench_pictures utility

Review URL: https://codereview.appspot.com/6775080

git-svn-id: http://skia.googlecode.com/svn/trunk@6267 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
junov@chromium.org 2012-11-02 18:11:49 +00:00
parent ea5d8af9fb
commit 9313ca4bde
4 changed files with 120 additions and 6 deletions

View File

@ -106,6 +106,7 @@
'../src/pipe/utils/SamplePipeControllers.cpp',
],
'include_dirs': [
'../src/core/',
'../src/pipe/utils/',
'../src/utils/',
],

View File

@ -18,6 +18,7 @@
#include "SkImageEncoder.h"
#include "SkMatrix.h"
#include "SkPicture.h"
#include "SkRTree.h"
#include "SkScalar.h"
#include "SkString.h"
#include "SkTemplates.h"
@ -45,6 +46,7 @@ void PictureRenderer::init(SkPicture* pict) {
}
fPicture = pict;
fPicture->ref();
fCanvas.reset(this->setupCanvas());
}
@ -78,10 +80,28 @@ SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
void PictureRenderer::end() {
this->resetState();
SkSafeUnref(fPicture);
fPicture = NULL;
fCanvas.reset(NULL);
}
/** Converts fPicture to a picture that uses a BBoxHierarchy.
* PictureRenderer subclasses that are used to test picture playback
* should call this method during init.
*/
void PictureRenderer::buildBBoxHierarchy() {
SkASSERT(NULL != fPicture);
if (kNone_BBoxHierarchyType != fBBoxHierarchyType && NULL != fPicture) {
SkPicture* newPicture = this->createPicture();
SkCanvas* recorder = newPicture->beginRecording(fPicture->width(), fPicture->height(),
this->recordFlags());
fPicture->draw(recorder);
newPicture->endRecording();
fPicture->unref();
fPicture = newPicture;
}
}
void PictureRenderer::resetState() {
#if SK_SUPPORT_GPU
if (this->isUsingGpuDevice()) {
@ -99,6 +119,11 @@ void PictureRenderer::resetState() {
#endif
}
uint32_t PictureRenderer::recordFlags() {
return kNone_BBoxHierarchyType == fBBoxHierarchyType ? 0 :
SkPicture::kOptimizeForClippedPlayback_RecordingFlag;
}
/**
* Write the canvas to the specified path.
* @param canvas Must be non-null. Canvas to be written to a file.
@ -140,10 +165,11 @@ static bool writeAppendNumber(SkCanvas* canvas, const SkString* path, int number
///////////////////////////////////////////////////////////////////////////////////////////////
bool RecordPictureRenderer::render(const SkString*) {
SkPicture replayer;
SkCanvas* recorder = replayer.beginRecording(fPicture->width(), fPicture->height());
SkAutoTUnref<SkPicture> replayer(this->createPicture());
SkCanvas* recorder = replayer->beginRecording(fPicture->width(), fPicture->height(),
this->recordFlags());
fPicture->draw(recorder);
replayer.endRecording();
replayer->endRecording();
// Since this class does not actually render, return false.
return false;
}
@ -171,6 +197,11 @@ bool PipePictureRenderer::render(const SkString* path) {
///////////////////////////////////////////////////////////////////////////////////////////////
void SimplePictureRenderer::init(SkPicture* picture) {
INHERITED::init(picture);
this->buildBBoxHierarchy();
}
bool SimplePictureRenderer::render(const SkString* path) {
SkASSERT(fCanvas.get() != NULL);
SkASSERT(fPicture != NULL);
@ -210,6 +241,10 @@ void TiledPictureRenderer::init(SkPicture* pict) {
// Do not call INHERITED::init(), which would create a (potentially large) canvas which is not
// used by bench_pictures.
fPicture = pict;
fPicture->ref();
if (!fUsePipe) {
this->buildBBoxHierarchy();
}
if (fTileWidthPercentage > 0) {
fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
@ -521,14 +556,42 @@ SkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) {
///////////////////////////////////////////////////////////////////////////////////////////////
void PlaybackCreationRenderer::setup() {
SkCanvas* recorder = fReplayer.beginRecording(fPicture->width(), fPicture->height());
fReplayer.reset(this->createPicture());
SkCanvas* recorder = fReplayer->beginRecording(fPicture->width(), fPicture->height(),
this->recordFlags());
fPicture->draw(recorder);
}
bool PlaybackCreationRenderer::render(const SkString*) {
fReplayer.endRecording();
fReplayer->endRecording();
// Since this class does not actually render, return false.
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// SkPicture variants for each BBoxHierarchy type
class RTreePicture : public SkPicture {
public:
virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE{
static const int kRTreeMinChildren = 6;
static const int kRTreeMaxChildren = 11;
SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(fWidth),
SkIntToScalar(fHeight));
return SkRTree::Create(kRTreeMinChildren, kRTreeMaxChildren,
aspectRatio);
}
};
SkPicture* PictureRenderer::createPicture() {
switch (fBBoxHierarchyType) {
case kNone_BBoxHierarchyType:
return SkNEW(SkPicture);
case kRTree_BBoxHierarchyType:
return SkNEW(RTreePicture);
}
SkASSERT(0); // invalid bbhType
return NULL;
}
} // namespace sk_tools

View File

@ -36,6 +36,11 @@ public:
#endif
};
enum BBoxHierarchyType {
kNone_BBoxHierarchyType = 0,
kRTree_BBoxHierarchyType,
};
virtual void init(SkPicture* pict);
/**
@ -62,6 +67,10 @@ public:
fDeviceType = deviceType;
}
void setBBoxHierarchyType(BBoxHierarchyType bbhType) {
fBBoxHierarchyType = bbhType;
}
bool isUsingBitmapDevice() {
return kBitmap_DeviceType == fDeviceType;
}
@ -97,12 +106,17 @@ public:
{}
protected:
void buildBBoxHierarchy();
SkPicture* createPicture();
uint32_t recordFlags();
SkCanvas* setupCanvas();
virtual SkCanvas* setupCanvas(int width, int height);
SkAutoTUnref<SkCanvas> fCanvas;
SkPicture* fPicture;
SkDeviceTypes fDeviceType;
BBoxHierarchyType fBBoxHierarchyType;
#if SK_SUPPORT_GPU
GrContextFactory fGrContextFactory;
@ -135,6 +149,8 @@ private:
class SimplePictureRenderer : public PictureRenderer {
public:
virtual void init(SkPicture* pict) SK_OVERRIDE;
virtual bool render(const SkString*) SK_OVERRIDE;
private:
@ -255,7 +271,7 @@ public:
virtual SkString getNormalTimeFormat() SK_OVERRIDE { return SkString("%6.4f"); }
private:
SkPicture fReplayer;
SkAutoTUnref<SkPicture> fReplayer;
typedef PictureRenderer INHERITED;
};

View File

@ -30,6 +30,7 @@ static void usage(const char* argv0) {
" [--mode pow2tile minWidth height[] | record | simple\n"
" | tile width[] height[] | playbackCreation]\n"
" [--pipe]\n"
" [--bbh bbhType]\n"
" [--multi numThreads]\n"
" [--device bitmap"
#if SK_SUPPORT_GPU
@ -77,6 +78,10 @@ static void usage(const char* argv0) {
" than 1. Only works with tiled rendering.\n"
" --pipe: Benchmark SkGPipe rendering. Compatible with tiled, multithreaded rendering.\n");
SkDebugf(
" --bbh bbhType: Set the bounding box hierarchy type to be used. Accepted\n"
" values are: none, rtree. Default value is none.\n"
" Not compatible with --pipe.\n");
SkDebugf(
" --device bitmap"
#if SK_SUPPORT_GPU
" | gpu"
@ -156,6 +161,8 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
const char* heightString = NULL;
bool isPowerOf2Mode = false;
const char* mode = NULL;
sk_tools::PictureRenderer::BBoxHierarchyType bbhType =
sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
for (++argv; argv < stop; ++argv) {
if (0 == strcmp(*argv, "--repeat")) {
++argv;
@ -203,6 +210,25 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
usage(argv0);
exit(-1);
}
} else if (0 == strcmp(*argv, "--bbh")) {
++argv;
if (argv >= stop) {
gLogger.logError("Missing value for --bbh\n");
usage(argv0);
exit(-1);
}
if (0 == strcmp(*argv, "none")) {
bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
} else if (0 == strcmp(*argv, "rtree")) {
bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType;
} else {
SkString err;
err.printf("%s is not a valid value for --bbhType\n", *argv);
gLogger.logError(err);
usage(argv0);
exit(-1);
}
} else if (0 == strcmp(*argv, "--mode")) {
++argv;
@ -336,6 +362,12 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
exit(-1);
}
if (usePipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) {
gLogger.logError("--pipe and --bbh cannot be used together\n");
usage(argv0);
exit(-1);
}
if (useTiles) {
SkASSERT(NULL == renderer);
sk_tools::TiledPictureRenderer* tiledRenderer = SkNEW(sk_tools::TiledPictureRenderer);
@ -411,6 +443,8 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
if (NULL == renderer) {
renderer = SkNEW(sk_tools::SimplePictureRenderer);
}
renderer->setBBoxHierarchyType(bbhType);
benchmark->setRenderer(renderer)->unref();
benchmark->setRepeats(repeats);
benchmark->setDeviceType(deviceType);