xref: /aosp_15_r20/external/skia/src/text/gpu/TextBlob.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "include/core/SkColor.h"
12 #include "include/core/SkMatrix.h"
13 #include "include/core/SkPaint.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkSurfaceProps.h"
17 #include "include/private/base/SkTo.h"
18 #include "src/base/SkTInternalLList.h"
19 #include "src/core/SkMaskFilterBase.h"
20 #include "src/text/gpu/SubRunAllocator.h"
21 #include "src/text/gpu/SubRunContainer.h"
22 
23 #include <cstddef>
24 #include <cstdint>
25 #include <tuple>
26 
27 class SkCanvas;
28 struct SkPoint;
29 struct SkStrikeDeviceInfo;
30 
31 namespace sktext {
32 class GlyphRunList;
33 class StrikeForGPUCacheInterface;
34 }
35 
36 namespace sktext::gpu {
37 class Slug;
38 
39 // -- TextBlob -----------------------------------------------------------------------------------
40 // A TextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
41 // on the GPU.  These are initially created with valid positions and colors, but with invalid
42 // texture coordinates.
43 //
44 // A TextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun
45 // tracks its own glyph and position data.
46 //
47 // In these classes, I'm trying to follow the convention about matrices and origins.
48 // * drawMatrix and drawOrigin - describes transformations for the current draw command.
49 // * positionMatrix - is equal to drawMatrix * [drawOrigin-as-translation-matrix]
50 // * initial Matrix - describes the combined initial matrix and origin the TextBlob was created
51 //                    with.
52 //
53 //
54 class TextBlob final : public SkRefCnt {
55 public:
56     // Key is not used as part of a hash map, so the hash is never taken. It's only used in a
57     // list search using operator =().
58     struct Key {
59         static std::tuple<bool, Key> Make(const GlyphRunList& glyphRunList,
60                                           const SkPaint& paint,
61                                           const SkMatrix& drawMatrix,
62                                           const SkStrikeDeviceInfo& strikeDevice);
63         uint32_t fUniqueID;
64         // Color may affect the gamma of the mask we generate, but in a fairly limited way.
65         // Each color is assigned to on of a fixed number of buckets based on its
66         // luminance. For each luminance bucket there is a "canonical color" that
67         // represents the bucket.  This functionality is currently only supported for A8
68         SkColor fCanonicalColor;
69         SkScalar fFrameWidth;
70         SkScalar fMiterLimit;
71         SkPixelGeometry fPixelGeometry;
72         SkMaskFilterBase::BlurRec fBlurRec;
73         uint32_t fScalerContextFlags;
74         SkMatrix fPositionMatrix;
75         // Below here fields are of size 1 byte.
76         bool fHasSomeDirectSubRuns;
77         bool fHasBlur;
78         SkPaint::Style fStyle;
79         SkPaint::Join fJoin;
80 
81         bool operator==(const Key& other) const;
82     };
83 
84     SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob);
85 
86     // Make a TextBlob and its sub runs.
87     static sk_sp<TextBlob> Make(const sktext::GlyphRunList& glyphRunList,
88                                 const SkPaint& paint,
89                                 const SkMatrix& positionMatrix,
90                                 SkStrikeDeviceInfo strikeDeviceInfo,
91                                 StrikeForGPUCacheInterface* strikeCache);
92 
93     TextBlob(SubRunAllocator&& alloc,
94              SubRunContainerOwner subRuns,
95              int totalMemorySize,
96              SkColor initialLuminance);
97 
98     ~TextBlob() override;
99 
100     // Change memory management to handle the data after TextBlob, but in the same allocation
101     // of memory. Only allow placement new.
102     void operator delete(void* p);
103     void* operator new(size_t);
104     void* operator new(size_t, void* p);
105 
key()106     const Key& key() { return fKey; }
107 
108     void addKey(const Key& key);
109 
110     bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const;
111 
112     const Key& key() const;
size()113     size_t size() const { return SkTo<size_t>(fSize); }
114 
115     void draw(SkCanvas*,
116               SkPoint drawOrigin,
117               const SkPaint& paint,
118               const AtlasDrawDelegate&);
119 
120 private:
121     friend class TextBlobTools;
122     // The allocator must come first because it needs to be destroyed last. Other fields of this
123     // structure may have pointers into it.
124     SubRunAllocator fAlloc;
125 
126     SubRunContainerOwner fSubRuns;
127 
128     // Overall size of this struct plus vertices and glyphs at the end.
129     const int fSize;
130 
131     const SkColor fInitialLuminance;
132 
133     Key fKey;
134 };
135 
136 sk_sp<sktext::gpu::Slug> MakeSlug(const SkMatrix& drawMatrix,
137                                   const sktext::GlyphRunList& glyphRunList,
138                                   const SkPaint& paint,
139                                   SkStrikeDeviceInfo strikeDeviceInfo,
140                                   sktext::StrikeForGPUCacheInterface* strikeCache);
141 }  // namespace sktext::gpu
142 #endif  // sktext_gpu_TextBlob_DEFINED
143