| /* |
| * Copyright 2022 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef sktext_gpu_GlyphVector_DEFINED |
| #define sktext_gpu_GlyphVector_DEFINED |
| |
| #include "include/core/SkRefCnt.h" |
| #include "include/core/SkSpan.h" |
| #include "src/core/SkGlyph.h" |
| #include "src/gpu/AtlasTypes.h" |
| #include "src/text/StrikeForGPU.h" |
| #include "src/text/gpu/StrikeCache.h" |
| |
| #include <cstddef> |
| #include <cstdint> |
| #include <optional> |
| #include <tuple> |
| |
| class SkReadBuffer; |
| class SkStrikeClient; |
| class SkWriteBuffer; |
| |
| class GrMeshDrawTarget; |
| namespace skgpu::ganesh { class AtlasTextOp; } |
| namespace skgpu::graphite { |
| class Device; |
| class Recorder; |
| } |
| |
| namespace sktext::gpu { |
| class Glyph; |
| class SubRunAllocator; |
| |
| // -- GlyphVector ---------------------------------------------------------------------------------- |
| // GlyphVector provides a way to delay the lookup of Glyphs until the code is running on the GPU |
| // in single threaded mode. The GlyphVector is created in a multi-threaded environment, but the |
| // StrikeCache is only single threaded (and must be single threaded because of the atlas). |
| class GlyphVector { |
| public: |
| union Variant { |
| // Initially, filled with packed id, but changed to Glyph* in the onPrepare stage. |
| SkPackedGlyphID packedGlyphID; |
| Glyph* glyph; |
| // Add ctors to help SkArenaAlloc create arrays. |
| Variant() : glyph{nullptr} {} |
| Variant(SkPackedGlyphID id) : packedGlyphID{id} {} |
| }; |
| |
| GlyphVector(SkStrikePromise&& strikePromise, SkSpan<Variant> glyphs); |
| |
| static GlyphVector Make(SkStrikePromise&& promise, |
| SkSpan<const SkPackedGlyphID> glyphs, |
| SubRunAllocator* alloc); |
| |
| SkSpan<const Glyph*> glyphs() const; |
| |
| static std::optional<GlyphVector> MakeFromBuffer(SkReadBuffer& buffer, |
| const SkStrikeClient* strikeClient, |
| SubRunAllocator* alloc); |
| void flatten(SkWriteBuffer& buffer) const; |
| |
| // This doesn't need to include sizeof(GlyphVector) because this is embedded in each of |
| // the sub runs. |
| int unflattenSize() const { return GlyphVectorSize(fGlyphs.size()); } |
| |
| void packedGlyphIDToGlyph(StrikeCache* cache); |
| |
| static size_t GlyphVectorSize(size_t count) { |
| return sizeof(Variant) * count; |
| } |
| |
| private: |
| friend class GlyphVectorTestingPeer; |
| friend class ::skgpu::graphite::Device; |
| friend class ::skgpu::ganesh::AtlasTextOp; |
| |
| // This function is implemented in ganesh/text/GrAtlasManager.cpp, and should only be called |
| // from AtlasTextOp or linking issues may occur. |
| std::tuple<bool, int> regenerateAtlasForGanesh( |
| int begin, int end, |
| skgpu::MaskFormat maskFormat, |
| int srcPadding, |
| GrMeshDrawTarget*); |
| |
| // This function is implemented in graphite/text/AtlasManager.cpp, and should only be called |
| // from graphite::Device or linking issues may occur. |
| std::tuple<bool, int> regenerateAtlasForGraphite( |
| int begin, int end, |
| skgpu::MaskFormat maskFormat, |
| int srcPadding, |
| skgpu::graphite::Recorder*); |
| |
| SkStrikePromise fStrikePromise; |
| SkSpan<Variant> fGlyphs; |
| sk_sp<TextStrike> fTextStrike{nullptr}; |
| uint64_t fAtlasGeneration{skgpu::AtlasGenerationCounter::kInvalidGeneration}; |
| skgpu::BulkUsePlotUpdater fBulkUseUpdater; |
| }; |
| } // namespace sktext::gpu |
| #endif // sktext_gpu_GlyphVector_DEFINED |