/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef sktext_StrikeForGPU_DEFINED #define sktext_StrikeForGPU_DEFINED #include "include/core/SkPath.h" #include "include/core/SkRefCnt.h" #include "include/core/SkTypes.h" #include "src/core/SkGlyph.h" #include #include #include class SkDescriptor; class SkDrawable; class SkReadBuffer; class SkStrike; class SkStrikeCache; class SkStrikeClient; class SkStrikeSpec; class SkWriteBuffer; namespace sktext { // -- SkStrikePromise ------------------------------------------------------------------------------ // SkStrikePromise produces an SkStrike when needed by GPU glyph rendering. In ordinary // operation, it just wraps an SkStrike. When used for remote glyph cache operation, the promise is // serialized to an SkDescriptor. When SkStrikePromise is deserialized, it uses the descriptor to // look up the SkStrike. // // When deserializing some care must be taken; if the needed SkStrike is removed from the cache, // then looking up using the descriptor will fail resulting in a deserialization failure. The // Renderer/GPU system solves this problem by pinning all the strikes needed into the cache. class SkStrikePromise { public: SkStrikePromise() = delete; SkStrikePromise(const SkStrikePromise&) = delete; SkStrikePromise& operator=(const SkStrikePromise&) = delete; SkStrikePromise(SkStrikePromise&&); SkStrikePromise& operator=(SkStrikePromise&&); explicit SkStrikePromise(sk_sp&& strike); explicit SkStrikePromise(const SkStrikeSpec& spec); // This only works when the GPU code is compiled in. static std::optional MakeFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* client, SkStrikeCache* strikeCache); void flatten(SkWriteBuffer& buffer) const; // Do what is needed to return a strike. SkStrike* strike(); // Reset the sk_sp to nullptr. void resetStrike(); // Return a descriptor used to look up the SkStrike. const SkDescriptor& descriptor() const; private: std::variant, std::unique_ptr> fStrikeOrSpec; }; // -- StrikeForGPU --------------------------------------------------------------------------------- class StrikeForGPU : public SkRefCnt { public: virtual void lock() = 0; virtual void unlock() = 0; // Generate a digest for a given packed glyph ID as drawn using the give action type. virtual SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID) = 0; // Prepare the glyph to draw an image, and return if the image exists. virtual bool prepareForImage(SkGlyph*) = 0; // Prepare the glyph to draw a path, and return if the path exists. virtual bool prepareForPath(SkGlyph*) = 0; // Prepare the glyph to draw a drawable, and return if the drawable exists. virtual bool prepareForDrawable(SkGlyph*) = 0; virtual const SkDescriptor& getDescriptor() const = 0; virtual const SkGlyphPositionRoundingSpec& roundingSpec() const = 0; // Return a strike promise. virtual SkStrikePromise strikePromise() = 0; }; // prepareForPathDrawing uses this union to convert glyph ids to paths. union IDOrPath { IDOrPath() {} IDOrPath(SkGlyphID glyphID) : fGlyphID{glyphID} {} // PathOpSubmitter takes care of destroying the paths. ~IDOrPath() {} SkGlyphID fGlyphID; SkPath fPath; }; // prepareForDrawableDrawing uses this union to convert glyph ids to drawables. union IDOrDrawable { SkGlyphID fGlyphID; SkDrawable* fDrawable; }; // -- StrikeMutationMonitor ------------------------------------------------------------------------ class StrikeMutationMonitor { public: StrikeMutationMonitor(StrikeForGPU* strike); ~StrikeMutationMonitor(); private: StrikeForGPU* fStrike; }; // -- StrikeForGPUCacheInterface ------------------------------------------------------------------- class StrikeForGPUCacheInterface { public: virtual ~StrikeForGPUCacheInterface() = default; virtual sk_sp findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) = 0; }; } // namespace sktext #endif // sktext_StrikeForGPU_DEFINED