Home | History | Annotate | Download | only in bench
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "Benchmark.h"
      9 #include "SkCanvas.h"
     10 #include "SkColor.h"
     11 #include "SkNullCanvas.h"
     12 #include "SkPaint.h"
     13 #include "SkPicture.h"
     14 #include "SkPictureRecorder.h"
     15 #include "SkString.h"
     16 
     17 class PictureNesting : public Benchmark {
     18 public:
     19     PictureNesting(const char* name, int maxLevel, int maxPictureLevel)
     20         : fMaxLevel(maxLevel)
     21         , fMaxPictureLevel(maxPictureLevel) {
     22         fName.printf("picture_nesting_%s_%d", name, this->countPics());
     23         fPaint.setColor(SK_ColorRED);
     24         fPaint.setAntiAlias(true);
     25         fPaint.setStyle(SkPaint::kStroke_Style);
     26     }
     27 
     28 protected:
     29     const char* onGetName() override {
     30         return fName.c_str();
     31     }
     32 
     33     void doDraw(SkCanvas* canvas) {
     34         SkIPoint canvasSize = onGetSize();
     35         canvas->save();
     36         canvas->scale(SkIntToScalar(canvasSize.x()), SkIntToScalar(canvasSize.y()));
     37 
     38         SkDEBUGCODE(int pics = ) this->sierpinsky(canvas, 0, fPaint);
     39         SkASSERT(pics == this->countPics());
     40 
     41         canvas->restore();
     42     }
     43 
     44     int sierpinsky(SkCanvas* canvas, int lvl, const SkPaint& paint) {
     45         if (++lvl > fMaxLevel) {
     46             return 0;
     47         }
     48 
     49         int pics = 0;
     50         bool recordPicture = lvl <= fMaxPictureLevel;
     51         SkPictureRecorder recorder;
     52         SkCanvas* c = canvas;
     53 
     54         if (recordPicture) {
     55             c = recorder.beginRecording(1, 1);
     56             pics++;
     57         }
     58 
     59         c->drawLine(0.5, 0, 0, 1, paint);
     60         c->drawLine(0.5, 0, 1, 1, paint);
     61         c->drawLine(0,   1, 1, 1, paint);
     62 
     63         c->save();
     64             c->scale(0.5, 0.5);
     65 
     66             c->translate(0, 1);
     67             pics += this->sierpinsky(c, lvl, paint);
     68 
     69             c->translate(1, 0);
     70             pics += this->sierpinsky(c, lvl, paint);
     71 
     72             c->translate(-0.5, -1);
     73             pics += this->sierpinsky(c, lvl, paint);
     74         c->restore();
     75 
     76         if (recordPicture) {
     77             SkAutoTUnref<SkPicture> picture(recorder.endRecording());
     78             canvas->drawPicture(picture);
     79         }
     80 
     81         return pics;
     82     }
     83 
     84     int fMaxLevel;
     85     int fMaxPictureLevel;
     86 
     87 private:
     88     int countPics() const {
     89         // Solve: pics from sierpinsky
     90         // f(m) = 1 + 3*f(m - 1)
     91         // f(0) = 0
     92         //   via "recursive function to closed form" tricks
     93         // f(m) = 1/2 (3^m - 1)
     94         int pics = 1;
     95         for (int i = 0; i < fMaxPictureLevel; i++) {
     96             pics *= 3;
     97         }
     98         pics--;
     99         pics /= 2;
    100         return pics;
    101     }
    102 
    103     SkString fName;
    104     SkPaint  fPaint;
    105 
    106     typedef Benchmark INHERITED;
    107 };
    108 
    109 class PictureNestingRecording : public PictureNesting {
    110 public:
    111     PictureNestingRecording(int maxLevel, int maxPictureLevel)
    112         : INHERITED("recording", maxLevel, maxPictureLevel) {
    113     }
    114 
    115 protected:
    116     bool isSuitableFor(Backend backend) override {
    117         return backend == kNonRendering_Backend;
    118     }
    119 
    120     void onDraw(int loops, SkCanvas*) override {
    121         SkIPoint canvasSize = onGetSize();
    122         SkPictureRecorder recorder;
    123 
    124         for (int i = 0; i < loops; i++) {
    125             SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
    126                                                   SkIntToScalar(canvasSize.y()));
    127             this->doDraw(c);
    128             SkAutoTUnref<SkPicture> picture(recorder.endRecording());
    129         }
    130     }
    131 
    132 private:
    133     typedef PictureNesting INHERITED;
    134 };
    135 
    136 class PictureNestingPlayback : public PictureNesting {
    137 public:
    138     PictureNestingPlayback(int maxLevel, int maxPictureLevel)
    139         : INHERITED("playback", maxLevel, maxPictureLevel) {
    140     }
    141 protected:
    142     void onDelayedSetup() override {
    143         this->INHERITED::onDelayedSetup();
    144 
    145         SkIPoint canvasSize = onGetSize();
    146         SkPictureRecorder recorder;
    147         SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
    148                                               SkIntToScalar(canvasSize.y()));
    149 
    150         this->doDraw(c);
    151         fPicture.reset(recorder.endRecording());
    152     }
    153 
    154     void onDraw(int loops, SkCanvas* canvas) override {
    155         for (int i = 0; i < loops; i++) {
    156             canvas->drawPicture(fPicture);
    157         }
    158     }
    159 
    160 private:
    161     SkAutoTUnref<SkPicture> fPicture;
    162 
    163     typedef PictureNesting INHERITED;
    164 };
    165 
    166 DEF_BENCH( return new PictureNestingRecording(8, 0); )
    167 DEF_BENCH( return new PictureNestingRecording(8, 1); )
    168 DEF_BENCH( return new PictureNestingRecording(8, 2); )
    169 DEF_BENCH( return new PictureNestingRecording(8, 3); )
    170 DEF_BENCH( return new PictureNestingRecording(8, 4); )
    171 DEF_BENCH( return new PictureNestingRecording(8, 5); )
    172 DEF_BENCH( return new PictureNestingRecording(8, 6); )
    173 DEF_BENCH( return new PictureNestingRecording(8, 7); )
    174 DEF_BENCH( return new PictureNestingRecording(8, 8); )
    175 
    176 DEF_BENCH( return new PictureNestingPlayback(8, 0); )
    177 DEF_BENCH( return new PictureNestingPlayback(8, 1); )
    178 DEF_BENCH( return new PictureNestingPlayback(8, 2); )
    179 DEF_BENCH( return new PictureNestingPlayback(8, 3); )
    180 DEF_BENCH( return new PictureNestingPlayback(8, 4); )
    181 DEF_BENCH( return new PictureNestingPlayback(8, 5); )
    182 DEF_BENCH( return new PictureNestingPlayback(8, 6); )
    183 DEF_BENCH( return new PictureNestingPlayback(8, 7); )
    184 DEF_BENCH( return new PictureNestingPlayback(8, 8); )
    185