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 // GM to stress the GPU font cache 9 // It's not necessary to run this with CPU configs 10 11 #include "gm.h" 12 13 #if SK_SUPPORT_GPU 14 15 #include "GrContext.h" 16 #include "GrContextOptions.h" 17 #include "SkCanvas.h" 18 #include "SkGraphics.h" 19 #include "SkImage.h" 20 #include "SkTypeface.h" 21 #include "gm.h" 22 #include "sk_tool_utils.h" 23 24 static SkScalar draw_string(SkCanvas* canvas, const SkString& text, SkScalar x, 25 SkScalar y, const SkPaint& paint) { 26 canvas->drawString(text, x, y, paint); 27 return x + paint.measureText(text.c_str(), text.size()); 28 } 29 30 class FontCacheGM : public skiagm::GM { 31 public: 32 FontCacheGM(GrContextOptions::Enable allowMultipleTextures) 33 : fAllowMultipleTextures(allowMultipleTextures) { 34 this->setBGColor(SK_ColorLTGRAY); 35 } 36 37 void modifyGrContextOptions(GrContextOptions* options) override { 38 options->fGlyphCacheTextureMaximumBytes = 0; 39 options->fAllowMultipleGlyphCacheTextures = fAllowMultipleTextures; 40 } 41 42 protected: 43 SkString onShortName() override { 44 SkString name("fontcache"); 45 if (GrContextOptions::Enable::kYes == fAllowMultipleTextures) { 46 name.append("-mt"); 47 } 48 return name; 49 } 50 51 SkISize onISize() override { return SkISize::Make(kSize, kSize); } 52 53 void onOnceBeforeDraw() override { 54 fTypefaces[0] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Italic()); 55 fTypefaces[1] = sk_tool_utils::create_portable_typeface("sans-serif",SkFontStyle::Italic()); 56 fTypefaces[2] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Normal()); 57 fTypefaces[3] = 58 sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Normal()); 59 fTypefaces[4] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Bold()); 60 fTypefaces[5] = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Bold()); 61 } 62 63 void onDraw(SkCanvas* canvas) override { 64 GrRenderTargetContext* renderTargetContext = 65 canvas->internal_private_accessTopLayerRenderTargetContext(); 66 if (!renderTargetContext) { 67 skiagm::GM::DrawGpuOnlyMessage(canvas); 68 return; 69 } 70 71 canvas->clear(SK_ColorLTGRAY); 72 this->drawText(canvas); 73 // Debugging tool for GPU. 74 static const bool kShowAtlas = false; 75 if (kShowAtlas) { 76 if (auto ctx = canvas->getGrContext()) { 77 auto img = ctx->getFontAtlasImage_ForTesting(kA8_GrMaskFormat); 78 canvas->drawImage(img, 0, 0); 79 } 80 } 81 } 82 83 private: 84 void drawText(SkCanvas* canvas) { 85 static const int kSizes[] = {8, 9, 10, 11, 12, 13, 18, 20, 25}; 86 87 static const SkString kTexts[] = {SkString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 88 SkString("abcdefghijklmnopqrstuvwxyz"), 89 SkString("0123456789"), 90 SkString("!@#$%^&*()<>[]{}")}; 91 SkPaint paint; 92 paint.setAntiAlias(true); 93 paint.setLCDRenderText(false); 94 paint.setSubpixelText(true); 95 96 static const SkScalar kSubPixelInc = 1 / 2.f; 97 SkScalar x = 0; 98 SkScalar y = 10; 99 SkScalar subpixelX = 0; 100 SkScalar subpixelY = 0; 101 bool offsetX = true; 102 103 if (GrContextOptions::Enable::kYes == fAllowMultipleTextures) { 104 canvas->scale(10, 10); 105 } 106 107 do { 108 for (auto s : kSizes) { 109 auto size = 2 * s; 110 paint.setTextSize(size); 111 for (const auto& typeface : fTypefaces) { 112 paint.setTypeface(typeface); 113 for (const auto& text : kTexts) { 114 x = size + draw_string(canvas, text, x + subpixelX, y + subpixelY, paint); 115 x = SkScalarCeilToScalar(x); 116 if (x + 100 > kSize) { 117 x = 0; 118 y += SkScalarCeilToScalar(size + 3); 119 if (y > kSize) { 120 return; 121 } 122 } 123 } 124 } 125 (offsetX ? subpixelX : subpixelY) += kSubPixelInc; 126 offsetX = !offsetX; 127 } 128 } while (true); 129 } 130 131 static constexpr SkScalar kSize = 1280; 132 133 GrContextOptions::Enable fAllowMultipleTextures; 134 sk_sp<SkTypeface> fTypefaces[6]; 135 typedef GM INHERITED; 136 }; 137 138 constexpr SkScalar FontCacheGM::kSize; 139 140 ////////////////////////////////////////////////////////////////////////////// 141 142 DEF_GM(return new FontCacheGM(GrContextOptions::Enable::kNo)) 143 DEF_GM(return new FontCacheGM(GrContextOptions::Enable::kYes)) 144 145 #endif 146