Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
PathTextBench.cpp
Go to the documentation of this file.
1/*
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 "bench/Benchmark.h"
10#include "include/core/SkFont.h"
12#include "include/core/SkPath.h"
13#include "src/base/SkRandom.h"
14#include "src/core/SkStrike.h"
17#include "tools/ToolUtils.h"
19
20static constexpr int kScreenWidth = 1500;
21static constexpr int kScreenHeight = 1500;
22
23static constexpr int kNumDraws = 2000;
24
25// I and l are rects on OS X.
26static constexpr char kGlyphs[] = "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
27static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
28static_assert(52 == kNumGlyphs, "expected 52 glyphs");
29
30/*
31 * This class benchmarks drawing many glyphs at random scales and rotations.
32 */
33class PathTextBench : public Benchmark {
34public:
35 PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
36
37private:
38 const char* onGetName() override {
39 fName = "path_text";
40 if (fClipped) {
41 fName.append("_clipped");
42 }
43 if (fUncached) {
44 fName.append("_uncached");
45 }
46 return fName.c_str();
47 }
49
50 void onDelayedSetup() override {
51 SkFont defaultFont = ToolUtils::DefaultFont();
52 SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
53 SkBulkGlyphMetricsAndPaths pathMaker{strikeSpec};
54 for (int i = 0; i < kNumGlyphs; ++i) {
55 SkGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
56 const SkGlyph* glyph = pathMaker.glyph(id);
57 if (glyph->path()) {
58 fGlyphs[i] = *glyph->path();
59 }
60 fGlyphs[i].setIsVolatile(fUncached);
61 }
62
63 SkRandom rand;
64 for (int i = 0; i < kNumDraws; ++i) {
65 const SkPath& glyph = fGlyphs[i % kNumGlyphs];
66 const SkRect& bounds = glyph.getBounds();
67 float glyphSize = std::max(bounds.width(), bounds.height());
68 SkASSERT(glyphSize > 0);
69
70 float t0 = pow(rand.nextF(), 100);
71 float size = (1 - t0) * std::min(kScreenWidth, kScreenHeight) / 50 +
72 t0 * std::min(kScreenWidth, kScreenHeight) / 3;
73 float scale = size / glyphSize;
74 float t1 = rand.nextF(), t2 = rand.nextF();
75 fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
76 t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
77 (1 - t2) * sqrt(2) * scale/2 * glyphSize +
78 t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
79 fXforms[i].preRotate(rand.nextF() * 360);
80 fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
81 fXforms[i].preScale(scale, scale);
82 fPaints[i].setAntiAlias(true);
83 fPaints[i].setColor(rand.nextU() | 0x80808080);
84 }
85
86 if (fClipped) {
88 fClipPath.setIsVolatile(fUncached);
89 }
90 }
91
92 void onDraw(int loops, SkCanvas* canvas) override {
93 SkAutoCanvasRestore acr(canvas, true);
94 if (fClipped) {
95 canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
96 }
97 for (int i = 0; i < kNumDraws; ++i) {
98 const SkPath& glyph = fGlyphs[i % kNumGlyphs];
99 canvas->setMatrix(fXforms[i]);
100 canvas->drawPath(glyph, fPaints[i]);
101 }
102 }
103
104 const bool fClipped;
105 const bool fUncached;
106 SkString fName;
107 SkPath fGlyphs[kNumGlyphs];
108 SkPaint fPaints[kNumDraws];
109 SkMatrix fXforms[kNumDraws];
110 SkPath fClipPath;
111
112 using INHERITED = Benchmark;
113};
114
115DEF_BENCH(return new PathTextBench(false, false);)
116DEF_BENCH(return new PathTextBench(false, true);)
117DEF_BENCH(return new PathTextBench(true, true);)
#define DEF_BENCH(code)
Definition Benchmark.h:20
static constexpr int kNumDraws
static constexpr int kScreenHeight
static constexpr int kNumGlyphs
static constexpr char kGlyphs[]
static constexpr int kScreenWidth
#define SkASSERT(cond)
Definition SkAssert.h:116
uint16_t SkGlyphID
Definition SkTypes.h:179
SkISize onGetSize() override
const char * onGetName() override
void onDelayedSetup() override
void onDraw(int loops, SkCanvas *canvas) override
PathTextBench(bool clipped, bool uncached)
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawPath(const SkPath &path, const SkPaint &paint)
void setMatrix(const SkM44 &matrix)
SkGlyphID unicharToGlyph(SkUnichar uni) const
Definition SkFont.cpp:173
const SkPath * path() const
Definition SkGlyph.cpp:284
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:254
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:263
SkMatrix & preRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:462
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:315
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition SkPaint.h:170
SkPath & setIsVolatile(bool isVolatile)
Definition SkPath.h:370
const SkRect & getBounds() const
Definition SkPath.cpp:420
uint32_t nextU()
Definition SkRandom.h:42
float nextF()
Definition SkRandom.h:55
static SkStrikeSpec MakeWithNoDevice(const SkFont &font, const SkPaint *paint=nullptr)
void append(const char text[])
Definition SkString.h:203
const char * c_str() const
Definition SkString.h:133
SkFont DefaultFont()
SkPath make_star(const SkRect &bounds, int numPts, int step)
const Scalar scale
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static SkRect MakeIWH(int w, int h)
Definition SkRect.h:623
const uintptr_t id