blob: 9bc69e74782eac0c522322bb25899d9082a2f9df [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
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;
Herb Derbyc3415002018-11-08 16:40:26 -050049 auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(defaultPaint);
Chris Daltoncb727222017-06-30 12:00:35 -060050 for (int i = 0; i < kNumGlyphs; ++i) {
Ben Wagner5ddb3082018-03-29 11:18:06 -040051 SkPackedGlyphID id(cache->unicharToGlyph(kGlyphs[i]));
52 sk_ignore_unused_variable(cache->getScalerContext()->getPath(id, &fGlyphs[i]));
Chris Dalton7c02cc72017-11-06 14:10:54 -070053 fGlyphs[i].setIsVolatile(fUncached);
Chris Daltoncb727222017-06-30 12:00:35 -060054 }
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 }
Chris Dalton7c02cc72017-11-06 14:10:54 -070077
78 if (fClipped) {
79 fClipPath = sk_tool_utils::make_star(SkRect::MakeIWH(kScreenWidth,kScreenHeight), 11,3);
80 fClipPath.setIsVolatile(fUncached);
81 }
Chris Daltoncb727222017-06-30 12:00:35 -060082 }
83
84 void onDraw(int loops, SkCanvas* canvas) override {
85 SkAutoCanvasRestore acr(canvas, true);
Chris Dalton7c02cc72017-11-06 14:10:54 -070086 if (fClipped) {
87 canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
88 }
Chris Daltoncb727222017-06-30 12:00:35 -060089 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
Chris Dalton7c02cc72017-11-06 14:10:54 -070096 const bool fClipped;
97 const bool fUncached;
98 SkString fName;
Chris Daltoncb727222017-06-30 12:00:35 -060099 SkPath fGlyphs[kNumGlyphs];
100 SkPaint fPaints[kNumDraws];
101 SkMatrix fXforms[kNumDraws];
Chris Dalton7c02cc72017-11-06 14:10:54 -0700102 SkPath fClipPath;
Chris Daltoncb727222017-06-30 12:00:35 -0600103
104 typedef Benchmark INHERITED;
105};
106
Chris Dalton7c02cc72017-11-06 14:10:54 -0700107DEF_BENCH(return new PathTextBench(false, false);)
108DEF_BENCH(return new PathTextBench(false, true);)
109DEF_BENCH(return new PathTextBench(true, true);)