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