Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SubRunContainer.h
Go to the documentation of this file.
1/*
2* Copyright 2022 Google LLC
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#ifndef sktext_gpu_SubRunContainer_DEFINED
9#define sktext_gpu_SubRunContainer_DEFINED
10
13#include "include/core/SkSpan.h"
15
16#include <cstddef>
17#include <functional>
18#include <iterator>
19#include <memory>
20#include <tuple>
21#include <utility>
22
23class SkCanvas;
24class SkPaint;
25class SkReadBuffer;
26class SkStrikeClient;
27class SkWriteBuffer;
28struct SkIRect;
29struct SkPoint;
31
32namespace sktext {
33class GlyphRunList;
34class StrikeForGPUCacheInterface;
35}
36
37namespace skgpu {
38enum class MaskFormat : int;
39}
40
41#if defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
44
45class GrClip;
46namespace skgpu::ganesh {
48}
49#endif
50
51namespace sktext::gpu {
52class GlyphVector;
53class Glyph;
54class StrikeCache;
55class VertexFiller;
56
57using RegenerateAtlasDelegate = std::function<std::tuple<bool, int>(GlyphVector*,
58 int begin,
59 int end,
61 int padding)>;
62
64 bool isSDF = false;
65 bool isLCD = false;
66};
67
68// -- AtlasSubRun --------------------------------------------------------------------------------
69// AtlasSubRun is the API that AtlasTextOp uses to generate vertex data for drawing.
70// There are three different ways AtlasSubRun is specialized.
71// * DirectMaskSubRun* - this is by far the most common type of SubRun. The mask pixels are
72// in 1:1 correspondence with the pixels on the device. The destination rectangles in this
73// SubRun are in device space. This SubRun handles color glyphs.
74// * TransformedMaskSubRun* - handles glyph where the image in the atlas needs to be
75// transformed to the screen. It is usually used for large color glyph which can't be
76// drawn with paths or scaled distance fields, but will be used to draw bitmap glyphs to
77// the screen, if the matrix does not map 1:1 to the screen. The destination rectangles
78// are in source space.
79// * SDFTSubRun* - scaled distance field text handles largish single color glyphs that still
80// can fit in the atlas; the sizes between direct SubRun, and path SubRun. The destination
81// rectangles are in source space.
83public:
84 virtual ~AtlasSubRun() = default;
85
86 virtual SkSpan<const Glyph*> glyphs() const = 0;
87 virtual int glyphCount() const = 0;
88 virtual skgpu::MaskFormat maskFormat() const = 0;
89 virtual int glyphSrcPadding() const = 0;
90 virtual unsigned short instanceFlags() const = 0;
91
92#if defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
93 virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0;
94
95 virtual std::tuple<const GrClip*, GrOp::Owner> makeAtlasTextOp(
96 const GrClip*,
97 const SkMatrix& viewMatrix,
98 SkPoint drawOrigin,
99 const SkPaint&,
100 sk_sp<SkRefCnt>&& subRunStorage,
102
103 virtual void fillVertexData(
104 void* vertexDst, int offset, int count,
106 const SkMatrix& drawMatrix,
107 SkPoint drawOrigin,
108 SkIRect clip) const = 0;
109#endif
110 // This call is not thread safe. It should only be called from a known single-threaded env.
111 virtual std::tuple<bool, int> regenerateAtlas(
112 int begin, int end, RegenerateAtlasDelegate) const = 0;
113
114 virtual const VertexFiller& vertexFiller() const = 0;
115
116 virtual void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache) const = 0;
117};
118
119using AtlasDrawDelegate = std::function<void(const sktext::gpu::AtlasSubRun* subRun,
120 SkPoint drawOrigin,
121 const SkPaint& paint,
122 sk_sp<SkRefCnt> subRunStorage,
124
125// -- SubRun -------------------------------------------------------------------------------------
126// SubRun defines the most basic functionality of a SubRun; the ability to draw, and the
127// ability to be in a list.
128class SubRun;
129using SubRunOwner = std::unique_ptr<SubRun, SubRunAllocator::Destroyer>;
130class SubRun {
131public:
132 virtual ~SubRun();
133
134 virtual void draw(SkCanvas*, SkPoint drawOrigin, const SkPaint&, sk_sp<SkRefCnt> subRunStorage,
135 const AtlasDrawDelegate&) const = 0;
136
137 void flatten(SkWriteBuffer& buffer) const;
140 const SkStrikeClient* client);
141
142 // Size hint for unflattening this run. If this is accurate, it will help with the allocation
143 // of the slug. If it's off then there may be more allocations needed to unflatten.
144 virtual int unflattenSize() const = 0;
145
146 // Given an already cached subRun, can this subRun handle this combination paint, matrix, and
147 // position.
148 virtual bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const = 0;
149
150 // Return the underlying atlas SubRun if it exists. Otherwise, return nullptr.
151 // * Don't use this API. It is only to support testing.
152 virtual const AtlasSubRun* testingOnly_atlasSubRun() const = 0;
153
154protected:
155 enum SubRunStreamTag : int;
156 virtual SubRunStreamTag subRunStreamTag() const = 0;
157 virtual void doFlatten(SkWriteBuffer& buffer) const = 0;
158
159private:
160 friend class SubRunList;
162};
163
164// -- SubRunList -----------------------------------------------------------------------------------
166public:
167 class Iterator {
168 public:
170 using difference_type = ptrdiff_t;
173 using iterator_category = std::input_iterator_tag;
174 Iterator(SubRun* subRun) : fPtr{subRun} { }
175 Iterator& operator++() { fPtr = fPtr->fNext.get(); return *this; }
176 Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
177 bool operator==(const Iterator& rhs) const { return fPtr == rhs.fPtr; }
178 bool operator!=(const Iterator& rhs) const { return fPtr != rhs.fPtr; }
179 reference operator*() { return *fPtr; }
180
181 private:
182 SubRun* fPtr;
183 };
184
185 void append(SubRunOwner subRun) {
186 SubRunOwner* newTail = &subRun->fNext;
187 *fTail = std::move(subRun);
188 fTail = newTail;
189 }
190 bool isEmpty() const { return fHead == nullptr; }
191 Iterator begin() { return Iterator{ fHead.get()}; }
192 Iterator end() { return Iterator{nullptr}; }
193 Iterator begin() const { return Iterator{ fHead.get()}; }
194 Iterator end() const { return Iterator{nullptr}; }
195 SubRun& front() const {return *fHead; }
196
197private:
198 SubRunOwner fHead{nullptr};
199 SubRunOwner* fTail{&fHead};
200};
201
202// -- SubRunContainer ------------------------------------------------------------------------------
203class SubRunContainer;
204using SubRunContainerOwner = std::unique_ptr<SubRunContainer, SubRunAllocator::Destroyer>;
206public:
207 explicit SubRunContainer(const SkMatrix& initialPositionMatrix);
208 SubRunContainer() = delete;
211
212 // Delete the move operations because the SubRuns contain pointers to fInitialPositionMatrix.
215
218
219 void flattenRuns(SkWriteBuffer& buffer) const;
221 const SkStrikeClient* client,
222 SubRunAllocator* alloc);
223
225 // The returned SubRunContainerOwner will never be null. If subRunCreation ==
226 // kStrikeCalculationsOnly, then the returned container will be empty.
227 [[nodiscard]] static SubRunContainerOwner MakeInAlloc(const GlyphRunList& glyphRunList,
228 const SkMatrix& positionMatrix,
229 const SkPaint& runPaint,
230 SkStrikeDeviceInfo strikeDeviceInfo,
231 StrikeForGPUCacheInterface* strikeCache,
233 SubRunCreationBehavior creationBehavior,
234 const char* tag);
235
236 static size_t EstimateAllocSize(const GlyphRunList& glyphRunList);
237
238 void draw(SkCanvas*, SkPoint drawOrigin, const SkPaint&, const SkRefCnt* subRunStorage,
239 const AtlasDrawDelegate&) const;
240
241 const SkMatrix& initialPosition() const { return fInitialPositionMatrix; }
242 bool isEmpty() const { return fSubRuns.isEmpty(); }
243 bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const;
244
245private:
246 friend class TextBlobTools;
247 const SkMatrix fInitialPositionMatrix;
248 SubRunList fSubRuns;
249};
250
251// Returns the empty span if there is a problem reading the positions.
252SkSpan<SkPoint> MakePointsFromBuffer(SkReadBuffer&, SubRunAllocator*);
253
254} // namespace sktext::gpu
255
256#endif // sktext_gpu_SubRunContainer_DEFINED
Instance * fNext
int count
uint32_t GrColor
Definition GrColor.h:25
SkColor4f color
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
Type::kYUV Type::kRGBA() int(0.7 *637)
virtual skgpu::MaskFormat maskFormat() const =0
virtual const VertexFiller & vertexFiller() const =0
virtual unsigned short instanceFlags() const =0
virtual int glyphSrcPadding() const =0
virtual void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const =0
virtual std::tuple< bool, int > regenerateAtlas(int begin, int end, RegenerateAtlasDelegate) const =0
virtual SkSpan< const Glyph * > glyphs() const =0
virtual ~AtlasSubRun()=default
virtual int glyphCount() const =0
static SubRunContainerOwner MakeInAlloc(const GlyphRunList &glyphRunList, const SkMatrix &positionMatrix, const SkPaint &runPaint, SkStrikeDeviceInfo strikeDeviceInfo, StrikeForGPUCacheInterface *strikeCache, sktext::gpu::SubRunAllocator *alloc, SubRunCreationBehavior creationBehavior, const char *tag)
SubRunContainer(SubRunContainer &&)=delete
static size_t EstimateAllocSize(const GlyphRunList &glyphRunList)
void flattenAllocSizeHint(SkWriteBuffer &buffer) const
SubRunContainer(const SubRunContainer &)=delete
const SkMatrix & initialPosition() const
SubRunContainer & operator=(SubRunContainer &&)=delete
static SubRunContainerOwner MakeFromBufferInAlloc(SkReadBuffer &buffer, const SkStrikeClient *client, SubRunAllocator *alloc)
void draw(SkCanvas *, SkPoint drawOrigin, const SkPaint &, const SkRefCnt *subRunStorage, const AtlasDrawDelegate &) const
SubRunContainer & operator=(const SubRunContainer &)=delete
void flattenRuns(SkWriteBuffer &buffer) const
static int AllocSizeHintFromBuffer(SkReadBuffer &buffer)
bool canReuse(const SkPaint &paint, const SkMatrix &positionMatrix) const
bool operator!=(const Iterator &rhs) const
std::input_iterator_tag iterator_category
bool operator==(const Iterator &rhs) const
void append(SubRunOwner subRun)
virtual void doFlatten(SkWriteBuffer &buffer) const =0
virtual int unflattenSize() const =0
virtual void draw(SkCanvas *, SkPoint drawOrigin, const SkPaint &, sk_sp< SkRefCnt > subRunStorage, const AtlasDrawDelegate &) const =0
virtual bool canReuse(const SkPaint &paint, const SkMatrix &positionMatrix) const =0
void flatten(SkWriteBuffer &buffer) const
virtual SubRunStreamTag subRunStreamTag() const =0
virtual const AtlasSubRun * testingOnly_atlasSubRun() const =0
static SubRunOwner MakeFromBuffer(SkReadBuffer &buffer, sktext::gpu::SubRunAllocator *alloc, const SkStrikeClient *client)
const Paint & paint
static const char * begin(const StringSlice &s)
Definition editor.cpp:252
glong glong end
static const uint8_t buffer[]
std::unique_ptr< SubRun, SubRunAllocator::Destroyer > SubRunOwner
std::function< std::tuple< bool, int >(GlyphVector *, int begin, int end, skgpu::MaskFormat, int padding)> RegenerateAtlasDelegate
std::unique_ptr< SubRunContainer, SubRunAllocator::Destroyer > SubRunContainerOwner
std::function< void(const sktext::gpu::AtlasSubRun *subRun, SkPoint drawOrigin, const SkPaint &paint, sk_sp< SkRefCnt > subRunStorage, sktext::gpu::RendererData)> AtlasDrawDelegate
Point offset