#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkPictureRecorder.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);
}
virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
return backend == kNonRendering_Backend;
}
enum {
PICTURE_WIDTH = 1000,
PICTURE_HEIGHT = 4000,
};
protected:
virtual const char* onGetName() SK_OVERRIDE {
return fName.c_str();
}
private:
SkString fName;
typedef SkBenchmark INHERITED;
};
static const int kMaxLoopsPerCanvas = 10000;
class DictionaryRecordBench : public PictureRecordBench {
public:
DictionaryRecordBench() : INHERITED("dictionaries") {}
protected:
virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
SkPictureRecorder recorder;
SkCanvas* canvas = NULL;
const SkPoint translateDelta = getTranslateDelta(loops);
for (int i = 0; i < loops; i++) {
if (0 == i % kMaxLoopsPerCanvas) {
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
}
SkColor color = SK_ColorYELLOW + (i % 255);
SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
canvas->save();
SkRegion region;
region.setRect(rect);
canvas->clipRegion(region);
SkPaint paint;
paint.setColor(color);
canvas->drawPaint(paint);
SkMatrix matrix;
matrix.setRotate(SkIntToScalar(i % 360));
canvas->setMatrix(matrix);
SkBitmap bitmap;
bitmap.allocPixels(SkImageInfo::Make(10, 10,
kRGB_565_SkColorType, kOpaque_SkAlphaType));
SkCanvas bitmapCanvas(bitmap);
bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
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;
};
class UniquePaintDictionaryRecordBench : public PictureRecordBench {
public:
UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") { }
protected:
virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
SkRandom rand;
SkPaint paint;
SkPictureRecorder recorder;
SkCanvas* canvas = NULL;
for (int i = 0; i < loops; i++) {
if (0 == i % kMaxLoopsPerCanvas) {
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
}
paint.setColor(rand.nextU());
canvas->drawPaint(paint);
}
}
private:
typedef PictureRecordBench INHERITED;
};
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, };
protected:
virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
for (int i = 0; i < loops; 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(); )