1 /* 2 * Copyright 2018 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 TextBlob regeneration and the GPU font cache 9 // It's not necessary to run this with CPU configs 10 // 11 // The point here is to draw a set of text that will fit in one Plot, and then some large 12 // text. After a flush we draw the first set of text again with a slightly different color, 13 // and then enough new large text to spill the entire atlas. What *should* happen is that 14 // the Plot with the first set of text will not get overwritten by the new large text. 15 16 #include "gm.h" 17 18 #include "GrContext.h" 19 #include "GrContextPriv.h" 20 #include "GrContextOptions.h" 21 #include "SkCanvas.h" 22 #include "SkGraphics.h" 23 #include "SkImage.h" 24 #include "SkTypeface.h" 25 #include "gm.h" 26 27 #include "sk_tool_utils.h" 28 29 static sk_sp<SkTextBlob> make_blob(const SkString& text, const SkFont& font) { 30 size_t len = text.size(); 31 SkAutoTArray<SkScalar> pos(len); 32 SkAutoTArray<SkGlyphID> glyphs(len); 33 34 font.textToGlyphs(text.c_str(), len, SkTextEncoding::kUTF8, glyphs.get(), len); 35 font.getXPos(glyphs.get(), len, pos.get()); 36 return SkTextBlob::MakeFromPosTextH(text.c_str(), len, pos.get(), 0, font); 37 } 38 39 class FontRegenGM : public skiagm::GpuGM { 40 public: 41 FontRegenGM() { 42 this->setBGColor(SK_ColorLTGRAY); 43 } 44 45 void modifyGrContextOptions(GrContextOptions* options) override { 46 options->fGlyphCacheTextureMaximumBytes = 0; 47 options->fAllowMultipleGlyphCacheTextures = GrContextOptions::Enable::kNo; 48 } 49 50 protected: 51 SkString onShortName() override { 52 SkString name("fontregen"); 53 return name; 54 } 55 56 SkISize onISize() override { return SkISize::Make(kSize, kSize); } 57 58 void onOnceBeforeDraw() override { 59 auto tf = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Normal()); 60 61 static const SkString kTexts[] = { 62 SkString("abcdefghijklmnopqrstuvwxyz"), 63 SkString("ABCDEFGHI"), 64 SkString("NOPQRSTUV") 65 }; 66 67 SkFont font; 68 font.setEdging(SkFont::Edging::kAntiAlias); 69 font.setSubpixel(false); 70 font.setSize(80); 71 font.setTypeface(tf); 72 73 fBlobs[0] = make_blob(kTexts[0], font); 74 font.setSize(162); 75 fBlobs[1] = make_blob(kTexts[1], font); 76 fBlobs[2] = make_blob(kTexts[2], font); 77 } 78 79 void onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas) override { 80 SkPaint paint; 81 paint.setColor(SK_ColorBLACK); 82 canvas->drawTextBlob(fBlobs[0], 10, 80, paint); 83 canvas->drawTextBlob(fBlobs[1], 10, 225, paint); 84 context->flush(); 85 86 paint.setColor(0xFF010101); 87 canvas->drawTextBlob(fBlobs[0], 10, 305, paint); 88 canvas->drawTextBlob(fBlobs[2], 10, 465, paint); 89 90 // Debugging tool for GPU. 91 static const bool kShowAtlas = false; 92 if (kShowAtlas) { 93 auto img = context->priv().testingOnly_getFontAtlasImage(kA8_GrMaskFormat); 94 canvas->drawImage(img, 200, 0); 95 } 96 } 97 98 private: 99 static constexpr SkScalar kSize = 512; 100 101 sk_sp<SkTextBlob> fBlobs[3]; 102 typedef GM INHERITED; 103 }; 104 105 constexpr SkScalar FontRegenGM::kSize; 106 107 ////////////////////////////////////////////////////////////////////////////// 108 109 DEF_GM(return new FontRegenGM()) 110