blob: 6551fa5f27ec36dedc91e9347f0feffab8b01092 [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:
Chris Daltona2ac30d2017-10-17 10:40:01 -060030 PathTextBench(bool cached) : fCached(cached) {}
Chris Daltoncb727222017-06-30 12:00:35 -060031 bool isVisual() override { return true; }
32
33private:
34 const char* onGetName() override {
Chris Daltona2ac30d2017-10-17 10:40:01 -060035 return fCached ? "path_text" : "path_text_uncached";
Chris Daltoncb727222017-06-30 12:00:35 -060036 }
37 SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
38
39 void onDelayedSetup() override {
40 SkPaint defaultPaint;
41 SkAutoGlyphCache agc(defaultPaint, nullptr, &SkMatrix::I());
42 SkGlyphCache* cache = agc.getCache();
43 for (int i = 0; i < kNumGlyphs; ++i) {
44 SkGlyphID id = cache->unicharToGlyph(kGlyphs[i]);
45 cache->getScalerContext()->getPath(SkPackedGlyphID(id), &fGlyphs[i]);
Chris Daltona2ac30d2017-10-17 10:40:01 -060046 fGlyphs[i].setIsVolatile(!fCached);
Chris Daltoncb727222017-06-30 12:00:35 -060047 }
48
49 SkRandom rand;
50 for (int i = 0; i < kNumDraws; ++i) {
51 const SkPath& glyph = fGlyphs[i % kNumGlyphs];
52 const SkRect& bounds = glyph.getBounds();
53 float glyphSize = SkTMax(bounds.width(), bounds.height());
54
55 float t0 = pow(rand.nextF(), 100);
56 float size = (1 - t0) * SkTMin(kScreenWidth, kScreenHeight) / 50 +
57 t0 * SkTMin(kScreenWidth, kScreenHeight) / 3;
58 float scale = size / glyphSize;
59 float t1 = rand.nextF(), t2 = rand.nextF();
60 fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
61 t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
62 (1 - t2) * sqrt(2) * scale/2 * glyphSize +
63 t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
64 fXforms[i].preRotate(rand.nextF() * 360);
65 fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
66 fXforms[i].preScale(scale, scale);
67 fPaints[i].setAntiAlias(true);
68 fPaints[i].setColor(rand.nextU() | 0x80808080);
69 }
70 }
71
72 void onDraw(int loops, SkCanvas* canvas) override {
73 SkAutoCanvasRestore acr(canvas, true);
74 for (int i = 0; i < kNumDraws; ++i) {
75 const SkPath& glyph = fGlyphs[i % kNumGlyphs];
76 canvas->setMatrix(fXforms[i]);
77 canvas->drawPath(glyph, fPaints[i]);
78 }
79 }
80
Chris Daltona2ac30d2017-10-17 10:40:01 -060081 const bool fCached;
Chris Daltoncb727222017-06-30 12:00:35 -060082 SkPath fGlyphs[kNumGlyphs];
83 SkPaint fPaints[kNumDraws];
84 SkMatrix fXforms[kNumDraws];
85
86 typedef Benchmark INHERITED;
87};
88
Chris Daltona2ac30d2017-10-17 10:40:01 -060089DEF_BENCH(return new PathTextBench(false);)
90DEF_BENCH(return new PathTextBench(true);)