2014-09-15 23:46:16 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Benchmark.h"
|
|
|
|
#include "SkCanvas.h"
|
|
|
|
#include "SkColor.h"
|
|
|
|
#include "SkNullCanvas.h"
|
|
|
|
#include "SkPaint.h"
|
|
|
|
#include "SkPicture.h"
|
|
|
|
#include "SkPictureRecorder.h"
|
|
|
|
#include "SkString.h"
|
|
|
|
|
|
|
|
class PictureNesting : public Benchmark {
|
|
|
|
public:
|
|
|
|
PictureNesting(const char* name, int maxLevel, int maxPictureLevel)
|
|
|
|
: fMaxLevel(maxLevel)
|
|
|
|
, fMaxPictureLevel(maxPictureLevel) {
|
2014-11-18 12:50:50 +00:00
|
|
|
fName.printf("picture_nesting_%s_%d", name, this->countPics());
|
2014-09-15 23:46:16 +00:00
|
|
|
fPaint.setColor(SK_ColorRED);
|
|
|
|
fPaint.setAntiAlias(true);
|
|
|
|
fPaint.setStyle(SkPaint::kStroke_Style);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2015-03-26 01:17:31 +00:00
|
|
|
const char* onGetName() override {
|
2014-09-15 23:46:16 +00:00
|
|
|
return fName.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void doDraw(SkCanvas* canvas) {
|
|
|
|
SkIPoint canvasSize = onGetSize();
|
|
|
|
canvas->save();
|
|
|
|
canvas->scale(SkIntToScalar(canvasSize.x()), SkIntToScalar(canvasSize.y()));
|
|
|
|
|
2014-11-18 12:50:50 +00:00
|
|
|
SkDEBUGCODE(int pics = ) this->sierpinsky(canvas, 0, fPaint);
|
|
|
|
SkASSERT(pics == this->countPics());
|
2014-09-15 23:46:16 +00:00
|
|
|
|
|
|
|
canvas->restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
int sierpinsky(SkCanvas* canvas, int lvl, const SkPaint& paint) {
|
|
|
|
if (++lvl > fMaxLevel) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pics = 0;
|
|
|
|
bool recordPicture = lvl <= fMaxPictureLevel;
|
|
|
|
SkPictureRecorder recorder;
|
|
|
|
SkCanvas* c = canvas;
|
|
|
|
|
|
|
|
if (recordPicture) {
|
|
|
|
c = recorder.beginRecording(1, 1);
|
|
|
|
pics++;
|
|
|
|
}
|
|
|
|
|
|
|
|
c->drawLine(0.5, 0, 0, 1, paint);
|
|
|
|
c->drawLine(0.5, 0, 1, 1, paint);
|
|
|
|
c->drawLine(0, 1, 1, 1, paint);
|
|
|
|
|
|
|
|
c->save();
|
|
|
|
c->scale(0.5, 0.5);
|
|
|
|
|
|
|
|
c->translate(0, 1);
|
|
|
|
pics += this->sierpinsky(c, lvl, paint);
|
|
|
|
|
|
|
|
c->translate(1, 0);
|
|
|
|
pics += this->sierpinsky(c, lvl, paint);
|
|
|
|
|
|
|
|
c->translate(-0.5, -1);
|
|
|
|
pics += this->sierpinsky(c, lvl, paint);
|
|
|
|
c->restore();
|
|
|
|
|
|
|
|
if (recordPicture) {
|
|
|
|
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
|
|
|
|
canvas->drawPicture(picture);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pics;
|
|
|
|
}
|
|
|
|
|
|
|
|
int fMaxLevel;
|
|
|
|
int fMaxPictureLevel;
|
|
|
|
|
|
|
|
private:
|
2014-11-18 12:50:50 +00:00
|
|
|
int countPics() const {
|
|
|
|
// Solve: pics from sierpinsky
|
|
|
|
// f(m) = 1 + 3*f(m - 1)
|
|
|
|
// f(0) = 0
|
|
|
|
// via "recursive function to closed form" tricks
|
|
|
|
// f(m) = 1/2 (3^m - 1)
|
2015-01-09 16:33:36 +00:00
|
|
|
int pics = 1;
|
|
|
|
for (int i = 0; i < fMaxPictureLevel; i++) {
|
|
|
|
pics *= 3;
|
|
|
|
}
|
|
|
|
pics--;
|
|
|
|
pics /= 2;
|
|
|
|
return pics;
|
2014-11-18 12:50:50 +00:00
|
|
|
}
|
|
|
|
|
2014-09-15 23:46:16 +00:00
|
|
|
SkString fName;
|
|
|
|
SkPaint fPaint;
|
|
|
|
|
|
|
|
typedef Benchmark INHERITED;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PictureNestingRecording : public PictureNesting {
|
|
|
|
public:
|
|
|
|
PictureNestingRecording(int maxLevel, int maxPictureLevel)
|
|
|
|
: INHERITED("recording", maxLevel, maxPictureLevel) {
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2015-07-13 13:18:39 +00:00
|
|
|
bool isSuitableFor(Backend backend) override {
|
2014-09-16 17:12:42 +00:00
|
|
|
return backend == kNonRendering_Backend;
|
|
|
|
}
|
|
|
|
|
2015-10-01 16:43:39 +00:00
|
|
|
void onDraw(int loops, SkCanvas*) override {
|
2014-09-15 23:46:16 +00:00
|
|
|
SkIPoint canvasSize = onGetSize();
|
|
|
|
SkPictureRecorder recorder;
|
|
|
|
|
|
|
|
for (int i = 0; i < loops; i++) {
|
|
|
|
SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
|
|
|
|
SkIntToScalar(canvasSize.y()));
|
|
|
|
this->doDraw(c);
|
|
|
|
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
typedef PictureNesting INHERITED;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PictureNestingPlayback : public PictureNesting {
|
|
|
|
public:
|
|
|
|
PictureNestingPlayback(int maxLevel, int maxPictureLevel)
|
|
|
|
: INHERITED("playback", maxLevel, maxPictureLevel) {
|
2014-11-18 12:50:50 +00:00
|
|
|
}
|
|
|
|
protected:
|
2015-09-30 19:11:07 +00:00
|
|
|
void onDelayedSetup() override {
|
|
|
|
this->INHERITED::onDelayedSetup();
|
2014-09-15 23:46:16 +00:00
|
|
|
|
|
|
|
SkIPoint canvasSize = onGetSize();
|
|
|
|
SkPictureRecorder recorder;
|
|
|
|
SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
|
|
|
|
SkIntToScalar(canvasSize.y()));
|
|
|
|
|
|
|
|
this->doDraw(c);
|
|
|
|
fPicture.reset(recorder.endRecording());
|
|
|
|
}
|
|
|
|
|
2015-10-01 16:43:39 +00:00
|
|
|
void onDraw(int loops, SkCanvas* canvas) override {
|
2014-09-15 23:46:16 +00:00
|
|
|
for (int i = 0; i < loops; i++) {
|
|
|
|
canvas->drawPicture(fPicture);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
SkAutoTUnref<SkPicture> fPicture;
|
|
|
|
|
|
|
|
typedef PictureNesting INHERITED;
|
|
|
|
};
|
|
|
|
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 0); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 1); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 2); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 3); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 4); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 5); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 6); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 7); )
|
|
|
|
DEF_BENCH( return new PictureNestingRecording(8, 8); )
|
|
|
|
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 0); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 1); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 2); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 3); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 4); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 5); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 6); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 7); )
|
|
|
|
DEF_BENCH( return new PictureNestingPlayback(8, 8); )
|