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 "SkPaint.h"
     11 #include "SkPath.h"
     12 #include "SkRandom.h"
     13 #include "SkStrike.h"
     14 #include "SkStrikeCache.h"
     15 #include "sk_tool_utils.h"
     16 
     17 static constexpr int kScreenWidth = 1500;
     18 static constexpr int kScreenHeight = 1500;
     19 
     20 static constexpr int kNumDraws = 2000;
     21 
     22 // I and l are rects on OS X.
     23 static constexpr char kGlyphs[] =  "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
     24 static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
     25 static_assert(52 == kNumGlyphs, "expected 52 glyphs");
     26 
     27 /*
     28  * This class benchmarks drawing many glyphs at random scales and rotations.
     29  */
     30 class PathTextBench : public Benchmark {
     31 public:
     32     PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
     33 
     34 private:
     35     const char* onGetName() override {
     36         fName = "path_text";
     37         if (fClipped) {
     38             fName.append("_clipped");
     39         }
     40         if (fUncached) {
     41             fName.append("_uncached");
     42         }
     43         return fName.c_str();
     44     }
     45     SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
     46 
     47     void onDelayedSetup() override {
     48         SkFont defaultFont;
     49         auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(defaultFont);
     50         for (int i = 0; i < kNumGlyphs; ++i) {
     51             SkPackedGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
     52             sk_ignore_unused_variable(cache->getScalerContext()->getPath(id, &fGlyphs[i]));
     53             fGlyphs[i].setIsVolatile(fUncached);
     54         }
     55 
     56         SkRandom rand;
     57         for (int i = 0; i < kNumDraws; ++i) {
     58             const SkPath& glyph = fGlyphs[i % kNumGlyphs];
     59             const SkRect& bounds = glyph.getBounds();
     60             float glyphSize = SkTMax(bounds.width(), bounds.height());
     61 
     62             float t0 = pow(rand.nextF(), 100);
     63             float size = (1 - t0) * SkTMin(kScreenWidth, kScreenHeight) / 50 +
     64                          t0 * SkTMin(kScreenWidth, kScreenHeight) / 3;
     65             float scale = size / glyphSize;
     66             float t1 = rand.nextF(), t2 = rand.nextF();
     67             fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
     68                                      t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
     69                                      (1 - t2) * sqrt(2) * scale/2 * glyphSize +
     70                                      t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
     71             fXforms[i].preRotate(rand.nextF() * 360);
     72             fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
     73             fXforms[i].preScale(scale, scale);
     74             fPaints[i].setAntiAlias(true);
     75             fPaints[i].setColor(rand.nextU() | 0x80808080);
     76         }
     77 
     78         if (fClipped) {
     79             fClipPath = sk_tool_utils::make_star(SkRect::MakeIWH(kScreenWidth,kScreenHeight), 11,3);
     80             fClipPath.setIsVolatile(fUncached);
     81         }
     82     }
     83 
     84     void onDraw(int loops, SkCanvas* canvas) override {
     85         SkAutoCanvasRestore acr(canvas, true);
     86         if (fClipped) {
     87             canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
     88         }
     89         for (int i = 0; i < kNumDraws; ++i) {
     90             const SkPath& glyph = fGlyphs[i % kNumGlyphs];
     91             canvas->setMatrix(fXforms[i]);
     92             canvas->drawPath(glyph, fPaints[i]);
     93         }
     94     }
     95 
     96     const bool fClipped;
     97     const bool fUncached;
     98     SkString fName;
     99     SkPath fGlyphs[kNumGlyphs];
    100     SkPaint fPaints[kNumDraws];
    101     SkMatrix fXforms[kNumDraws];
    102     SkPath fClipPath;
    103 
    104     typedef Benchmark INHERITED;
    105 };
    106 
    107 DEF_BENCH(return new PathTextBench(false, false);)
    108 DEF_BENCH(return new PathTextBench(false, true);)
    109 DEF_BENCH(return new PathTextBench(true, true);)
    110