• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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