1 /* 2 * Copyright 2015 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 9 #include "SkStrike.h" 10 11 #include "Benchmark.h" 12 #include "SkCanvas.h" 13 #include "SkStrikeCache.h" 14 #include "SkGraphics.h" 15 #include "SkTaskGroup.h" 16 #include "SkTypeface.h" 17 #include "sk_tool_utils.h" 18 19 20 static void do_font_stuff(SkFont* font) { 21 SkPaint defaultPaint; 22 for (SkScalar i = 8; i < 64; i++) { 23 font->setSize(i); 24 auto cache = SkStrikeCache::FindOrCreateStrikeExclusive( 25 *font, defaultPaint, SkSurfaceProps(0, kUnknown_SkPixelGeometry), 26 SkScalerContextFlags::kNone, SkMatrix::I()); 27 uint16_t glyphs['z']; 28 for (int c = ' '; c < 'z'; c++) { 29 glyphs[c] = font->unicharToGlyph(c); 30 } 31 for (int lookups = 0; lookups < 10; lookups++) { 32 for (int c = ' '; c < 'z'; c++) { 33 const SkGlyph& g = cache->getGlyphIDMetrics(glyphs[c]); 34 cache->findImage(g); 35 } 36 } 37 38 } 39 } 40 41 class SkGlyphCacheBasic : public Benchmark { 42 public: 43 explicit SkGlyphCacheBasic(size_t cacheSize) : fCacheSize(cacheSize) { } 44 45 protected: 46 const char* onGetName() override { 47 fName.printf("SkGlyphCacheBasic%dK", (int)(fCacheSize >> 10)); 48 return fName.c_str(); 49 } 50 51 bool isSuitableFor(Backend backend) override { 52 return backend == kNonRendering_Backend; 53 } 54 55 void onDraw(int loops, SkCanvas*) override { 56 size_t oldCacheLimitSize = SkGraphics::GetFontCacheLimit(); 57 SkGraphics::SetFontCacheLimit(fCacheSize); 58 SkFont font; 59 font.setEdging(SkFont::Edging::kAntiAlias); 60 font.setSubpixel(true); 61 font.setTypeface(sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Italic())); 62 63 for (int work = 0; work < loops; work++) { 64 do_font_stuff(&font); 65 } 66 SkGraphics::SetFontCacheLimit(oldCacheLimitSize); 67 } 68 69 private: 70 typedef Benchmark INHERITED; 71 const size_t fCacheSize; 72 SkString fName; 73 }; 74 75 class SkGlyphCacheStressTest : public Benchmark { 76 public: 77 explicit SkGlyphCacheStressTest(int cacheSize) : fCacheSize(cacheSize) { } 78 79 protected: 80 const char* onGetName() override { 81 fName.printf("SkGlyphCacheStressTest%dK", (int)(fCacheSize >> 10)); 82 return fName.c_str(); 83 } 84 85 bool isSuitableFor(Backend backend) override { 86 return backend == kNonRendering_Backend; 87 } 88 89 void onDraw(int loops, SkCanvas*) override { 90 size_t oldCacheLimitSize = SkGraphics::GetFontCacheLimit(); 91 SkGraphics::SetFontCacheLimit(fCacheSize); 92 sk_sp<SkTypeface> typefaces[] = 93 {sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Italic()), 94 sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Italic())}; 95 96 for (int work = 0; work < loops; work++) { 97 SkTaskGroup().batch(16, [&](int threadIndex) { 98 SkFont font; 99 font.setEdging(SkFont::Edging::kAntiAlias); 100 font.setSubpixel(true); 101 font.setTypeface(typefaces[threadIndex % 2]); 102 do_font_stuff(&font); 103 }); 104 } 105 SkGraphics::SetFontCacheLimit(oldCacheLimitSize); 106 } 107 108 private: 109 typedef Benchmark INHERITED; 110 const size_t fCacheSize; 111 SkString fName; 112 }; 113 114 DEF_BENCH( return new SkGlyphCacheBasic(256 * 1024); ) 115 DEF_BENCH( return new SkGlyphCacheBasic(32 * 1024 * 1024); ) 116 DEF_BENCH( return new SkGlyphCacheStressTest(256 * 1024); ) 117 DEF_BENCH( return new SkGlyphCacheStressTest(32 * 1024 * 1024); ) 118