• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
PathTextBench(bool clipped,bool uncached)32     PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
33 
34 private:
onGetName()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     }
onGetSize()45     SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
46 
onDelayedSetup()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 
onDraw(int loops,SkCanvas * canvas)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