xref: /aosp_15_r20/external/skia/src/text/gpu/GlyphVector.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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_GlyphVector_DEFINED
9 #define sktext_gpu_GlyphVector_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkSpan.h"
13 #include "src/core/SkGlyph.h"
14 #include "src/gpu/AtlasTypes.h"
15 #include "src/text/StrikeForGPU.h"
16 #include "src/text/gpu/StrikeCache.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <optional>
21 #include <tuple>
22 
23 class SkReadBuffer;
24 class SkStrikeClient;
25 class SkWriteBuffer;
26 
27 class GrMeshDrawTarget;
28 namespace skgpu::ganesh { class AtlasTextOp; }
29 namespace skgpu::graphite {
30 class Device;
31 class Recorder;
32 }
33 
34 namespace sktext::gpu {
35 class Glyph;
36 class SubRunAllocator;
37 
38 // -- GlyphVector ----------------------------------------------------------------------------------
39 // GlyphVector provides a way to delay the lookup of Glyphs until the code is running on the GPU
40 // in single threaded mode. The GlyphVector is created in a multi-threaded environment, but the
41 // StrikeCache is only single threaded (and must be single threaded because of the atlas).
42 class GlyphVector {
43 public:
44     union Variant {
45         // Initially, filled with packed id, but changed to Glyph* in the onPrepare stage.
46         SkPackedGlyphID packedGlyphID;
47         Glyph* glyph;
48         // Add ctors to help SkArenaAlloc create arrays.
Variant()49         Variant() : glyph{nullptr} {}
Variant(SkPackedGlyphID id)50         Variant(SkPackedGlyphID id) : packedGlyphID{id} {}
51     };
52 
53     GlyphVector(SkStrikePromise&& strikePromise, SkSpan<Variant> glyphs);
54 
55     static GlyphVector Make(SkStrikePromise&& promise,
56                             SkSpan<const SkPackedGlyphID> glyphs,
57                             SubRunAllocator* alloc);
58 
59     SkSpan<const Glyph*> glyphs() const;
60 
61     static std::optional<GlyphVector> MakeFromBuffer(SkReadBuffer& buffer,
62                                                      const SkStrikeClient* strikeClient,
63                                                      SubRunAllocator* alloc);
64     void flatten(SkWriteBuffer& buffer) const;
65 
66     // This doesn't need to include sizeof(GlyphVector) because this is embedded in each of
67     // the sub runs.
unflattenSize()68     int unflattenSize() const { return GlyphVectorSize(fGlyphs.size()); }
69 
70     void packedGlyphIDToGlyph(StrikeCache* cache);
71 
GlyphVectorSize(size_t count)72     static size_t GlyphVectorSize(size_t count) {
73         return sizeof(Variant) * count;
74     }
75 
76 private:
77     friend class GlyphVectorTestingPeer;
78     friend class ::skgpu::graphite::Device;
79     friend class ::skgpu::ganesh::AtlasTextOp;
80 
81     // This function is implemented in ganesh/text/GrAtlasManager.cpp, and should only be called
82     // from AtlasTextOp or linking issues may occur.
83     std::tuple<bool, int> regenerateAtlasForGanesh(
84             int begin, int end,
85             skgpu::MaskFormat maskFormat,
86             int srcPadding,
87             GrMeshDrawTarget*);
88 
89     // This function is implemented in graphite/text/AtlasManager.cpp, and should only be called
90     // from graphite::Device or linking issues may occur.
91     std::tuple<bool, int> regenerateAtlasForGraphite(
92             int begin, int end,
93             skgpu::MaskFormat maskFormat,
94             int srcPadding,
95             skgpu::graphite::Recorder*);
96 
97     SkStrikePromise fStrikePromise;
98     SkSpan<Variant> fGlyphs;
99     sk_sp<TextStrike> fTextStrike{nullptr};
100     uint64_t fAtlasGeneration{skgpu::AtlasGenerationCounter::kInvalidGeneration};
101     skgpu::BulkUsePlotUpdater fBulkUseUpdater;
102 };
103 }  // namespace sktext::gpu
104 #endif  // sktext_gpu_GlyphVector_DEFINED
105