TextBench.cpp revision f059900f75639f1b1a03f2c25333ef9aa22d58b8
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9#include "Benchmark.h" 10#include "Resources.h" 11#include "SkCanvas.h" 12#include "SkPaint.h" 13#include "SkRandom.h" 14#include "SkStream.h" 15#include "SkString.h" 16#include "SkTemplates.h" 17#include "SkTypeface.h" 18 19enum FontQuality { 20 kBW, 21 kAA, 22 kLCD, 23}; 24 25static const char* fontQualityName(const SkPaint& paint) { 26 if (!paint.isAntiAlias()) { 27 return "BW"; 28 } 29 if (paint.isLCDRenderText()) { 30 return "LCD"; 31 } 32 return "AA"; 33} 34 35/* Some considerations for performance: 36 short -vs- long strings (measuring overhead) 37 tiny -vs- large pointsize (measure blit -vs- overhead) 38 1 -vs- many point sizes (measure cache lookup) 39 normal -vs- subpixel -vs- lineartext (minor) 40 force purge after each draw to measure scaler 41 textencoding? 42 text -vs- postext - pathtext 43 */ 44class TextBench : public Benchmark { 45 SkPaint fPaint; 46 SkString fText; 47 SkString fName; 48 FontQuality fFQ; 49 bool fDoPos; 50 bool fDoColorEmoji; 51 SkAutoTUnref<SkTypeface> fColorEmojiTypeface; 52 SkPoint* fPos; 53public: 54 TextBench(const char text[], int ps, 55 SkColor color, FontQuality fq, bool doColorEmoji = false, bool doPos = false) 56 : fText(text) 57 , fFQ(fq) 58 , fDoPos(doPos) 59 , fDoColorEmoji(doColorEmoji) 60 , fPos(NULL) { 61 fPaint.setAntiAlias(kBW != fq); 62 fPaint.setLCDRenderText(kLCD == fq); 63 fPaint.setTextSize(SkIntToScalar(ps)); 64 fPaint.setColor(color); 65 } 66 67 virtual ~TextBench() { 68 delete[] fPos; 69 } 70 71protected: 72 void onPreDraw() override { 73 if (fDoColorEmoji) { 74 SkASSERT(kBW == fFQ); 75 fColorEmojiTypeface.reset(GetResourceAsTypeface("/fonts/Funkster.ttf")); 76 } 77 78 if (fDoPos) { 79 size_t len = fText.size(); 80 SkScalar* adv = new SkScalar[len]; 81 fPaint.getTextWidths(fText.c_str(), len, adv); 82 fPos = new SkPoint[len]; 83 SkScalar x = 0; 84 for (size_t i = 0; i < len; ++i) { 85 fPos[i].set(x, SkIntToScalar(50)); 86 x += adv[i]; 87 } 88 delete[] adv; 89 } 90 } 91 92 93 const char* onGetName() override { 94 fName.printf("text_%g", SkScalarToFloat(fPaint.getTextSize())); 95 if (fDoPos) { 96 fName.append("_pos"); 97 } 98 fName.appendf("_%s", fontQualityName(fPaint)); 99 if (SK_ColorBLACK != fPaint.getColor()) { 100 fName.appendf("_%02X", fPaint.getAlpha()); 101 } else { 102 fName.append("_BK"); 103 } 104 105 if (fDoColorEmoji) { 106 fName.append("_ColorEmoji"); 107 } 108 109 return fName.c_str(); 110 } 111 112 void onDraw(const int loops, SkCanvas* canvas) override { 113 const SkIPoint dim = this->getSize(); 114 SkRandom rand; 115 116 SkPaint paint(fPaint); 117 this->setupPaint(&paint); 118 // explicitly need these 119 paint.setColor(fPaint.getColor()); 120 paint.setAntiAlias(kBW != fFQ); 121 paint.setLCDRenderText(kLCD == fFQ); 122 123 if (fDoColorEmoji && fColorEmojiTypeface) { 124 paint.setTypeface(fColorEmojiTypeface); 125 } 126 127 const SkScalar x0 = SkIntToScalar(-10); 128 const SkScalar y0 = SkIntToScalar(-10); 129 130 if (fDoPos) { 131 // realistically, the matrix is often at least translated, so we 132 // do that since it exercises different code in drawPosText. 133 canvas->translate(SK_Scalar1, SK_Scalar1); 134 } 135 136 for (int i = 0; i < loops; i++) { 137 if (fDoPos) { 138 canvas->drawPosText(fText.c_str(), fText.size(), fPos, paint); 139 } else { 140 SkScalar x = x0 + rand.nextUScalar1() * dim.fX; 141 SkScalar y = y0 + rand.nextUScalar1() * dim.fY; 142 canvas->drawText(fText.c_str(), fText.size(), x, y, paint); 143 } 144 } 145 } 146 147private: 148 typedef Benchmark INHERITED; 149}; 150 151/////////////////////////////////////////////////////////////////////////////// 152 153#define STR "Hamburgefons" 154 155DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW); ) 156DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kBW); ) 157DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kBW); ) 158 159DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA); ) 160DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kAA); ) 161DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kAA); ) 162 163DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kLCD); ) 164DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kLCD); ) 165DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kLCD); ) 166 167DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW, true); ) 168DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kBW, true); ) 169DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kBW, true); ) 170 171DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW, true, true); ) 172DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA, false, true); ) 173