blob: e4b24916a49cf092c06919d01db7180d749b9bb6 [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
Herb Derbyb33140a2021-02-08 17:57:03 -050011#include <algorithm>
Robert Phillips51b3e602020-04-09 12:48:50 -040012#include <limits>
13
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkPoint3.h"
Robert Phillips51b3e602020-04-09 12:48:50 -040015#include "include/core/SkRefCnt.h"
16#include "src/core/SkGlyphRunPainter.h"
17#include "src/core/SkIPoint16.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/core/SkMaskFilterBase.h"
19#include "src/core/SkOpts.h"
20#include "src/core/SkRectPriv.h"
Herb Derbye7efd082019-05-28 11:30:33 -040021#include "src/core/SkStrikeSpec.h"
Michael Ludwigb23630c2021-08-10 12:27:25 -040022#include "src/core/SkTInternalLList.h"
Robert Phillips51b3e602020-04-09 12:48:50 -040023#include "src/core/SkTLazy.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040024#include "src/gpu/GrColor.h"
Herb Derbyd5a67642021-04-16 09:07:24 -040025#include "src/gpu/GrSubRunAllocator.h"
Herb Derbyd5a67642021-04-16 09:07:24 -040026#include "src/gpu/ops/GrOp.h"
joshualitt374b2f72015-07-21 08:05:03 -070027
Robert Phillipsc4039ea2018-03-01 11:36:45 -050028class GrAtlasManager;
Herb Derby660c2ff2019-11-14 18:22:41 -050029class GrAtlasTextOp;
Robert Phillips51b3e602020-04-09 12:48:50 -040030class GrDeferredUploadTarget;
Robert Phillips5fa68b42020-03-31 08:34:22 -040031class GrGlyph;
Robert Phillips71143952021-06-17 14:55:07 -040032class GrMeshDrawTarget;
Robert Phillips41bd97d2020-04-07 14:19:37 -040033class GrStrikeCache;
Herb Derby3d00a972020-07-14 11:43:14 -040034class GrSubRun;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050035
Brian Osman449b1152020-04-15 16:43:00 -040036class SkMatrixProvider;
Robert Phillips41bd97d2020-04-07 14:19:37 -040037class SkSurfaceProps;
joshualitt2e2202e2015-12-10 11:22:08 -080038class SkTextBlob;
39class SkTextBlobRunIterator;
40
Robert Phillips643f4812021-08-11 09:31:00 -040041namespace skgpu { namespace v1 { class SurfaceDrawContext; }}
Herb Derby15264442020-12-16 10:45:50 -050042
Herb Derbyd90024d2020-11-20 10:21:32 -050043// -- GrAtlasSubRun --------------------------------------------------------------------------------
44// GrAtlasSubRun is the API that GrAtlasTextOp uses to generate vertex data for drawing.
Herb Derby018f5f62020-10-28 15:55:32 -040045// There are three different ways GrAtlasSubRun is specialized.
Herb Derby15264442020-12-16 10:45:50 -050046// * DirectMaskSubRun - this is by far the most common type of SubRun. The mask pixels are
Herb Derby018f5f62020-10-28 15:55:32 -040047// in 1:1 correspondence with the pixels on the device. The destination rectangles in this
Herb Derby15264442020-12-16 10:45:50 -050048// SubRun are in device space. This SubRun handles color glyphs.
Herb Derby7d3886d2020-11-09 09:08:42 -050049// * TransformedMaskSubRun - handles glyph where the image in the atlas needs to be
Herb Derby018f5f62020-10-28 15:55:32 -040050// transformed to the screen. It is usually used for large color glyph which can't be
51// drawn with paths or scaled distance fields. The destination rectangles are in source
52// space.
Herb Derby7d3886d2020-11-09 09:08:42 -050053// * SDFTSubRun - scaled distance field text handles largish single color glyphs that still
Herb Derby15264442020-12-16 10:45:50 -050054// can fit in the atlas; the sizes between direct SubRun, and path SubRun. The destination
Herb Derby2e0b5bb2020-11-19 11:03:50 -050055
56class GrAtlasSubRun;
57using GrAtlasSubRunOwner = std::unique_ptr<GrAtlasSubRun, GrSubRunAllocator::Destroyer>;
Herb Derbyd90024d2020-11-20 10:21:32 -050058class GrAtlasSubRun {
Herb Derbyc24a6af2020-07-16 12:10:52 -040059public:
60 static constexpr int kVerticesPerGlyph = 4;
Herb Derbyd90024d2020-11-20 10:21:32 -050061
62 virtual ~GrAtlasSubRun() = default;
63
Herb Derby46d1e9f2020-12-01 14:12:04 -050064 virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0;
Herb Derbyc24a6af2020-07-16 12:10:52 -040065 virtual int glyphCount() const = 0;
66
Robert Phillips46eb3ab2021-08-02 17:09:01 -040067#if SK_GPU_V1
Herb Derbyc76d4092020-10-07 16:46:15 -040068 virtual std::tuple<const GrClip*, GrOp::Owner>
Herb Derby2e0b5bb2020-11-19 11:03:50 -050069 makeAtlasTextOp(
Robert Phillips4dca8312021-07-28 15:13:20 -040070 const GrClip*,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050071 const SkMatrixProvider& viewMatrix,
Robert Phillips4dca8312021-07-28 15:13:20 -040072 const SkGlyphRunList&,
73 const SkPaint&,
74 skgpu::v1::SurfaceDrawContext*,
Herb Derby2e0b5bb2020-11-19 11:03:50 -050075 GrAtlasSubRunOwner subRun) const = 0;
Robert Phillips46eb3ab2021-08-02 17:09:01 -040076#endif
77
Herb Derbyc24a6af2020-07-16 12:10:52 -040078 virtual void fillVertexData(
79 void* vertexDst, int offset, int count,
Herb Derby40894182020-12-02 11:39:48 -050080 GrColor color, const SkMatrix& positionMatrix,
Herb Derbyc24a6af2020-07-16 12:10:52 -040081 SkIRect clip) const = 0;
Herb Derby43ad7912020-07-20 16:14:19 -040082
Herb Derbyc27d5352020-08-12 13:58:34 -040083 virtual void testingOnly_packedGlyphIDToGrGlyph(GrStrikeCache* cache) = 0;
84
Herb Derby43ad7912020-07-20 16:14:19 -040085 // This call is not thread safe. It should only be called from GrDrawOp::onPrepare which
86 // is single threaded.
87 virtual std::tuple<bool, int> regenerateAtlas(
Robert Phillips71143952021-06-17 14:55:07 -040088 int begin, int end, GrMeshDrawTarget* target) const = 0;
Herb Derbyc24a6af2020-07-16 12:10:52 -040089};
Herb Derbyd90024d2020-11-20 10:21:32 -050090
91// -- GrSubRun -------------------------------------------------------------------------------------
Herb Derby15264442020-12-16 10:45:50 -050092// GrSubRun is the API the GrTextBlob uses for the SubRun.
93// There are several types of SubRun, which can be broken into five classes:
Herb Derbyd90024d2020-11-20 10:21:32 -050094// * PathSubRun - handle very large single color glyphs using paths to render the glyph.
95// * DirectMaskSubRun - handle the majority of the glyphs where the cache entry's pixels are in
96// 1:1 correspondence to the device pixels.
97// * TransformedMaskSubRun - handle large bitmap/argb glyphs that need to be scaled to the screen.
98// * SDFTSubRun - use signed distance fields to draw largish glyphs to the screen.
99// * GrAtlasSubRun - this is an abstract class used for atlas drawing.
Herb Derbyc1a06002021-03-11 10:57:16 -0500100class GrSubRun;
101using GrSubRunOwner = std::unique_ptr<GrSubRun, GrSubRunAllocator::Destroyer>;
Herb Derbyd90024d2020-11-20 10:21:32 -0500102class GrSubRun {
103public:
104 virtual ~GrSubRun() = default;
105
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400106#if SK_GPU_V1
Herb Derbyd90024d2020-11-20 10:21:32 -0500107 // Produce GPU ops for this subRun.
Robert Phillips4dca8312021-07-28 15:13:20 -0400108 virtual void draw(const GrClip*,
Herb Derbyd90024d2020-11-20 10:21:32 -0500109 const SkMatrixProvider& viewMatrix,
Robert Phillips4dca8312021-07-28 15:13:20 -0400110 const SkGlyphRunList&,
111 const SkPaint&,
112 skgpu::v1::SurfaceDrawContext*) const = 0;
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400113#endif
Herb Derbyd90024d2020-11-20 10:21:32 -0500114
115 // Given an already cached subRun, can this subRun handle this combination paint, matrix, and
116 // position.
Herb Derby743c6972021-02-23 12:57:56 -0500117 virtual bool canReuse(const SkPaint& paint, const SkMatrix& drawMatrix) const = 0;
Herb Derbyd90024d2020-11-20 10:21:32 -0500118
Herb Derby15264442020-12-16 10:45:50 -0500119 // Return the underlying atlas SubRun if it exists. Otherwise, return nullptr.
Herb Derbyd90024d2020-11-20 10:21:32 -0500120 // * Don't use this API. It is only to support testing.
121 virtual GrAtlasSubRun* testingOnly_atlasSubRun() = 0;
122
Herb Derbyc1a06002021-03-11 10:57:16 -0500123 GrSubRunOwner fNext;
Herb Derby55f795e2021-02-05 13:45:05 -0500124};
125
126struct GrSubRunList {
127 class Iterator {
128 public:
129 using value_type = GrSubRun;
130 using difference_type = ptrdiff_t;
131 using pointer = value_type*;
132 using reference = value_type&;
133 using iterator_category = std::input_iterator_tag;
Herb Derby15264442020-12-16 10:45:50 -0500134 Iterator(GrSubRun* subRun) : fPtr{subRun} { }
135 Iterator& operator++() { fPtr = fPtr->fNext.get(); return *this; }
136 Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
137 bool operator==(const Iterator& rhs) const { return fPtr == rhs.fPtr; }
138 bool operator!=(const Iterator& rhs) const { return fPtr != rhs.fPtr; }
139 reference operator*() { return *fPtr; }
Herb Derby55f795e2021-02-05 13:45:05 -0500140
141 private:
142 GrSubRun* fPtr;
143 };
144
Herb Derbyc1a06002021-03-11 10:57:16 -0500145 void append(GrSubRunOwner subRun) {
146 GrSubRunOwner* newTail = &subRun->fNext;
Herb Derby15264442020-12-16 10:45:50 -0500147 *fTail = std::move(subRun);
Herb Derby55f795e2021-02-05 13:45:05 -0500148 fTail = newTail;
149 }
150 bool isEmpty() const { return fHead == nullptr; }
Herb Derby15264442020-12-16 10:45:50 -0500151 Iterator begin() { return Iterator{ fHead.get()}; }
Herb Derby55f795e2021-02-05 13:45:05 -0500152 Iterator end() { return Iterator{nullptr}; }
Herb Derby6b27ae82021-02-23 13:03:59 -0500153 Iterator begin() const { return Iterator{ fHead.get()}; }
154 Iterator end() const { return Iterator{nullptr}; }
Herb Derby55f795e2021-02-05 13:45:05 -0500155 GrSubRun& front() const {return *fHead; }
156
Herb Derbyc1a06002021-03-11 10:57:16 -0500157 GrSubRunOwner fHead{nullptr};
158 GrSubRunOwner* fTail{&fHead};
Herb Derby55f795e2021-02-05 13:45:05 -0500159};
160
161// A GrTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
162// on the GPU. These are initially created with valid positions and colors, but invalid
163// texture coordinates.
164//
165// A GrTextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun
166// tracks its own GrGlyph* and vertex data. The memory is organized in the arena in the following
167// way so that the pointers for the GrGlyph* and vertex data are known before creating the SubRun.
168//
169// GrGlyph*... | vertexData... | SubRun | GrGlyph*... | vertexData... | SubRun etc.
170//
171// In these classes, I'm trying to follow the convention about matrices and origins.
172// * draw Matrix|Origin - describes the current draw command.
173// * initial Matrix - describes the combined initial matrix and origin the GrTextBlob was created
174// with.
175//
176//
177class GrTextBlob final : public SkNVRefCnt<GrTextBlob>, public SkGlyphRunPainterInterface {
178public:
Herb Derby64477842021-03-08 13:47:06 -0500179
180 // Key is not used as part of a hash map, so the hash is never taken. It's only used in a
181 // list search using operator =().
Herb Derby55f795e2021-02-05 13:45:05 -0500182 struct Key {
Herb Derby64477842021-03-08 13:47:06 -0500183 static std::tuple<bool, Key> Make(const SkGlyphRunList& glyphRunList,
Herb Derby0da2c142021-03-22 15:28:23 -0400184 const SkPaint& paint,
Herb Derby64477842021-03-08 13:47:06 -0500185 const SkSurfaceProps& surfaceProps,
186 const GrColorInfo& colorInfo,
187 const SkMatrix& drawMatrix,
188 const GrSDFTControl& control);
Herb Derby55f795e2021-02-05 13:45:05 -0500189 uint32_t fUniqueID;
190 // Color may affect the gamma of the mask we generate, but in a fairly limited way.
191 // Each color is assigned to on of a fixed number of buckets based on its
192 // luminance. For each luminance bucket there is a "canonical color" that
193 // represents the bucket. This functionality is currently only supported for A8
194 SkColor fCanonicalColor;
Herb Derby55f795e2021-02-05 13:45:05 -0500195 SkScalar fFrameWidth;
196 SkScalar fMiterLimit;
Herb Derby55f795e2021-02-05 13:45:05 -0500197 SkPixelGeometry fPixelGeometry;
Herb Derby55f795e2021-02-05 13:45:05 -0500198 SkMaskFilterBase::BlurRec fBlurRec;
199 uint32_t fScalerContextFlags;
Herb Derbye4ef35c2021-03-01 11:49:32 -0500200 SkMatrix fDrawMatrix;
201 // Below here fields are of size 1 byte.
202 uint8_t fSetOfDrawingTypes;
203 bool fHasBlur;
204 SkPaint::Style fStyle;
205 SkPaint::Join fJoin;
Herb Derby55f795e2021-02-05 13:45:05 -0500206
207 bool operator==(const Key& other) const;
208 };
209
210 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrTextBlob);
211
Herb Derby63fe8e52021-03-08 13:22:56 -0500212 // Make a GrTextBlob and its sub runs.
Herb Derby55f795e2021-02-05 13:45:05 -0500213 static sk_sp<GrTextBlob> Make(const SkGlyphRunList& glyphRunList,
Herb Derby0da2c142021-03-22 15:28:23 -0400214 const SkPaint& paint,
Herb Derby63fe8e52021-03-08 13:22:56 -0500215 const SkMatrix& drawMatrix,
216 const GrSDFTControl& control,
217 SkGlyphRunListPainter* painter);
Herb Derby55f795e2021-02-05 13:45:05 -0500218
219 ~GrTextBlob() override;
220
221 // Change memory management to handle the data after GrTextBlob, but in the same allocation
222 // of memory. Only allow placement new.
223 void operator delete(void* p);
224 void* operator new(size_t);
225 void* operator new(size_t, void* p);
226
Herb Derbyc8e31ea2021-03-08 12:42:17 -0500227 const Key& key() { return fKey; }
Herb Derby55f795e2021-02-05 13:45:05 -0500228
229 void addKey(const Key& key);
230 bool hasPerspective() const;
231 const SkMatrix& initialMatrix() const { return fInitialMatrix; }
232
Herb Derby55f795e2021-02-05 13:45:05 -0500233 std::tuple<SkScalar, SkScalar> scaleBounds() const {
234 return {fMaxMinScale, fMinMaxScale};
235 }
236
Herb Derby743c6972021-02-23 12:57:56 -0500237 bool canReuse(const SkPaint& paint, const SkMatrix& drawMatrix) const;
Herb Derby55f795e2021-02-05 13:45:05 -0500238
239 const Key& key() const;
240 size_t size() const;
241
Herb Derby6b27ae82021-02-23 13:03:59 -0500242 const GrSubRunList& subRunList() const {
Herb Derby55f795e2021-02-05 13:45:05 -0500243 return fSubRunList;
244 }
245
Herb Derbyd90024d2020-11-20 10:21:32 -0500246private:
Herb Derby15264442020-12-16 10:45:50 -0500247 GrTextBlob(int allocSize, const SkMatrix& drawMatrix, SkColor initialLuminance);
Herb Derby55f795e2021-02-05 13:45:05 -0500248
Herb Derbyd15c52d2021-02-23 13:33:12 -0500249 template<typename AddSingleMaskFormat>
250 void addMultiMaskFormat(
251 AddSingleMaskFormat addSingle,
252 const SkZip<SkGlyphVariant, SkPoint>& drawables,
253 const SkStrikeSpec& strikeSpec);
254
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400255#if SK_GPU_V1
Herb Derby55f795e2021-02-05 13:45:05 -0500256 // Methods to satisfy SkGlyphRunPainterInterface
257 void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
258 const SkStrikeSpec& strikeSpec) override;
259 void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables,
260 const SkFont& runFont,
261 const SkStrikeSpec& strikeSpec) override;
262 void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables,
263 const SkStrikeSpec& strikeSpec,
264 const SkFont& runFont,
265 SkScalar minScale,
266 SkScalar maxScale) override;
267 void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
268 const SkStrikeSpec& strikeSpec) override;
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400269#endif // SK_GPU_V1
Herb Derby55f795e2021-02-05 13:45:05 -0500270
Herb Derby15264442020-12-16 10:45:50 -0500271 // The allocator must come first because it needs to be destroyed last. Other fields of this
272 // structure may have pointers into it.
273 GrSubRunAllocator fAlloc;
274
275 // Owner and list of the SubRun.
276 GrSubRunList fSubRunList;
277
Herb Derby55f795e2021-02-05 13:45:05 -0500278 // Overall size of this struct plus vertices and glyphs at the end.
Herb Derby15264442020-12-16 10:45:50 -0500279 const int fSize;
Herb Derby55f795e2021-02-05 13:45:05 -0500280
281 // The initial view matrix combined with the initial origin. Used to determine if a cached
282 // subRun can be used in this draw situation.
283 const SkMatrix fInitialMatrix;
284
285 const SkColor fInitialLuminance;
286
287 Key fKey;
288
289 // We can reuse distance field text, but only if the new view matrix would not result in
290 // a mip change. Because there can be multiple runs in a blob, we track the overall
291 // maximum minimum scale, and minimum maximum scale, we can support before we need to regen
292 SkScalar fMaxMinScale{-SK_ScalarMax};
293 SkScalar fMinMaxScale{SK_ScalarMax};
294
295 bool fSomeGlyphsExcluded{false};
Herb Derbyd90024d2020-11-20 10:21:32 -0500296};
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500297
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400298#if SK_GPU_V1
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500299class GrSubRunNoCachePainter : public SkGlyphRunPainterInterface {
300public:
Robert Phillips4dca8312021-07-28 15:13:20 -0400301 GrSubRunNoCachePainter(skgpu::v1::SurfaceDrawContext*,
302 GrSubRunAllocator*,
303 const GrClip*,
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500304 const SkMatrixProvider& viewMatrix,
Robert Phillips4dca8312021-07-28 15:13:20 -0400305 const SkGlyphRunList&,
306 const SkPaint&);
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500307 void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
308 const SkStrikeSpec& strikeSpec) override;
309 void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
310 const SkStrikeSpec& strikeSpec) override;
311 void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables,
312 const SkFont& runFont, const SkStrikeSpec& strikeSpec) override;
313 void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables,
314 const SkStrikeSpec& strikeSpec, const SkFont& runFont,
315 SkScalar minScale, SkScalar maxScale) override;
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400316
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500317private:
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400318
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500319 // Draw passes ownership of the sub run to the op.
320 void draw(GrAtlasSubRunOwner subRun);
321
Robert Phillips4dca8312021-07-28 15:13:20 -0400322 skgpu::v1::SurfaceDrawContext* const fSDC;
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500323 GrSubRunAllocator* const fAlloc;
324 const GrClip* const fClip;
325 const SkMatrixProvider& fViewMatrix;
326 const SkGlyphRunList& fGlyphRunList;
Herb Derby0da2c142021-03-22 15:28:23 -0400327 const SkPaint& fPaint;
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500328};
Robert Phillips46eb3ab2021-08-02 17:09:01 -0400329#endif // SK_GPU_V1
Herb Derby2e0b5bb2020-11-19 11:03:50 -0500330
Herb Derby86240592018-05-24 16:12:31 -0400331#endif // GrTextBlob_DEFINED