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 "include/core/SkRefCnt.h" 12 #include "include/core/SkTypeface.h" 13 #include "include/private/base/SkAPI.h" 14 15 #include <cstddef> 16 #include <cstdint> 17 #include <memory> 18 #include <vector> 19 20 class SkAutoDescriptor; 21 class SkCanvas; 22 class SkColorSpace; 23 class SkStrikeCache; 24 class SkStrikeClientImpl; 25 class SkStrikeServerImpl; 26 class SkSurfaceProps; 27 namespace sktext::gpu { class Slug; } 28 29 using SkDiscardableHandleId = uint32_t; 30 // This class is not thread-safe. 31 class SkStrikeServer { 32 public: 33 // An interface used by the server to create handles for pinning SkStrike 34 // entries on the remote client. 35 class DiscardableHandleManager { 36 public: 37 SK_SPI virtual ~DiscardableHandleManager() = default; 38 39 // Creates a new *locked* handle and returns a unique ID that can be used to identify 40 // it on the remote client. 41 SK_SPI virtual SkDiscardableHandleId createHandle() = 0; 42 43 // Returns true if the handle could be successfully locked. The server can 44 // assume it will remain locked until the next set of serialized entries is 45 // pulled from the SkStrikeServer. 46 // If returns false, the cache entry mapped to the handle has been deleted 47 // on the client. Any subsequent attempts to lock the same handle are not 48 // allowed. 49 SK_SPI virtual bool lockHandle(SkDiscardableHandleId) = 0; 50 51 // Returns true if a handle has been deleted on the remote client. It is 52 // invalid to use a handle id again with this manager once this returns true. 53 SK_SPI virtual bool isHandleDeleted(SkDiscardableHandleId) = 0; 54 }; 55 56 SK_SPI explicit SkStrikeServer(DiscardableHandleManager* discardableHandleManager); 57 SK_SPI ~SkStrikeServer(); 58 59 // Create an analysis SkCanvas used to populate the SkStrikeServer with ops 60 // which will be serialized and rendered using the SkStrikeClient. 61 SK_API std::unique_ptr<SkCanvas> makeAnalysisCanvas(int width, int height, 62 const SkSurfaceProps& props, 63 sk_sp<SkColorSpace> colorSpace, 64 bool DFTSupport, 65 bool DFTPerspSupport = true); 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 assertHandleValid(SkDiscardableHandleId)110 virtual void assertHandleValid(SkDiscardableHandleId) {} 111 112 virtual void notifyCacheMiss(CacheMissType type, int fontSize) = 0; 113 114 struct ReadFailureData { 115 size_t memorySize; 116 size_t bytesRead; 117 uint64_t typefaceSize; 118 uint64_t strikeCount; 119 uint64_t glyphImagesCount; 120 uint64_t glyphPathsCount; 121 }; notifyReadFailure(const ReadFailureData & data)122 virtual void notifyReadFailure(const ReadFailureData& data) {} 123 }; 124 125 SK_SPI explicit SkStrikeClient(sk_sp<DiscardableHandleManager>, 126 bool isLogging = true, 127 SkStrikeCache* strikeCache = nullptr); 128 SK_SPI ~SkStrikeClient(); 129 130 // Deserializes the strike data from a SkStrikeServer. All messages generated 131 // from a server when serializing the ops must be deserialized before the op 132 // is rasterized. 133 // Returns false if the data is invalid. 134 SK_SPI bool readStrikeData(const volatile void* memory, size_t memorySize); 135 136 // Given a descriptor re-write the Rec mapping the typefaceID from the renderer to the 137 // corresponding typefaceID on the GPU. 138 SK_SPI bool translateTypefaceID(SkAutoDescriptor* descriptor) const; 139 140 // Testing helpers 141 sk_sp<SkTypeface> retrieveTypefaceUsingServerIDForTest(SkTypefaceID) const; 142 143 // Given a buffer, unflatten into a slug making sure to do the typefaceID translation from 144 // renderer to GPU. Returns nullptr if there was a problem. 145 sk_sp<sktext::gpu::Slug> deserializeSlugForTest(const void* data, size_t size) const; 146 147 private: 148 std::unique_ptr<SkStrikeClientImpl> fImpl; 149 }; 150 #endif // SkChromeRemoteGlyphCache_DEFINED 151