1 /* 2 * Copyright 2019 Google Inc. 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_StrikeForGPU_DEFINED 9 #define sktext_StrikeForGPU_DEFINED 10 11 #include "include/core/SkPath.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/core/SkTypes.h" 14 #include "src/core/SkGlyph.h" 15 16 #include <memory> 17 #include <optional> 18 #include <variant> 19 20 class SkDescriptor; 21 class SkDrawable; 22 class SkReadBuffer; 23 class SkStrike; 24 class SkStrikeCache; 25 class SkStrikeClient; 26 class SkStrikeSpec; 27 class SkWriteBuffer; 28 29 namespace sktext { 30 // -- SkStrikePromise ------------------------------------------------------------------------------ 31 // SkStrikePromise produces an SkStrike when needed by GPU glyph rendering. In ordinary 32 // operation, it just wraps an SkStrike. When used for remote glyph cache operation, the promise is 33 // serialized to an SkDescriptor. When SkStrikePromise is deserialized, it uses the descriptor to 34 // look up the SkStrike. 35 // 36 // When deserializing some care must be taken; if the needed SkStrike is removed from the cache, 37 // then looking up using the descriptor will fail resulting in a deserialization failure. The 38 // Renderer/GPU system solves this problem by pinning all the strikes needed into the cache. 39 class SkStrikePromise { 40 public: 41 SkStrikePromise() = delete; 42 SkStrikePromise(const SkStrikePromise&) = delete; 43 SkStrikePromise& operator=(const SkStrikePromise&) = delete; 44 SkStrikePromise(SkStrikePromise&&); 45 SkStrikePromise& operator=(SkStrikePromise&&); 46 47 explicit SkStrikePromise(sk_sp<SkStrike>&& strike); 48 explicit SkStrikePromise(const SkStrikeSpec& spec); 49 50 // This only works when the GPU code is compiled in. 51 static std::optional<SkStrikePromise> MakeFromBuffer(SkReadBuffer& buffer, 52 const SkStrikeClient* client, 53 SkStrikeCache* strikeCache); 54 void flatten(SkWriteBuffer& buffer) const; 55 56 // Do what is needed to return a strike. 57 SkStrike* strike(); 58 59 // Reset the sk_sp<SkStrike> to nullptr. 60 void resetStrike(); 61 62 // Return a descriptor used to look up the SkStrike. 63 const SkDescriptor& descriptor() const; 64 65 private: 66 std::variant<sk_sp<SkStrike>, std::unique_ptr<SkStrikeSpec>> fStrikeOrSpec; 67 }; 68 69 // -- StrikeForGPU --------------------------------------------------------------------------------- 70 class StrikeForGPU : public SkRefCnt { 71 public: 72 virtual void lock() = 0; 73 virtual void unlock() = 0; 74 75 // Generate a digest for a given packed glyph ID as drawn using the give action type. 76 virtual SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID) = 0; 77 78 // Prepare the glyph to draw an image, and return if the image exists. 79 virtual bool prepareForImage(SkGlyph*) = 0; 80 81 // Prepare the glyph to draw a path, and return if the path exists. 82 virtual bool prepareForPath(SkGlyph*) = 0; 83 84 // Prepare the glyph to draw a drawable, and return if the drawable exists. 85 virtual bool prepareForDrawable(SkGlyph*) = 0; 86 87 88 virtual const SkDescriptor& getDescriptor() const = 0; 89 90 virtual const SkGlyphPositionRoundingSpec& roundingSpec() const = 0; 91 92 // Return a strike promise. 93 virtual SkStrikePromise strikePromise() = 0; 94 }; 95 96 // prepareForPathDrawing uses this union to convert glyph ids to paths. 97 union IDOrPath { IDOrPath()98 IDOrPath() {} IDOrPath(SkGlyphID glyphID)99 IDOrPath(SkGlyphID glyphID) : fGlyphID{glyphID} {} 100 101 // PathOpSubmitter takes care of destroying the paths. ~IDOrPath()102 ~IDOrPath() {} 103 SkGlyphID fGlyphID; 104 SkPath fPath; 105 }; 106 107 // prepareForDrawableDrawing uses this union to convert glyph ids to drawables. 108 union IDOrDrawable { 109 SkGlyphID fGlyphID; 110 SkDrawable* fDrawable; 111 }; 112 113 // -- StrikeMutationMonitor ------------------------------------------------------------------------ 114 class StrikeMutationMonitor { 115 public: 116 StrikeMutationMonitor(StrikeForGPU* strike); 117 ~StrikeMutationMonitor(); 118 119 private: 120 StrikeForGPU* fStrike; 121 }; 122 123 // -- StrikeForGPUCacheInterface ------------------------------------------------------------------- 124 class StrikeForGPUCacheInterface { 125 public: 126 virtual ~StrikeForGPUCacheInterface() = default; 127 virtual sk_sp<StrikeForGPU> findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) = 0; 128 }; 129 } // namespace sktext 130 #endif // sktext_StrikeForGPU_DEFINED 131