blob: 6ee8f8879c689a5ac44cf6da0962ad32e14ad23c [file] [log] [blame]
Chris Daltoncb727222017-06-30 12:00:35 -06001/*
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
15static constexpr int kScreenWidth = 1500;
16static constexpr int kScreenHeight = 1500;
17
18static constexpr int kNumDraws = 2000;
19
20// I and l are rects on OS X.
21static constexpr char kGlyphs[] = "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
22static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
23static_assert(52 == kNumGlyphs, "expected 52 glyphs");
24
25/*
26 * This class benchmarks drawing many glyphs at random scales and rotations.
27 */
28class PathTextBench : public Benchmark {
29public:
30 bool isVisual() override { return true; }
31
32private:
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
86DEF_BENCH(return new PathTextBench;)