| /* |
| * Copyright 2021 Google LLC. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkChromeRemoteGlyphCache_DEFINED |
| #define SkChromeRemoteGlyphCache_DEFINED |
| |
| #include "include/core/SkRefCnt.h" |
| #include "include/core/SkTypeface.h" |
| #include "include/private/base/SkAPI.h" |
| |
| #include <cstddef> |
| #include <cstdint> |
| #include <memory> |
| #include <vector> |
| |
| class SkAutoDescriptor; |
| class SkCanvas; |
| class SkColorSpace; |
| class SkStrikeCache; |
| class SkStrikeClientImpl; |
| class SkStrikeServerImpl; |
| class SkSurfaceProps; |
| namespace sktext::gpu { class Slug; } |
| |
| using SkDiscardableHandleId = uint32_t; |
| // This class is not thread-safe. |
| class SkStrikeServer { |
| public: |
| // An interface used by the server to create handles for pinning SkStrike |
| // entries on the remote client. |
| class DiscardableHandleManager { |
| public: |
| SK_SPI virtual ~DiscardableHandleManager() = default; |
| |
| // Creates a new *locked* handle and returns a unique ID that can be used to identify |
| // it on the remote client. |
| SK_SPI virtual SkDiscardableHandleId createHandle() = 0; |
| |
| // Returns true if the handle could be successfully locked. The server can |
| // assume it will remain locked until the next set of serialized entries is |
| // pulled from the SkStrikeServer. |
| // If returns false, the cache entry mapped to the handle has been deleted |
| // on the client. Any subsequent attempts to lock the same handle are not |
| // allowed. |
| SK_SPI virtual bool lockHandle(SkDiscardableHandleId) = 0; |
| |
| // Returns true if a handle has been deleted on the remote client. It is |
| // invalid to use a handle id again with this manager once this returns true. |
| SK_SPI virtual bool isHandleDeleted(SkDiscardableHandleId) = 0; |
| }; |
| |
| SK_SPI explicit SkStrikeServer(DiscardableHandleManager* discardableHandleManager); |
| SK_SPI ~SkStrikeServer(); |
| |
| // Create an analysis SkCanvas used to populate the SkStrikeServer with ops |
| // which will be serialized and rendered using the SkStrikeClient. |
| SK_API std::unique_ptr<SkCanvas> makeAnalysisCanvas(int width, int height, |
| const SkSurfaceProps& props, |
| sk_sp<SkColorSpace> colorSpace, |
| bool DFTSupport, |
| bool DFTPerspSupport = true); |
| |
| // Serializes the strike data captured using a canvas returned by ::makeAnalysisCanvas. Any |
| // handles locked using the DiscardableHandleManager will be assumed to be |
| // unlocked after this call. |
| SK_SPI void writeStrikeData(std::vector<uint8_t>* memory); |
| |
| // Testing helpers |
| void setMaxEntriesInDescriptorMapForTesting(size_t count); |
| size_t remoteStrikeMapSizeForTesting() const; |
| |
| private: |
| SkStrikeServerImpl* impl(); |
| |
| std::unique_ptr<SkStrikeServerImpl> fImpl; |
| }; |
| |
| class SkStrikeClient { |
| public: |
| // This enum is used in histogram reporting in chromium. Please don't re-order the list of |
| // entries, and consider it to be append-only. |
| enum CacheMissType : uint32_t { |
| // Hard failures where no fallback could be found. |
| kFontMetrics = 0, |
| kGlyphMetrics = 1, |
| kGlyphImage = 2, |
| kGlyphPath = 3, |
| |
| // (DEPRECATED) The original glyph could not be found and a fallback was used. |
| kGlyphMetricsFallback = 4, |
| kGlyphPathFallback = 5, |
| |
| kGlyphDrawable = 6, |
| kLast = kGlyphDrawable |
| }; |
| |
| // An interface to delete handles that may be pinned by the remote server. |
| class DiscardableHandleManager : public SkRefCnt { |
| public: |
| ~DiscardableHandleManager() override = default; |
| |
| // Returns true if the handle was unlocked and can be safely deleted. Once |
| // successful, subsequent attempts to delete the same handle are invalid. |
| virtual bool deleteHandle(SkDiscardableHandleId) = 0; |
| |
| virtual void assertHandleValid(SkDiscardableHandleId) {} |
| |
| virtual void notifyCacheMiss(CacheMissType type, int fontSize) = 0; |
| |
| struct ReadFailureData { |
| size_t memorySize; |
| size_t bytesRead; |
| uint64_t typefaceSize; |
| uint64_t strikeCount; |
| uint64_t glyphImagesCount; |
| uint64_t glyphPathsCount; |
| }; |
| virtual void notifyReadFailure(const ReadFailureData& data) {} |
| }; |
| |
| SK_SPI explicit SkStrikeClient(sk_sp<DiscardableHandleManager>, |
| bool isLogging = true, |
| SkStrikeCache* strikeCache = nullptr); |
| SK_SPI ~SkStrikeClient(); |
| |
| // Deserializes the strike data from a SkStrikeServer. All messages generated |
| // from a server when serializing the ops must be deserialized before the op |
| // is rasterized. |
| // Returns false if the data is invalid. |
| SK_SPI bool readStrikeData(const volatile void* memory, size_t memorySize); |
| |
| // Given a descriptor re-write the Rec mapping the typefaceID from the renderer to the |
| // corresponding typefaceID on the GPU. |
| SK_SPI bool translateTypefaceID(SkAutoDescriptor* descriptor) const; |
| |
| // Testing helpers |
| sk_sp<SkTypeface> retrieveTypefaceUsingServerIDForTest(SkTypefaceID) const; |
| |
| // Given a buffer, unflatten into a slug making sure to do the typefaceID translation from |
| // renderer to GPU. Returns nullptr if there was a problem. |
| sk_sp<sktext::gpu::Slug> deserializeSlugForTest(const void* data, size_t size) const; |
| |
| private: |
| std::unique_ptr<SkStrikeClientImpl> fImpl; |
| }; |
| #endif // SkChromeRemoteGlyphCache_DEFINED |