1 /*
2 * Copyright 2013 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"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkFont.h"
11 #include "include/core/SkTypeface.h"
12 #include "include/utils/SkRandom.h"
13 #include "src/utils/SkCharToGlyphCache.h"
14 #include "src/utils/SkUTF.h"
15
16 enum {
17 NGLYPHS = 100
18 };
19
20 namespace {
21 struct Rec {
22 const SkCharToGlyphCache& fCache;
23 int fLoops;
24 const SkFont& fFont;
25 const SkUnichar* fText;
26 int fCount;
27 };
28 }
29
30 typedef void (*TypefaceProc)(const Rec& r);
31
textToGlyphs_proc(const Rec & r)32 static void textToGlyphs_proc(const Rec& r) {
33 uint16_t glyphs[NGLYPHS];
34 SkASSERT(r.fCount <= NGLYPHS);
35
36 for (int i = 0; i < r.fLoops; ++i) {
37 r.fFont.textToGlyphs(r.fText, r.fCount*4, SkTextEncoding::kUTF32, glyphs, NGLYPHS);
38 }
39 }
40
charsToGlyphs_proc(const Rec & r)41 static void charsToGlyphs_proc(const Rec& r) {
42 uint16_t glyphs[NGLYPHS];
43 SkASSERT(r.fCount <= NGLYPHS);
44
45 SkTypeface* face = r.fFont.getTypefaceOrDefault();
46 for (int i = 0; i < r.fLoops; ++i) {
47 face->unicharsToGlyphs(r.fText, r.fCount, glyphs);
48 }
49 }
50
addcache_proc(const Rec & r)51 static void addcache_proc(const Rec& r) {
52 for (int i = 0; i < r.fLoops; ++i) {
53 SkCharToGlyphCache cache;
54 for (int i = 0; i < r.fCount; ++i) {
55 cache.addCharAndGlyph(r.fText[i], i);
56 }
57 }
58 }
59
findcache_proc(const Rec & r)60 static void findcache_proc(const Rec& r) {
61 for (int i = 0; i < r.fLoops; ++i) {
62 for (int i = 0; i < r.fCount; ++i) {
63 r.fCache.findGlyphIndex(r.fText[i]);
64 }
65 }
66 }
67
68 class CMAPBench : public Benchmark {
69 TypefaceProc fProc;
70 SkString fName;
71 SkUnichar fText[NGLYPHS];
72 SkFont fFont;
73 SkCharToGlyphCache fCache;
74 int fCount;
75
76 public:
CMAPBench(TypefaceProc proc,const char name[],int count)77 CMAPBench(TypefaceProc proc, const char name[], int count) {
78 SkASSERT(count <= NGLYPHS);
79
80 fProc = proc;
81 fName.printf("%s_%d", name, count);
82 fCount = count;
83
84 SkRandom rand;
85 for (int i = 0; i < count; ++i) {
86 fText[i] = rand.nextU() & 0xFFFF;
87 fCache.addCharAndGlyph(fText[i], i);
88 }
89 fFont.setTypeface(SkTypeface::MakeDefault());
90 }
91
isSuitableFor(Backend backend)92 bool isSuitableFor(Backend backend) override {
93 return backend == kNonRendering_Backend;
94 }
95
96 protected:
onGetName()97 const char* onGetName() override {
98 return fName.c_str();
99 }
100
onDraw(int loops,SkCanvas * canvas)101 void onDraw(int loops, SkCanvas* canvas) override {
102 fProc({fCache, loops, fFont, fText, fCount});
103 }
104
105 private:
106
107 typedef Benchmark INHERITED;
108 };
109
110 //////////////////////////////////////////////////////////////////////////////
111
112 constexpr int SMALL = 10;
113
114 DEF_BENCH( return new CMAPBench(textToGlyphs_proc, "font_charToGlyph", SMALL); )
115 DEF_BENCH( return new CMAPBench(charsToGlyphs_proc, "face_charToGlyph", SMALL); )
116 DEF_BENCH( return new CMAPBench(addcache_proc, "addcache_charToGlyph", SMALL); )
117 DEF_BENCH( return new CMAPBench(findcache_proc, "findcache_charToGlyph", SMALL); )
118
119 constexpr int BIG = 100;
120
121 DEF_BENCH( return new CMAPBench(textToGlyphs_proc, "font_charToGlyph", BIG); )
122 DEF_BENCH( return new CMAPBench(charsToGlyphs_proc, "face_charToGlyph", BIG); )
123 DEF_BENCH( return new CMAPBench(addcache_proc, "addcache_charToGlyph", BIG); )
124 DEF_BENCH( return new CMAPBench(findcache_proc, "findcache_charToGlyph", BIG); )
125