• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
make_blob(const SkString & text,const SkFont & font)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::GM {
40 public:
FontRegenGM()41     FontRegenGM() {
42         this->setBGColor(SK_ColorLTGRAY);
43     }
44 
modifyGrContextOptions(GrContextOptions * options)45     void modifyGrContextOptions(GrContextOptions* options) override {
46         options->fGlyphCacheTextureMaximumBytes = 0;
47         options->fAllowMultipleGlyphCacheTextures = GrContextOptions::Enable::kNo;
48     }
49 
50 protected:
onShortName()51     SkString onShortName() override {
52         SkString name("fontregen");
53         return name;
54     }
55 
onISize()56     SkISize onISize() override { return SkISize::Make(kSize, kSize); }
57 
onOnceBeforeDraw()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 
onDraw(SkCanvas * canvas)79     void onDraw(SkCanvas* canvas) override {
80         GrRenderTargetContext* renderTargetContext =
81             canvas->internal_private_accessTopLayerRenderTargetContext();
82         if (!renderTargetContext) {
83             skiagm::GM::DrawGpuOnlyMessage(canvas);
84             return;
85         }
86 
87         SkPaint paint;
88         paint.setColor(SK_ColorBLACK);
89         canvas->drawTextBlob(fBlobs[0], 10, 80, paint);
90         canvas->drawTextBlob(fBlobs[1], 10, 225, paint);
91         canvas->flush();
92 
93         paint.setColor(0xFF010101);
94         canvas->drawTextBlob(fBlobs[0], 10, 305, paint);
95         canvas->drawTextBlob(fBlobs[2], 10, 465, paint);
96 
97         //  Debugging tool for GPU.
98         static const bool kShowAtlas = false;
99         if (kShowAtlas) {
100             if (auto ctx = canvas->getGrContext()) {
101                 auto img = ctx->contextPriv().getFontAtlasImage_ForTesting(kA8_GrMaskFormat);
102                 canvas->drawImage(img, 200, 0);
103             }
104         }
105     }
106 
107 private:
108     static constexpr SkScalar kSize = 512;
109 
110     sk_sp<SkTextBlob> fBlobs[3];
111     typedef GM INHERITED;
112 };
113 
114 constexpr SkScalar FontRegenGM::kSize;
115 
116 //////////////////////////////////////////////////////////////////////////////
117 
118 DEF_GM(return new FontRegenGM())
119