• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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