blob: 4e83d33119f8f4af7f50fd18e0ad54178cf466d5 [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"
Chris Dalton7c02cc72017-11-06 14:10:54 -070014#include "sk_tool_utils.h"
Chris Daltoncb727222017-06-30 12:00:35 -060015
16static constexpr int kScreenWidth = 1500;
17static constexpr int kScreenHeight = 1500;
18
19static constexpr int kNumDraws = 2000;
20
21// I and l are rects on OS X.
22static constexpr char kGlyphs[] = "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
23static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
24static_assert(52 == kNumGlyphs, "expected 52 glyphs");
25
26/*
27 * This class benchmarks drawing many glyphs at random scales and rotations.
28 */
29class PathTextBench : public Benchmark {
30public:
Chris Dalton7c02cc72017-11-06 14:10:54 -070031 PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
Chris Daltoncb727222017-06-30 12:00:35 -060032 bool isVisual() override { return true; }
33
34private:
35 const char* onGetName() override {
Chris Dalton7c02cc72017-11-06 14:10:54 -070036 fName = "path_text";
37 if (fClipped) {
38 fName.append("_clipped");
39 }
40 if (fUncached) {
41 fName.append("_uncached");
42 }
43 return fName.c_str();
Chris Daltoncb727222017-06-30 12:00:35 -060044 }
45 SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
46
47 void onDelayedSetup() override {
48 SkPaint defaultPaint;
49 SkAutoGlyphCache agc(defaultPaint, nullptr, &SkMatrix::I());
Herb Derbyc2ef4ab2018-03-09 10:15:52 -050050 SkGlyphCache* cache = agc.get();
Chris Daltoncb727222017-06-30 12:00:35 -060051 for (int i = 0; i < kNumGlyphs; ++i) {
52 SkGlyphID id = cache->unicharToGlyph(kGlyphs[i]);
53 cache->getScalerContext()->getPath(SkPackedGlyphID(id), &fGlyphs[i]);
Chris Dalton7c02cc72017-11-06 14:10:54 -070054 fGlyphs[i].setIsVolatile(fUncached);
Chris Daltoncb727222017-06-30 12:00:35 -060055 }
56
57 SkRandom rand;
58 for (int i = 0; i < kNumDraws; ++i) {
59 const SkPath& glyph = fGlyphs[i % kNumGlyphs];
60 const SkRect& bounds = glyph.getBounds();
61 float glyphSize = SkTMax(bounds.width(), bounds.height());
62
63 float t0 = pow(rand.nextF(), 100);
64 float size = (1 - t0) * SkTMin(kScreenWidth, kScreenHeight) / 50 +
65 t0 * SkTMin(kScreenWidth, kScreenHeight) / 3;
66 float scale = size / glyphSize;
67 float t1 = rand.nextF(), t2 = rand.nextF();
68 fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
69 t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
70 (1 - t2) * sqrt(2) * scale/2 * glyphSize +
71 t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
72 fXforms[i].preRotate(rand.nextF() * 360);
73 fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
74 fXforms[i].preScale(scale, scale);
75 fPaints[i].setAntiAlias(true);
76 fPaints[i].setColor(rand.nextU() | 0x80808080);
77 }
Chris Dalton7c02cc72017-11-06 14:10:54 -070078
79 if (fClipped) {
80 fClipPath = sk_tool_utils::make_star(SkRect::MakeIWH(kScreenWidth,kScreenHeight), 11,3);
81 fClipPath.setIsVolatile(fUncached);
82 }
Chris Daltoncb727222017-06-30 12:00:35 -060083 }
84
85 void onDraw(int loops, SkCanvas* canvas) override {
86 SkAutoCanvasRestore acr(canvas, true);
Chris Dalton7c02cc72017-11-06 14:10:54 -070087 if (fClipped) {
88 canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
89 }
Chris Daltoncb727222017-06-30 12:00:35 -060090 for (int i = 0; i < kNumDraws; ++i) {
91 const SkPath& glyph = fGlyphs[i % kNumGlyphs];
92 canvas->setMatrix(fXforms[i]);
93 canvas->drawPath(glyph, fPaints[i]);
94 }
95 }
96
Chris Dalton7c02cc72017-11-06 14:10:54 -070097 const bool fClipped;
98 const bool fUncached;
99 SkString fName;
Chris Daltoncb727222017-06-30 12:00:35 -0600100 SkPath fGlyphs[kNumGlyphs];
101 SkPaint fPaints[kNumDraws];
102 SkMatrix fXforms[kNumDraws];
Chris Dalton7c02cc72017-11-06 14:10:54 -0700103 SkPath fClipPath;
Chris Daltoncb727222017-06-30 12:00:35 -0600104
105 typedef Benchmark INHERITED;
106};
107
Chris Dalton7c02cc72017-11-06 14:10:54 -0700108DEF_BENCH(return new PathTextBench(false, false);)
109DEF_BENCH(return new PathTextBench(false, true);)
110DEF_BENCH(return new PathTextBench(true, true);)