Home | History | Annotate | Download | only in gm
      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