Home | History | Annotate | Download | only in bench
      1 /*
      2  * Copyright 2017 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 "SkGlyphCache.h"
     11 #include "SkPaint.h"
     12 #include "SkPath.h"
     13 #include "SkRandom.h"
     14 
     15 static constexpr int kScreenWidth = 1500;
     16 static constexpr int kScreenHeight = 1500;
     17 
     18 static constexpr int kNumDraws = 2000;
     19 
     20 // I and l are rects on OS X.
     21 static constexpr char kGlyphs[] =  "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
     22 static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
     23 static_assert(52 == kNumGlyphs, "expected 52 glyphs");
     24 
     25 /*
     26  * This class benchmarks drawing many glyphs at random scales and rotations.
     27  */
     28 class PathTextBench : public Benchmark {
     29 public:
     30     bool isVisual() override { return true; }
     31 
     32 private:
     33     const char* onGetName() override {
     34         return "path_text";
     35     }
     36     SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
     37 
     38     void onDelayedSetup() override {
     39         SkPaint defaultPaint;
     40         SkAutoGlyphCache agc(defaultPaint, nullptr, &SkMatrix::I());
     41         SkGlyphCache* cache = agc.getCache();
     42         for (int i = 0; i < kNumGlyphs; ++i) {
     43             SkGlyphID id = cache->unicharToGlyph(kGlyphs[i]);
     44             cache->getScalerContext()->getPath(SkPackedGlyphID(id), &fGlyphs[i]);
     45         }
     46 
     47         SkRandom rand;
     48         for (int i = 0; i < kNumDraws; ++i) {
     49             const SkPath& glyph = fGlyphs[i % kNumGlyphs];
     50             const SkRect& bounds = glyph.getBounds();
     51             float glyphSize = SkTMax(bounds.width(), bounds.height());
     52 
     53             float t0 = pow(rand.nextF(), 100);
     54             float size = (1 - t0) * SkTMin(kScreenWidth, kScreenHeight) / 50 +
     55                          t0 * SkTMin(kScreenWidth, kScreenHeight) / 3;
     56             float scale = size / glyphSize;
     57             float t1 = rand.nextF(), t2 = rand.nextF();
     58             fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
     59                                      t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
     60                                      (1 - t2) * sqrt(2) * scale/2 * glyphSize +
     61                                      t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
     62             fXforms[i].preRotate(rand.nextF() * 360);
     63             fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
     64             fXforms[i].preScale(scale, scale);
     65             fPaints[i].setAntiAlias(true);
     66             fPaints[i].setColor(rand.nextU() | 0x80808080);
     67         }
     68     }
     69 
     70     void onDraw(int loops, SkCanvas* canvas) override {
     71         SkAutoCanvasRestore acr(canvas, true);
     72         for (int i = 0; i < kNumDraws; ++i) {
     73             const SkPath& glyph = fGlyphs[i % kNumGlyphs];
     74             canvas->setMatrix(fXforms[i]);
     75             canvas->drawPath(glyph, fPaints[i]);
     76         }
     77     }
     78 
     79     SkPath fGlyphs[kNumGlyphs];
     80     SkPaint fPaints[kNumDraws];
     81     SkMatrix fXforms[kNumDraws];
     82 
     83     typedef Benchmark INHERITED;
     84 };
     85 
     86 DEF_BENCH(return new PathTextBench;)
     87