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