blob: 39b23b9a92fcd9233efc888592a09296cc47ec32 [file] [log] [blame]
Jim Van Verth753403c2018-12-18 11:04:37 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "gm/gm.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040018#include "include/core/SkColor.h"
19#include "include/core/SkFont.h"
Jim Van Verth34b72ae2019-11-14 13:42:06 -050020#include "include/core/SkFontMgr.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040021#include "include/core/SkFontStyle.h"
22#include "include/core/SkFontTypes.h"
23#include "include/core/SkPaint.h"
24#include "include/core/SkRefCnt.h"
25#include "include/core/SkScalar.h"
26#include "include/core/SkSize.h"
27#include "include/core/SkString.h"
28#include "include/core/SkTextBlob.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050029#include "include/core/SkTypeface.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040030#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050031#include "include/gpu/GrContext.h"
32#include "include/gpu/GrContextOptions.h"
Robert Phillipsb7bfbc22020-07-01 12:55:01 -040033#include "include/gpu/GrDirectContext.h"
34#include "include/gpu/GrRecordingContext.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040035#include "include/private/GrTypesPriv.h"
36#include "include/private/SkTemplates.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050037#include "src/gpu/GrContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050038#include "tools/ToolUtils.h"
Jim Van Verth753403c2018-12-18 11:04:37 -050039
Ben Wagner7fde8e12019-05-01 17:28:53 -040040class GrRenderTargetContext;
41
Jim Van Verth753403c2018-12-18 11:04:37 -050042static sk_sp<SkTextBlob> make_blob(const SkString& text, const SkFont& font) {
43 size_t len = text.size();
44 SkAutoTArray<SkScalar> pos(len);
45 SkAutoTArray<SkGlyphID> glyphs(len);
46
47 font.textToGlyphs(text.c_str(), len, SkTextEncoding::kUTF8, glyphs.get(), len);
48 font.getXPos(glyphs.get(), len, pos.get());
49 return SkTextBlob::MakeFromPosTextH(text.c_str(), len, pos.get(), 0, font);
50}
51
Chris Dalton3a778372019-02-07 15:23:36 -070052class FontRegenGM : public skiagm::GpuGM {
Jim Van Verth753403c2018-12-18 11:04:37 -050053
54 void modifyGrContextOptions(GrContextOptions* options) override {
55 options->fGlyphCacheTextureMaximumBytes = 0;
56 options->fAllowMultipleGlyphCacheTextures = GrContextOptions::Enable::kNo;
57 }
58
Hal Canaryfa3305a2019-07-18 12:36:54 -040059 SkString onShortName() override { return SkString("fontregen"); }
Jim Van Verth753403c2018-12-18 11:04:37 -050060
Hal Canaryfa3305a2019-07-18 12:36:54 -040061 SkISize onISize() override { return {kSize, kSize}; }
Jim Van Verth753403c2018-12-18 11:04:37 -050062
63 void onOnceBeforeDraw() override {
Hal Canaryfa3305a2019-07-18 12:36:54 -040064 this->setBGColor(SK_ColorLTGRAY);
65
Mike Kleinea3f0142019-03-20 11:12:10 -050066 auto tf = ToolUtils::create_portable_typeface("sans-serif", SkFontStyle::Normal());
Jim Van Verth753403c2018-12-18 11:04:37 -050067
68 static const SkString kTexts[] = {
69 SkString("abcdefghijklmnopqrstuvwxyz"),
70 SkString("ABCDEFGHI"),
71 SkString("NOPQRSTUV")
72 };
73
74 SkFont font;
75 font.setEdging(SkFont::Edging::kAntiAlias);
76 font.setSubpixel(false);
77 font.setSize(80);
78 font.setTypeface(tf);
79
80 fBlobs[0] = make_blob(kTexts[0], font);
81 font.setSize(162);
82 fBlobs[1] = make_blob(kTexts[1], font);
83 fBlobs[2] = make_blob(kTexts[2], font);
84 }
85
Robert Phillips95c250c2020-06-29 15:36:12 -040086 void onDraw(GrRecordingContext* context, GrRenderTargetContext*, SkCanvas* canvas) override {
Robert Phillipsf8f45d92020-07-01 11:11:18 -040087 auto direct = context->asDirectContext();
Robert Phillips95c250c2020-06-29 15:36:12 -040088 if (!direct) {
89 return;
90 }
91
Jim Van Verth753403c2018-12-18 11:04:37 -050092 SkPaint paint;
93 paint.setColor(SK_ColorBLACK);
94 canvas->drawTextBlob(fBlobs[0], 10, 80, paint);
95 canvas->drawTextBlob(fBlobs[1], 10, 225, paint);
Robert Phillips95c250c2020-06-29 15:36:12 -040096 direct->flushAndSubmit();
Jim Van Verth753403c2018-12-18 11:04:37 -050097
98 paint.setColor(0xFF010101);
99 canvas->drawTextBlob(fBlobs[0], 10, 305, paint);
100 canvas->drawTextBlob(fBlobs[2], 10, 465, paint);
101
102 // Debugging tool for GPU.
103 static const bool kShowAtlas = false;
104 if (kShowAtlas) {
Robert Phillips95c250c2020-06-29 15:36:12 -0400105 auto img = direct->priv().testingOnly_getFontAtlasImage(kA8_GrMaskFormat);
Robert Phillips19104af2019-03-05 12:51:52 -0500106 canvas->drawImage(img, 200, 0);
Jim Van Verth753403c2018-12-18 11:04:37 -0500107 }
108 }
109
110private:
Hal Canaryfa3305a2019-07-18 12:36:54 -0400111 static constexpr int kSize = 512;
Jim Van Verth753403c2018-12-18 11:04:37 -0500112
113 sk_sp<SkTextBlob> fBlobs[3];
114 typedef GM INHERITED;
115};
116
Jim Van Verth753403c2018-12-18 11:04:37 -0500117//////////////////////////////////////////////////////////////////////////////
118
119DEF_GM(return new FontRegenGM())
Jim Van Verth34b72ae2019-11-14 13:42:06 -0500120
121///////////////////////////////////////////////////////////////////////////////
122
123class BadAppleGM : public skiagm::GpuGM {
124
125 SkString onShortName() override { return SkString("badapple"); }
126
127 SkISize onISize() override { return {kSize, kSize}; }
128
129 void onOnceBeforeDraw() override {
130 this->setBGColor(SK_ColorWHITE);
131 auto fm = SkFontMgr::RefDefault();
132
133 static const SkString kTexts[] = {
134 SkString("Meet"),
135 SkString("iPad Pro"),
136 };
137
138 SkFont font;
139 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
140 font.setSubpixel(true);
141 font.setSize(256);
142
143 fBlobs[0] = make_blob(kTexts[0], font);
144 fBlobs[1] = make_blob(kTexts[1], font);
145 }
146
Robert Phillips95c250c2020-06-29 15:36:12 -0400147 void onDraw(GrRecordingContext* context, GrRenderTargetContext*, SkCanvas* canvas) override {
Jim Van Verth34b72ae2019-11-14 13:42:06 -0500148 SkPaint paint;
149 paint.setColor(0xFF111111);
150 canvas->drawTextBlob(fBlobs[0], 10, 260, paint);
151 canvas->drawTextBlob(fBlobs[1], 10, 500, paint);
Jim Van Verth34b72ae2019-11-14 13:42:06 -0500152 }
153
154private:
155 static constexpr int kSize = 512;
156
157 sk_sp<SkTextBlob> fBlobs[3];
158 typedef GM INHERITED;
159};
160
161//////////////////////////////////////////////////////////////////////////////
162
163DEF_GM(return new BadAppleGM())