skia2/bench/PictureRecordBench.cpp

182 lines
5.1 KiB
C++
Raw Normal View History

/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkPoint.h"
#include "SkRandom.h"
#include "SkRect.h"
#include "SkString.h"
class PictureRecordBench : public SkBenchmark {
public:
PictureRecordBench(const char name[]) {
fName.printf("picture_record_%s", name);
fPictureWidth = SkIntToScalar(PICTURE_WIDTH);
fPictureHeight = SkIntToScalar(PICTURE_HEIGHT);
fIsRendering = false;
}
enum {
PICTURE_WIDTH = 1000,
PICTURE_HEIGHT = 4000,
};
protected:
virtual const char* onGetName() {
return fName.c_str();
}
virtual void onDraw(SkCanvas*) {
SkPicture picture;
SkCanvas* pCanvas = picture.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
recordCanvas(pCanvas);
// we don't need to draw the picture as the endRecording step will
// do the work of transferring the recorded content into a playback
// object.
picture.endRecording();
}
virtual void recordCanvas(SkCanvas* canvas) = 0;
SkString fName;
SkScalar fPictureWidth;
SkScalar fPictureHeight;
SkScalar fTextSize;
private:
typedef SkBenchmark INHERITED;
};
/*
* An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
* and regions. This bench populates those dictionaries to test the speed of
* reading and writing to those particular dictionary data structures.
*/
class DictionaryRecordBench : public PictureRecordBench {
public:
DictionaryRecordBench()
: INHERITED("dictionaries") { }
protected:
virtual void recordCanvas(SkCanvas* canvas) {
const SkPoint translateDelta = getTranslateDelta(this->getLoops());
for (int i = 0; i < this->getLoops(); i++) {
SkColor color = SK_ColorYELLOW + (i % 255);
SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
canvas->save();
// set the clip to the given region
SkRegion region;
region.setRect(rect);
canvas->clipRegion(region);
// fill the clip with a color
SkPaint paint;
paint.setColor(color);
canvas->drawPaint(paint);
// set a matrix on the canvas
SkMatrix matrix;
matrix.setRotate(SkIntToScalar(i % 360));
canvas->setMatrix(matrix);
// create a simple bitmap
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kRGB_565_Config, 10, 10);
bitmap.allocPixels();
// draw a single color into the bitmap
SkCanvas bitmapCanvas(bitmap);
bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
// draw the bitmap onto the canvas
canvas->drawBitmapMatrix(bitmap, matrix);
canvas->restore();
canvas->translate(translateDelta.fX, translateDelta.fY);
}
}
SkPoint getTranslateDelta(int M) {
SkIPoint canvasSize = onGetSize();
return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
}
private:
typedef PictureRecordBench INHERITED;
};
/*
* Populates the SkPaint dictionary with a large number of unique paint
* objects that differ only by color
*/
class UniquePaintDictionaryRecordBench : public PictureRecordBench {
public:
UniquePaintDictionaryRecordBench()
: INHERITED("unique_paint_dictionary") { }
protected:
virtual void recordCanvas(SkCanvas* canvas) {
SkRandom rand;
for (int i = 0; i < this->getLoops(); i++) {
SkPaint paint;
paint.setColor(rand.nextU());
canvas->drawPaint(paint);
}
}
private:
typedef PictureRecordBench INHERITED;
};
/*
* Populates the SkPaint dictionary with a number of unique paint
* objects that get reused repeatedly.
*
* Re-creating the paint objects in the inner loop slows the benchmark down 10%.
* Using setColor(i % objCount) instead of a random color creates a very high rate
* of hash conflicts, slowing us down 12%.
*/
class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
public:
RecurringPaintDictionaryRecordBench()
: INHERITED("recurring_paint_dictionary") {
SkRandom rand;
for (int i = 0; i < ObjCount; i++) {
fPaint[i].setColor(rand.nextU());
}
}
enum {
ObjCount = 100, // number of unique paint objects
};
protected:
virtual void recordCanvas(SkCanvas* canvas) {
for (int i = 0; i < this->getLoops(); i++) {
canvas->drawPaint(fPaint[i % ObjCount]);
}
}
private:
SkPaint fPaint [ObjCount];
typedef PictureRecordBench INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
DEF_BENCH( return new DictionaryRecordBench(); )
DEF_BENCH( return new UniquePaintDictionaryRecordBench(); )
DEF_BENCH( return new RecurringPaintDictionaryRecordBench(); )