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
draw_string(SkCanvas * canvas,const SkString & text,SkScalar x,SkScalar y,const SkPaint & paint)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:
FontCacheGM()37 FontCacheGM() {
38 for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
39 fTypefaces[i] = NULL;
40 }
41 }
42
~FontCacheGM()43 virtual ~FontCacheGM() {
44 for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
45 SkSafeUnref(fTypefaces[i]);
46 }
47 }
48
49 protected:
onShortName()50 virtual SkString onShortName() SK_OVERRIDE {
51 return SkString("fontcache");
52 }
53
onISize()54 virtual SkISize onISize() SK_OVERRIDE {
55 return SkISize::Make(640, 320);
56 }
57
onOnceBeforeDraw()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
onDraw(SkCanvas * canvas)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
onGetFlags() const106 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