Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / text / gpu / TextBlob.h
1 /*
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
8 #ifndef sktext_gpu_TextBlob_DEFINED
9 #define sktext_gpu_TextBlob_DEFINED
10
11 #include <algorithm>
12 #include <limits>
13
14 #include "include/core/SkPoint3.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/private/chromium/Slug.h"
17 #include "src/core/SkDevice.h"
18 #include "src/core/SkGlyphRunPainter.h"
19 #include "src/core/SkIPoint16.h"
20 #include "src/core/SkMaskFilterBase.h"
21 #include "src/core/SkOpts.h"
22 #include "src/core/SkRectPriv.h"
23 #include "src/core/SkStrikeSpec.h"
24 #include "src/core/SkTInternalLList.h"
25 #include "src/core/SkTLazy.h"
26 #if SK_SUPPORT_GPU
27 #include "src/gpu/ganesh/GrColor.h"
28 #include "src/gpu/ganesh/ops/GrOp.h"
29 #endif
30 #include "src/text/gpu/SubRunAllocator.h"
31
32 #if SK_SUPPORT_GPU
33 class GrAtlasManager;
34 class GrDeferredUploadTarget;
35 class GrMeshDrawTarget;
36 #endif
37
38 class SkMatrixProvider;
39 class SkStrikeClient;
40 class SkSurfaceProps;
41 class SkTextBlob;
42 class SkTextBlobRunIterator;
43
44 namespace sktext::gpu {
45 class Glyph;
46 class StrikeCache;
47 }
48
49 namespace skgpu::v1 { class SurfaceDrawContext; }
50
51 namespace sktext::gpu {
52
53 // -- AtlasSubRun --------------------------------------------------------------------------------
54 // AtlasSubRun is the API that AtlasTextOp uses to generate vertex data for drawing.
55 //     There are three different ways AtlasSubRun is specialized.
56 //      * DirectMaskSubRun* - this is by far the most common type of SubRun. The mask pixels are
57 //        in 1:1 correspondence with the pixels on the device. The destination rectangles in this
58 //        SubRun are in device space. This SubRun handles color glyphs.
59 //      * TransformedMaskSubRun* - handles glyph where the image in the atlas needs to be
60 //        transformed to the screen. It is usually used for large color glyph which can't be
61 //        drawn with paths or scaled distance fields, but will be used to draw bitmap glyphs to
62 //        the screen, if the matrix does not map 1:1 to the screen. The destination rectangles
63 //        are in source space.
64 //      * SDFTSubRun* - scaled distance field text handles largish single color glyphs that still
65 //        can fit in the atlas; the sizes between direct SubRun, and path SubRun. The destination
66 //        rectangles are in source space.
67 class AtlasSubRun  {
68 public:
69     virtual ~AtlasSubRun() = default;
70
71     virtual int glyphCount() const = 0;
72
73 #if SK_SUPPORT_GPU
74     virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0;
75
76     virtual std::tuple<const GrClip*, GrOp::Owner>
77     makeAtlasTextOp(
78             const GrClip*,
79             const SkMatrixProvider& viewMatrix,
80             SkPoint drawOrigin,
81             const SkPaint&,
82             sk_sp<SkRefCnt>&& subRunStorage,
83             skgpu::v1::SurfaceDrawContext*) const = 0;
84
85     virtual void fillVertexData(
86             void* vertexDst, int offset, int count,
87             GrColor color,
88             const SkMatrix& drawMatrix,
89             SkPoint drawOrigin,
90             SkIRect clip) const = 0;
91
92     // This call is not thread safe. It should only be called from GrDrawOp::onPrepare which
93     // is single threaded.
94     virtual std::tuple<bool, int> regenerateAtlas(
95             int begin, int end, GrMeshDrawTarget* target) const = 0;
96 #endif
97
98     virtual void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache) const = 0;
99 };
100
101 // -- SubRun -------------------------------------------------------------------------------------
102 // SubRun defines the most basic functionality of a SubRun; the ability to draw, and the
103 // ability to be in a list.
104 class SubRun;
105 using SubRunOwner = std::unique_ptr<SubRun, SubRunAllocator::Destroyer>;
106 class BlobSubRun;
107 class SubRun {
108 public:
109     virtual ~SubRun();
110 #if SK_SUPPORT_GPU
111     // Produce GPU ops for this subRun or just draw them.
112     virtual void draw(SkCanvas*,
113                       const GrClip*,
114                       const SkMatrixProvider& viewMatrix,
115                       SkPoint drawOrigin,
116                       const SkPaint&,
117                       sk_sp<SkRefCnt> subRunStorage,
118                       skgpu::v1::SurfaceDrawContext*) const = 0;
119 #endif
120
121     virtual const BlobSubRun* blobCast() const;
122     void flatten(SkWriteBuffer& buffer) const;
123     static SubRunOwner MakeFromBuffer(const SkMatrix& initialPositionMatrix,
124                                       SkReadBuffer& buffer,
125                                       sktext::gpu::SubRunAllocator* alloc,
126                                       const SkStrikeClient* client);
127
128     // Size hint for unflattening this run. If this is accurate, it will help with the allocation
129     // of the slug. If it's off then there may be more allocations needed to unflatten.
130     virtual int unflattenSize() const = 0;
131
132     // Given an already cached subRun, can this subRun handle this combination paint, matrix, and
133     // position.
134     virtual bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const = 0;
135
136     // Return the underlying atlas SubRun if it exists. Otherwise, return nullptr.
137     // * Don't use this API. It is only to support testing.
138     virtual const AtlasSubRun* testingOnly_atlasSubRun() const = 0;
139
140 protected:
141     enum SubRunType : int;
142     virtual SubRunType subRunType() const = 0;
143     virtual void doFlatten(SkWriteBuffer& buffer) const = 0;
144
145 private:
146     friend class SubRunList;
147     SubRunOwner fNext;
148 };
149
150 // -- SubRunList ---------------------------------------------------------------------------------
151 class SubRunList {
152 public:
153     class Iterator {
154     public:
155         using value_type = SubRun;
156         using difference_type = ptrdiff_t;
157         using pointer = value_type*;
158         using reference = value_type&;
159         using iterator_category = std::input_iterator_tag;
160         Iterator(SubRun* subRun) : fPtr{subRun} { }
161         Iterator& operator++() { fPtr = fPtr->fNext.get(); return *this; }
162         Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
163         bool operator==(const Iterator& rhs) const { return fPtr == rhs.fPtr; }
164         bool operator!=(const Iterator& rhs) const { return fPtr != rhs.fPtr; }
165         reference operator*() { return *fPtr; }
166
167     private:
168         SubRun* fPtr;
169     };
170
171     void append(SubRunOwner subRun) {
172         SubRunOwner* newTail = &subRun->fNext;
173         *fTail = std::move(subRun);
174         fTail = newTail;
175     }
176     bool isEmpty() const { return fHead == nullptr; }
177     Iterator begin() { return Iterator{ fHead.get()}; }
178     Iterator end() { return Iterator{nullptr}; }
179     Iterator begin() const { return Iterator{ fHead.get()}; }
180     Iterator end() const { return Iterator{nullptr}; }
181     SubRun& front() const {return *fHead; }
182
183 private:
184     SubRunOwner fHead{nullptr};
185     SubRunOwner* fTail{&fHead};
186 };
187
188 // -- TextBlob -----------------------------------------------------------------------------------
189 // A TextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
190 // on the GPU.  These are initially created with valid positions and colors, but with invalid
191 // texture coordinates.
192 //
193 // A TextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun
194 // tracks its own glyph and position data.
195 //
196 // In these classes, I'm trying to follow the convention about matrices and origins.
197 // * drawMatrix and drawOrigin - describes transformations for the current draw command.
198 // * positionMatrix - is equal to drawMatrix * [drawOrigin-as-translation-matrix]
199 // * initial Matrix - describes the combined initial matrix and origin the TextBlob was created
200 //                    with.
201 //
202 //
203 class TextBlob final : public SkRefCnt {
204 public:
205     // Key is not used as part of a hash map, so the hash is never taken. It's only used in a
206     // list search using operator =().
207     struct Key {
208         static std::tuple<bool, Key> Make(const SkGlyphRunList& glyphRunList,
209                                           const SkPaint& paint,
210                                           const SkMatrix& drawMatrix,
211                                           const SkStrikeDeviceInfo& strikeDevice);
212         uint32_t fUniqueID;
213         // Color may affect the gamma of the mask we generate, but in a fairly limited way.
214         // Each color is assigned to on of a fixed number of buckets based on its
215         // luminance. For each luminance bucket there is a "canonical color" that
216         // represents the bucket.  This functionality is currently only supported for A8
217         SkColor fCanonicalColor;
218         SkScalar fFrameWidth;
219         SkScalar fMiterLimit;
220         SkPixelGeometry fPixelGeometry;
221         SkMaskFilterBase::BlurRec fBlurRec;
222         uint32_t fScalerContextFlags;
223         SkMatrix fPositionMatrix;
224         // Below here fields are of size 1 byte.
225         bool fHasSomeDirectSubRuns;
226         bool fHasBlur;
227         SkPaint::Style fStyle;
228         SkPaint::Join fJoin;
229
230         bool operator==(const Key& other) const;
231     };
232
233     SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob);
234
235     // Make a TextBlob and its sub runs.
236     static sk_sp<TextBlob> Make(const SkGlyphRunList& glyphRunList,
237                                 const SkPaint& paint,
238                                 const SkMatrix& positionMatrix,
239                                 SkStrikeDeviceInfo strikeDeviceInfo,
240                                 SkStrikeForGPUCacheInterface* strikeCache);
241
242     TextBlob(SubRunAllocator&& alloc,
243              int totalMemorySize,
244              const SkMatrix& positionMatrix,
245              SkColor initialLuminance);
246
247     ~TextBlob() override;
248
249     // Change memory management to handle the data after TextBlob, but in the same allocation
250     // of memory. Only allow placement new.
251     void operator delete(void* p);
252     void* operator new(size_t);
253     void* operator new(size_t, void* p);
254
255     const Key& key() { return fKey; }
256
257     void addKey(const Key& key);
258     bool hasPerspective() const;
259
260     bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const;
261
262     const Key& key() const;
263     size_t size() const { return SkTo<size_t>(fSize); }
264
265 #if SK_SUPPORT_GPU
266     void draw(SkCanvas*,
267               const GrClip* clip,
268               const SkMatrixProvider& viewMatrix,
269               SkPoint drawOrigin,
270               const SkPaint& paint,
271               skgpu::v1::SurfaceDrawContext* sdc);
272 #endif
273     const AtlasSubRun* testingOnlyFirstSubRun() const;
274
275 private:
276     // The allocator must come first because it needs to be destroyed last. Other fields of this
277     // structure may have pointers into it.
278     SubRunAllocator fAlloc;
279
280     // Owner and list of the SubRun.
281     SubRunList fSubRunList;
282
283     // Overall size of this struct plus vertices and glyphs at the end.
284     const int fSize;
285
286     // The initial view matrix combined with the initial origin. Used to determine if a cached
287     // subRun can be used in this draw situation.
288     const SkMatrix fInitialPositionMatrix;
289
290     const SkColor fInitialLuminance;
291
292     Key fKey;
293
294     bool fSomeGlyphsExcluded{false};
295 };
296
297 }  // namespace sktext::gpu
298
299 namespace skgpu::v1 {
300 sk_sp<sktext::gpu::Slug> MakeSlug(const SkMatrixProvider& drawMatrix,
301                                   const SkGlyphRunList& glyphRunList,
302                                   const SkPaint& initialPaint,
303                                   const SkPaint& drawingPaint,
304                                   SkStrikeDeviceInfo strikeDeviceInfo,
305                                   SkStrikeForGPUCacheInterface* strikeCache);
306 }  // namespace skgpu::v1
307
308 #endif  // sktext_gpu_TextBlob_DEFINED