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