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