You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.2 KiB
183 lines
5.2 KiB
/* |
|
* 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) { |
|
fName.printf("picture_nesting_%s_%d", name, this->countPics()); |
|
fPaint.setColor(SK_ColorRED); |
|
fPaint.setAntiAlias(true); |
|
fPaint.setStyle(SkPaint::kStroke_Style); |
|
} |
|
|
|
protected: |
|
const char* onGetName() override { |
|
return fName.c_str(); |
|
} |
|
|
|
void doDraw(SkCanvas* canvas) { |
|
SkIPoint canvasSize = onGetSize(); |
|
canvas->save(); |
|
canvas->scale(SkIntToScalar(canvasSize.x()), SkIntToScalar(canvasSize.y())); |
|
|
|
SkDEBUGCODE(int pics = ) this->sierpinsky(canvas, 0, fPaint); |
|
SkASSERT(pics == this->countPics()); |
|
|
|
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) { |
|
canvas->drawPicture(recorder.finishRecordingAsPicture()); |
|
} |
|
|
|
return pics; |
|
} |
|
|
|
int fMaxLevel; |
|
int fMaxPictureLevel; |
|
|
|
private: |
|
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) |
|
int pics = 1; |
|
for (int i = 0; i < fMaxPictureLevel; i++) { |
|
pics *= 3; |
|
} |
|
pics--; |
|
pics /= 2; |
|
return pics; |
|
} |
|
|
|
SkString fName; |
|
SkPaint fPaint; |
|
|
|
typedef Benchmark INHERITED; |
|
}; |
|
|
|
class PictureNestingRecording : public PictureNesting { |
|
public: |
|
PictureNestingRecording(int maxLevel, int maxPictureLevel) |
|
: INHERITED("recording", maxLevel, maxPictureLevel) { |
|
} |
|
|
|
protected: |
|
bool isSuitableFor(Backend backend) override { |
|
return backend == kNonRendering_Backend; |
|
} |
|
|
|
void onDraw(int loops, SkCanvas*) override { |
|
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); |
|
(void)recorder.finishRecordingAsPicture(); |
|
} |
|
} |
|
|
|
private: |
|
typedef PictureNesting INHERITED; |
|
}; |
|
|
|
class PictureNestingPlayback : public PictureNesting { |
|
public: |
|
PictureNestingPlayback(int maxLevel, int maxPictureLevel) |
|
: INHERITED("playback", maxLevel, maxPictureLevel) { |
|
} |
|
protected: |
|
void onDelayedSetup() override { |
|
this->INHERITED::onDelayedSetup(); |
|
|
|
SkIPoint canvasSize = onGetSize(); |
|
SkPictureRecorder recorder; |
|
SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()), |
|
SkIntToScalar(canvasSize.y())); |
|
|
|
this->doDraw(c); |
|
fPicture = recorder.finishRecordingAsPicture(); |
|
} |
|
|
|
void onDraw(int loops, SkCanvas* canvas) override { |
|
for (int i = 0; i < loops; i++) { |
|
canvas->drawPicture(fPicture); |
|
} |
|
} |
|
|
|
private: |
|
sk_sp<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); )
|
|
|