blob: b1c9e01a80a2d4076b0f8892d734dbf89173ead0 [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"
Herb Derbydce19a72018-04-18 16:02:17 -040014#include "SkStrikeCache.h"
Chris Dalton7c02cc72017-11-06 14:10:54 -070015#include "sk_tool_utils.h"
Chris Daltoncb727222017-06-30 12:00:35 -060016
17static constexpr int kScreenWidth = 1500;
18static constexpr int kScreenHeight = 1500;
19
20static constexpr int kNumDraws = 2000;
21
22// I and l are rects on OS X.
23static constexpr char kGlyphs[] = "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
24static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
25static_assert(52 == kNumGlyphs, "expected 52 glyphs");
26
27/*
28 * This class benchmarks drawing many glyphs at random scales and rotations.
29 */
30class PathTextBench : public Benchmark {
31public:
Chris Dalton7c02cc72017-11-06 14:10:54 -070032 PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
Chris Daltoncb727222017-06-30 12:00:35 -060033 bool isVisual() override { return true; }
34
35private:
36 const char* onGetName() override {
Chris Dalton7c02cc72017-11-06 14:10:54 -070037 fName = "path_text";
38 if (fClipped) {
39 fName.append("_clipped");
40 }
41 if (fUncached) {
42 fName.append("_uncached");
43 }
44 return fName.c_str();
Chris Daltoncb727222017-06-30 12:00:35 -060045 }
46 SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
47
48 void onDelayedSetup() override {
49 SkPaint defaultPaint;
Herb Derbyfa996902018-04-18 11:36:12 -040050 auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(defaultPaint);
Chris Daltoncb727222017-06-30 12:00:35 -060051 for (int i = 0; i < kNumGlyphs; ++i) {
Ben Wagner5ddb3082018-03-29 11:18:06 -040052 SkPackedGlyphID id(cache->unicharToGlyph(kGlyphs[i]));
53 sk_ignore_unused_variable(cache->getScalerContext()->getPath(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);)