1 /* 2 * Copyright 2021 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 SkChromeRemoteGlyphCache_DEFINED 9 #define SkChromeRemoteGlyphCache_DEFINED 10 11 #include <memory> 12 #include <vector> 13 14 #include "include/core/SkData.h" 15 #include "include/core/SkRefCnt.h" 16 #include "include/utils/SkNoDrawCanvas.h" 17 18 class GrSlug; 19 struct SkPackedGlyphID; 20 class SkAutoDescriptor; 21 class SkStrikeCache; 22 class SkStrikeClientImpl; 23 class SkStrikeServer; 24 class SkStrikeServerImpl; 25 class SkTypeface; 26 27 using SkDiscardableHandleId = uint32_t; 28 // This class is not thread-safe. 29 class SkStrikeServer { 30 public: 31 // An interface used by the server to create handles for pinning SkStrike 32 // entries on the remote client. 33 class DiscardableHandleManager { 34 public: 35 SK_SPI virtual ~DiscardableHandleManager() = default; 36 37 // Creates a new *locked* handle and returns a unique ID that can be used to identify 38 // it on the remote client. 39 SK_SPI virtual SkDiscardableHandleId createHandle() = 0; 40 41 // Returns true if the handle could be successfully locked. The server can 42 // assume it will remain locked until the next set of serialized entries is 43 // pulled from the SkStrikeServer. 44 // If returns false, the cache entry mapped to the handle has been deleted 45 // on the client. Any subsequent attempts to lock the same handle are not 46 // allowed. 47 SK_SPI virtual bool lockHandle(SkDiscardableHandleId) = 0; 48 49 // Returns true if a handle has been deleted on the remote client. It is 50 // invalid to use a handle id again with this manager once this returns true. 51 SK_SPI virtual bool isHandleDeleted(SkDiscardableHandleId) = 0; 52 }; 53 54 SK_SPI explicit SkStrikeServer(DiscardableHandleManager* discardableHandleManager); 55 SK_SPI ~SkStrikeServer(); 56 57 // Create an analysis SkCanvas used to populate the SkStrikeServer with ops 58 // which will be serialized and rendered using the SkStrikeClient. 59 SK_API std::unique_ptr<SkCanvas> makeAnalysisCanvas(int width, int height, 60 const SkSurfaceProps& props, 61 sk_sp<SkColorSpace> colorSpace, 62 bool DFTSupport); 63 64 // Serializes the typeface to be transmitted using this server. 65 SK_SPI sk_sp<SkData> serializeTypeface(SkTypeface*); 66 67 // Serializes the strike data captured using a canvas returned by ::makeAnalysisCanvas. Any 68 // handles locked using the DiscardableHandleManager will be assumed to be 69 // unlocked after this call. 70 SK_SPI void writeStrikeData(std::vector<uint8_t>* memory); 71 72 // Testing helpers 73 void setMaxEntriesInDescriptorMapForTesting(size_t count); 74 size_t remoteStrikeMapSizeForTesting() const; 75 76 private: 77 SkStrikeServerImpl* impl(); 78 79 std::unique_ptr<SkStrikeServerImpl> fImpl; 80 }; 81 82 class SkStrikeClient { 83 public: 84 // This enum is used in histogram reporting in chromium. Please don't re-order the list of 85 // entries, and consider it to be append-only. 86 enum CacheMissType : uint32_t { 87 // Hard failures where no fallback could be found. 88 kFontMetrics = 0, 89 kGlyphMetrics = 1, 90 kGlyphImage = 2, 91 kGlyphPath = 3, 92 93 // (DEPRECATED) The original glyph could not be found and a fallback was used. 94 kGlyphMetricsFallback = 4, 95 kGlyphPathFallback = 5, 96 97 kGlyphDrawable = 6, 98 kLast = kGlyphDrawable 99 }; 100 101 // An interface to delete handles that may be pinned by the remote server. 102 class DiscardableHandleManager : public SkRefCnt { 103 public: 104 ~DiscardableHandleManager() override = default; 105 106 // Returns true if the handle was unlocked and can be safely deleted. Once 107 // successful, subsequent attempts to delete the same handle are invalid. 108 virtual bool deleteHandle(SkDiscardableHandleId) = 0; 109 110 virtual void notifyCacheMiss(CacheMissType type, int fontSize) = 0; 111 112 struct ReadFailureData { 113 size_t memorySize; 114 size_t bytesRead; 115 uint64_t typefaceSize; 116 uint64_t strikeCount; 117 uint64_t glyphImagesCount; 118 uint64_t glyphPathsCount; 119 }; notifyReadFailure(const ReadFailureData & data)120 virtual void notifyReadFailure(const ReadFailureData& data) {} 121 }; 122 123 SK_SPI explicit SkStrikeClient(sk_sp<DiscardableHandleManager>, 124 bool isLogging = true, 125 SkStrikeCache* strikeCache = nullptr); 126 SK_SPI ~SkStrikeClient(); 127 128 // Deserializes the typeface previously serialized using the SkStrikeServer. Returns null if the 129 // data is invalid. 130 SK_SPI sk_sp<SkTypeface> deserializeTypeface(const void* data, size_t length); 131 132 // Deserializes the strike data from a SkStrikeServer. All messages generated 133 // from a server when serializing the ops must be deserialized before the op 134 // is rasterized. 135 // Returns false if the data is invalid. 136 SK_SPI bool readStrikeData(const volatile void* memory, size_t memorySize); 137 138 // Given a descriptor re-write the Rec mapping the typefaceID from the renderer to the 139 // corresponding typefaceID on the GPU. 140 SK_SPI bool translateTypefaceID(SkAutoDescriptor* descriptor) const; 141 142 // Given a buffer, unflatten into a slug making sure to do the typefaceID translation from 143 // renderer to GPU. Returns nullptr if there was a problem. 144 sk_sp<GrSlug> makeSlugFromBuffer(SkReadBuffer& buffer) const; 145 146 private: 147 std::unique_ptr<SkStrikeClientImpl> fImpl; 148 }; 149 #endif // SkChromeRemoteGlyphCache_DEFINED 150