blob: b34dd8114966b4a9ef912d8a75527696e99e7eb8 [file] [log] [blame]
joshualitt374b2f72015-07-21 08:05:03 -07001/*
2 * Copyright 2015 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
Herb Derby86240592018-05-24 16:12:31 -04008#ifndef GrTextBlob_DEFINED
9#define GrTextBlob_DEFINED
joshualitt374b2f72015-07-21 08:05:03 -070010
Robert Phillips51b3e602020-04-09 12:48:50 -040011#include <limits>
12
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkPoint3.h"
Robert Phillips51b3e602020-04-09 12:48:50 -040014#include "include/core/SkRefCnt.h"
15#include "src/core/SkGlyphRunPainter.h"
16#include "src/core/SkIPoint16.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/core/SkMaskFilterBase.h"
18#include "src/core/SkOpts.h"
19#include "src/core/SkRectPriv.h"
Herb Derbye7efd082019-05-28 11:30:33 -040020#include "src/core/SkStrikeSpec.h"
Robert Phillips51b3e602020-04-09 12:48:50 -040021#include "src/core/SkTLazy.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040022#include "src/gpu/GrColor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/GrDrawOpAtlas.h"
Herb Derbyd68ad7d2020-07-13 15:08:32 -040024#include "src/gpu/ops/GrMeshDrawOp.h"
Herb Derbyc1cde362020-07-17 14:07:00 -040025#include "src/gpu/text/GrStrikeCache.h"
joshualitt374b2f72015-07-21 08:05:03 -070026
Robert Phillipsc4039ea2018-03-01 11:36:45 -050027class GrAtlasManager;
Herb Derby660c2ff2019-11-14 18:22:41 -050028class GrAtlasTextOp;
Robert Phillips51b3e602020-04-09 12:48:50 -040029class GrDeferredUploadTarget;
Herb Derby4a1f5fc2020-07-10 16:39:28 -040030class GrDrawOp;
Robert Phillips5fa68b42020-03-31 08:34:22 -040031class GrGlyph;
Robert Phillips41bd97d2020-04-07 14:19:37 -040032class GrStrikeCache;
Herb Derby3d00a972020-07-14 11:43:14 -040033class GrSubRun;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050034
Brian Osman449b1152020-04-15 16:43:00 -040035class SkMatrixProvider;
Robert Phillips41bd97d2020-04-07 14:19:37 -040036class SkSurfaceProps;
joshualitt2e2202e2015-12-10 11:22:08 -080037class SkTextBlob;
38class SkTextBlobRunIterator;
39
Herb Derbyc514e7d2019-12-11 17:00:31 -050040// A GrTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
41// on the GPU. These are initially created with valid positions and colors, but invalid
42// texture coordinates.
43//
44// A GrTextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun
45// tracks its own GrGlyph* and vertex data. The memory is organized in the arena in the following
46// way so that the pointers for the GrGlyph* and vertex data are known before creating the SubRun.
47//
48// GrGlyph*... | vertexData... | SubRun | GrGlyph*... | vertexData... | SubRun etc.
49//
Herb Derby5bf5b042019-12-12 16:37:03 -050050// In these classes, I'm trying to follow the convention about matrices and origins.
51// * draw Matrix|Origin - describes the current draw command.
Herb Derby1d0ee962020-09-09 15:46:46 -040052// * initial Matrix - describes the combined initial matrix and origin the GrTextBlob was created
53// with.
Herb Derby5bf5b042019-12-12 16:37:03 -050054//
Herb Derby5bf5b042019-12-12 16:37:03 -050055//
Herb Derbya9047642019-12-06 12:12:11 -050056class GrTextBlob final : public SkNVRefCnt<GrTextBlob>, public SkGlyphRunPainterInterface {
joshualitt2e2202e2015-12-10 11:22:08 -080057public:
joshualitt323c2eb2016-01-20 06:48:47 -080058 struct Key {
Herb Derbya9047642019-12-06 12:12:11 -050059 Key();
joshualitt323c2eb2016-01-20 06:48:47 -080060 uint32_t fUniqueID;
61 // Color may affect the gamma of the mask we generate, but in a fairly limited way.
62 // Each color is assigned to on of a fixed number of buckets based on its
63 // luminance. For each luminance bucket there is a "canonical color" that
64 // represents the bucket. This functionality is currently only supported for A8
65 SkColor fCanonicalColor;
66 SkPaint::Style fStyle;
Herb Derby00b2fdb2020-09-03 11:54:01 -040067 SkScalar fFrameWidth;
68 SkScalar fMiterLimit;
69 SkPaint::Join fJoin;
Herb Derby5c7f38a2019-12-13 16:28:42 +000070 SkPixelGeometry fPixelGeometry;
joshualitt323c2eb2016-01-20 06:48:47 -080071 bool fHasBlur;
Herb Derby00b2fdb2020-09-03 11:54:01 -040072 SkMaskFilterBase::BlurRec fBlurRec;
Herb Derby5c7f38a2019-12-13 16:28:42 +000073 uint32_t fScalerContextFlags;
joshualitt323c2eb2016-01-20 06:48:47 -080074
Herb Derbya9047642019-12-06 12:12:11 -050075 bool operator==(const Key& other) const;
joshualitt323c2eb2016-01-20 06:48:47 -080076 };
77
Herb Derbya9047642019-12-06 12:12:11 -050078 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrTextBlob);
79
80 // Change memory management to handle the data after GrTextBlob, but in the same allocation
81 // of memory. Only allow placement new.
82 void operator delete(void* p);
83 void* operator new(size_t);
84 void* operator new(size_t, void* p);
85
86 ~GrTextBlob() override;
87
88 // Make an empty GrTextBlob, with all the invariants set to make the right decisions when
89 // adding SubRuns.
Herb Derby659e4092019-12-06 15:38:10 -050090 static sk_sp<GrTextBlob> Make(const SkGlyphRunList& glyphRunList,
Herb Derbybe202052020-06-05 17:22:38 -040091 const SkMatrix& drawMatrix);
Herb Derbya9047642019-12-06 12:12:11 -050092
Herb Derbya9047642019-12-06 12:12:11 -050093 static const Key& GetKey(const GrTextBlob& blob);
94 static uint32_t Hash(const Key& key);
joshualitt92303772016-02-10 11:55:52 -080095
Herb Derby00b2fdb2020-09-03 11:54:01 -040096 void addKey(const Key& key);
Herb Derbya9047642019-12-06 12:12:11 -050097 bool hasPerspective() const;
Herb Derby81c6d6e2020-09-03 17:10:45 -040098 const SkMatrix& initialMatrix() const { return fInitialMatrix; }
joshualitt323c2eb2016-01-20 06:48:47 -080099
Herb Derbya9047642019-12-06 12:12:11 -0500100 void setMinAndMaxScale(SkScalar scaledMin, SkScalar scaledMax);
Herb Derby81c6d6e2020-09-03 17:10:45 -0400101 std::tuple<SkScalar, SkScalar> scaleBounds() const {
102 return {fMaxMinScale, fMinMaxScale};
103 }
joshualitt323c2eb2016-01-20 06:48:47 -0800104
Herb Derby734f8e32020-09-09 17:43:05 -0400105 bool canReuse(const SkPaint& paint, const SkMatrix& drawMatrix);
joshualitt323c2eb2016-01-20 06:48:47 -0800106
Herb Derbya9047642019-12-06 12:12:11 -0500107 const Key& key() const;
108 size_t size() const;
joshualitt92303772016-02-10 11:55:52 -0800109
Herb Derby31adbc62020-05-29 12:59:22 -0400110 template<typename AddSingleMaskFormat>
Herb Derby1b8dcd12019-11-15 15:21:15 -0500111 void addMultiMaskFormat(
Herb Derby31adbc62020-05-29 12:59:22 -0400112 AddSingleMaskFormat addSingle,
Herb Derby1b8dcd12019-11-15 15:21:15 -0500113 const SkZip<SkGlyphVariant, SkPoint>& drawables,
Herb Derby90f211f2020-11-18 11:10:54 -0500114 const SkStrikeSpec& strikeSpec);
Herb Derby1b8dcd12019-11-15 15:21:15 -0500115
Herb Derby3d00a972020-07-14 11:43:14 -0400116 const SkTInternalLList<GrSubRun>& subRunList() const { return fSubRunList; }
Herb Derbye5b768b2020-07-07 15:56:07 -0400117
Herb Derby660c2ff2019-11-14 18:22:41 -0500118private:
Herb Derby734f8e32020-09-09 17:43:05 -0400119 GrTextBlob(size_t allocSize, const SkMatrix& drawMatrix, SkColor initialLuminance);
Herb Derby00ae9592019-12-03 15:55:56 -0500120
Herb Derby3d00a972020-07-14 11:43:14 -0400121 void insertSubRun(GrSubRun* subRun);
Herb Derbycb718892019-12-07 00:07:42 -0500122
Herb Derbya9047642019-12-06 12:12:11 -0500123 // Methods to satisfy SkGlyphRunPainterInterface
Herb Derby20eafff2019-10-16 16:21:13 -0400124 void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
Herb Derby90f211f2020-11-18 11:10:54 -0500125 const SkStrikeSpec& strikeSpec) override;
Herb Derby12130412019-10-21 18:02:24 -0400126 void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables,
Herb Derby1b8dcd12019-11-15 15:21:15 -0500127 const SkFont& runFont,
Herb Derby36a54c12019-06-06 10:50:56 -0400128 const SkStrikeSpec& strikeSpec) override;
Herb Derby20eafff2019-10-16 16:21:13 -0400129 void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables,
Herb Derby36a54c12019-06-06 10:50:56 -0400130 const SkStrikeSpec& strikeSpec,
Herb Derbyc72594a2019-03-05 17:39:38 -0500131 const SkFont& runFont,
Herb Derbyc72594a2019-03-05 17:39:38 -0500132 SkScalar minScale,
Herb Derby1b8dcd12019-11-15 15:21:15 -0500133 SkScalar maxScale) override;
Herb Derby1b8dcd12019-11-15 15:21:15 -0500134 void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
135 const SkStrikeSpec& strikeSpec) override;
Herb Derbyc72594a2019-03-05 17:39:38 -0500136
Herb Derby00ae9592019-12-03 15:55:56 -0500137 // Overall size of this struct plus vertices and glyphs at the end.
138 const size_t fSize;
Herb Derby1b8dcd12019-11-15 15:21:15 -0500139
Herb Derby1d0ee962020-09-09 15:46:46 -0400140 // The initial view matrix combined with the initial origin. Used to determine if a cached
141 // subRun can be used in this draw situation.
Herb Derby1c5be7b2019-12-13 12:03:06 -0500142 const SkMatrix fInitialMatrix;
Herb Derbye9f691d2019-12-04 12:11:13 -0500143
Herb Derbyaebc5f82019-12-10 14:07:10 -0500144 const SkColor fInitialLuminance;
Herb Derby1b8dcd12019-11-15 15:21:15 -0500145
joshualitt374b2f72015-07-21 08:05:03 -0700146 Key fKey;
joshualitt374b2f72015-07-21 08:05:03 -0700147
Herb Derbyeba195f2019-12-03 16:44:47 -0500148 // We can reuse distance field text, but only if the new view matrix would not result in
joshualitt374b2f72015-07-21 08:05:03 -0700149 // a mip change. Because there can be multiple runs in a blob, we track the overall
150 // maximum minimum scale, and minimum maximum scale, we can support before we need to regen
Herb Derbya00da612019-03-04 17:10:01 -0500151 SkScalar fMaxMinScale{-SK_ScalarMax};
152 SkScalar fMinMaxScale{SK_ScalarMax};
Herb Derby1b8dcd12019-11-15 15:21:15 -0500153
Herb Derby624f3f72020-10-29 17:56:26 -0400154 bool fSomeGlyphsExcluded{false};
Herb Derby3d00a972020-07-14 11:43:14 -0400155 SkTInternalLList<GrSubRun> fSubRunList;
Herb Derbycb718892019-12-07 00:07:42 -0500156 SkArenaAlloc fAlloc;
joshualitt374b2f72015-07-21 08:05:03 -0700157};
158
Herb Derbyd90024d2020-11-20 10:21:32 -0500159// -- GrAtlasSubRun --------------------------------------------------------------------------------
160// GrAtlasSubRun is the API that GrAtlasTextOp uses to generate vertex data for drawing.
Herb Derby018f5f62020-10-28 15:55:32 -0400161// There are three different ways GrAtlasSubRun is specialized.
Herb Derby7d3886d2020-11-09 09:08:42 -0500162// * DirectMaskSubRun - this is by far the most common type of subrun. The mask pixels are
Herb Derby018f5f62020-10-28 15:55:32 -0400163// in 1:1 correspondence with the pixels on the device. The destination rectangles in this
164// subrun are in device space. This subrun handles color glyphs.
Herb Derby7d3886d2020-11-09 09:08:42 -0500165// * TransformedMaskSubRun - handles glyph where the image in the atlas needs to be
Herb Derby018f5f62020-10-28 15:55:32 -0400166// transformed to the screen. It is usually used for large color glyph which can't be
167// drawn with paths or scaled distance fields. The destination rectangles are in source
168// space.
Herb Derby7d3886d2020-11-09 09:08:42 -0500169// * SDFTSubRun - scaled distance field text handles largish single color glyphs that still
Herb Derby018f5f62020-10-28 15:55:32 -0400170// can fit in the atlas; the sizes between direct subruns, and path subruns. The destination
Herb Derbyd90024d2020-11-20 10:21:32 -0500171class GrAtlasSubRun {
Herb Derbyc24a6af2020-07-16 12:10:52 -0400172public:
173 static constexpr int kVerticesPerGlyph = 4;
Herb Derbyd90024d2020-11-20 10:21:32 -0500174
175 virtual ~GrAtlasSubRun() = default;
176
Herb Derby46d1e9f2020-12-01 14:12:04 -0500177 virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0;
Herb Derbyc24a6af2020-07-16 12:10:52 -0400178 virtual int glyphCount() const = 0;
179
Herb Derbyc76d4092020-10-07 16:46:15 -0400180 virtual std::tuple<const GrClip*, GrOp::Owner>
Herb Derbyc24a6af2020-07-16 12:10:52 -0400181 makeAtlasTextOp(const GrClip* clip,
182 const SkMatrixProvider& viewMatrix,
183 const SkGlyphRunList& glyphRunList,
Herb Derby43ad7912020-07-20 16:14:19 -0400184 GrRenderTargetContext* rtc) const = 0;
Herb Derbyc24a6af2020-07-16 12:10:52 -0400185 virtual void fillVertexData(
186 void* vertexDst, int offset, int count,
Herb Derby40894182020-12-02 11:39:48 -0500187 GrColor color, const SkMatrix& positionMatrix,
Herb Derbyc24a6af2020-07-16 12:10:52 -0400188 SkIRect clip) const = 0;
Herb Derby43ad7912020-07-20 16:14:19 -0400189
Herb Derbyc27d5352020-08-12 13:58:34 -0400190 virtual void testingOnly_packedGlyphIDToGrGlyph(GrStrikeCache* cache) = 0;
191
Herb Derby43ad7912020-07-20 16:14:19 -0400192 // This call is not thread safe. It should only be called from GrDrawOp::onPrepare which
193 // is single threaded.
194 virtual std::tuple<bool, int> regenerateAtlas(
195 int begin, int end, GrMeshDrawOp::Target* target) const = 0;
Herb Derbyc24a6af2020-07-16 12:10:52 -0400196};
Herb Derbyd90024d2020-11-20 10:21:32 -0500197
198// -- GrSubRun -------------------------------------------------------------------------------------
199// GrSubRun is the API the GrTextBlob uses for the subruns.
200// There are several types of subrun, which can be broken into five classes:
201// * PathSubRun - handle very large single color glyphs using paths to render the glyph.
202// * DirectMaskSubRun - handle the majority of the glyphs where the cache entry's pixels are in
203// 1:1 correspondence to the device pixels.
204// * TransformedMaskSubRun - handle large bitmap/argb glyphs that need to be scaled to the screen.
205// * SDFTSubRun - use signed distance fields to draw largish glyphs to the screen.
206// * GrAtlasSubRun - this is an abstract class used for atlas drawing.
207class GrSubRun {
208public:
209 virtual ~GrSubRun() = default;
210
211 // Produce GPU ops for this subRun.
212 virtual void draw(const GrClip* clip,
213 const SkMatrixProvider& viewMatrix,
214 const SkGlyphRunList& glyphRunList,
215 GrRenderTargetContext* rtc) const = 0;
216
217 // Given an already cached subRun, can this subRun handle this combination paint, matrix, and
218 // position.
219 virtual bool canReuse(const SkPaint& paint, const SkMatrix& drawMatrix) = 0;
220
221 // Return the underlying atlas subrun if it exists. Otherwise, return nullptr.
222 // * Don't use this API. It is only to support testing.
223 virtual GrAtlasSubRun* testingOnly_atlasSubRun() = 0;
224
225private:
226 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrSubRun);
227};
Herb Derby86240592018-05-24 16:12:31 -0400228#endif // GrTextBlob_DEFINED