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