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 "gm.h" 9 #include "SkCanvas.h" 10 #include "SkGraphics.h" 11 #include "SkTypeface.h" 12 13 // GM to stress the GPU font cache 14 15 const char* gFamilyNames[] = { 16 "sans-serif", "serif", "monospace" 17 }; 18 19 const SkTypeface::Style gStyles[] = { 20 SkTypeface::kNormal, SkTypeface::kItalic 21 }; 22 23 const SkScalar gTextSizes[] = { 24 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 25 }; 26 27 #define TYPEFACE_COUNT (SK_ARRAY_COUNT(gFamilyNames)*SK_ARRAY_COUNT(gStyles)) 28 29 static SkScalar draw_string(SkCanvas* canvas, const SkString& text, SkScalar x, 30 SkScalar y, const SkPaint& paint) { 31 canvas->drawText(text.c_str(), text.size(), x, y, paint); 32 return x + paint.measureText(text.c_str(), text.size()); 33 } 34 35 class FontCacheGM : public skiagm::GM { 36 public: 37 FontCacheGM() { 38 for (size_t i = 0; i < TYPEFACE_COUNT; ++i) { 39 fTypefaces[i] = NULL; 40 } 41 } 42 43 virtual ~FontCacheGM() { 44 for (size_t i = 0; i < TYPEFACE_COUNT; ++i) { 45 SkSafeUnref(fTypefaces[i]); 46 } 47 } 48 49 protected: 50 virtual SkString onShortName() SK_OVERRIDE { 51 return SkString("fontcache"); 52 } 53 54 virtual SkISize onISize() SK_OVERRIDE { 55 return SkISize::Make(640, 320); 56 } 57 58 virtual void onOnceBeforeDraw() SK_OVERRIDE { 59 int typefaceCount = 0; 60 for (size_t i = 0; i < SK_ARRAY_COUNT(gFamilyNames); ++i) { 61 for (size_t j = 0; j < SK_ARRAY_COUNT(gStyles); ++j) { 62 fTypefaces[typefaceCount++] = SkTypeface::CreateFromName(gFamilyNames[i], 63 gStyles[j]); 64 } 65 } 66 } 67 68 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 69 SkScalar y = 32; 70 SkPaint paint; 71 paint.setAntiAlias(true); 72 paint.setLCDRenderText(true); 73 paint.setSubpixelText(true); 74 75 SkString text("Ham"); 76 77 // draw some initial text to partially fill the GPU cache 78 for (size_t i = 0; i < 2; ++i) { 79 paint.setTypeface(fTypefaces[i]); 80 SkScalar x = 20; 81 82 for (size_t j = 0; j < SK_ARRAY_COUNT(gTextSizes); ++j) { 83 paint.setTextSize(gTextSizes[j]); 84 x = draw_string(canvas, text, x, y, paint) + 19; 85 } 86 y += 32; 87 } 88 89 // force a flush 90 canvas->flush(); 91 92 // draw again, and more to overflow the cache 93 for (size_t i = 0; i < TYPEFACE_COUNT; ++i) { 94 paint.setTypeface(fTypefaces[i]); 95 SkScalar x = 20; 96 97 for (size_t j = 0; j < SK_ARRAY_COUNT(gTextSizes); ++j) { 98 paint.setTextSize(gTextSizes[j]); 99 x = draw_string(canvas, text, x, y, paint) + 19; 100 } 101 y += 32; 102 } 103 104 } 105 106 virtual uint32_t onGetFlags() const SK_OVERRIDE { 107 // this GM is meant only for the GPU 108 return kGPUOnly_Flag; 109 } 110 111 private: 112 SkTypeface* fTypefaces[TYPEFACE_COUNT]; 113 typedef GM INHERITED; 114 }; 115 116 117 ////////////////////////////////////////////////////////////////////////////// 118 119 DEF_GM( return SkNEW(FontCacheGM); ) 120