• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 struct SkPackedGlyphID;
19 class SkAutoDescriptor;
20 class SkStrikeCache;
21 class SkStrikeClientImpl;
22 class SkStrikeServer;
23 class SkStrikeServerImpl;
24 class SkTypeface;
25 namespace sktext::gpu { class Slug; }
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                                                         bool DFTPerspSupport = true);
64 
65     // Serializes the typeface to be transmitted using this server.
66     SK_SPI sk_sp<SkData> serializeTypeface(SkTypeface*);
67 
68     // Serializes the strike data captured using a canvas returned by ::makeAnalysisCanvas. Any
69     // handles locked using the DiscardableHandleManager will be assumed to be
70     // unlocked after this call.
71     SK_SPI void writeStrikeData(std::vector<uint8_t>* memory);
72 
73     // Testing helpers
74     void setMaxEntriesInDescriptorMapForTesting(size_t count);
75     size_t remoteStrikeMapSizeForTesting() const;
76 
77 private:
78     SkStrikeServerImpl* impl();
79 
80     std::unique_ptr<SkStrikeServerImpl> fImpl;
81 };
82 
83 class SkStrikeClient {
84 public:
85     // This enum is used in histogram reporting in chromium. Please don't re-order the list of
86     // entries, and consider it to be append-only.
87     enum CacheMissType : uint32_t {
88         // Hard failures where no fallback could be found.
89         kFontMetrics = 0,
90         kGlyphMetrics = 1,
91         kGlyphImage = 2,
92         kGlyphPath = 3,
93 
94         // (DEPRECATED) The original glyph could not be found and a fallback was used.
95         kGlyphMetricsFallback = 4,
96         kGlyphPathFallback    = 5,
97 
98         kGlyphDrawable = 6,
99         kLast = kGlyphDrawable
100     };
101 
102     // An interface to delete handles that may be pinned by the remote server.
103     class DiscardableHandleManager : public SkRefCnt {
104     public:
105         ~DiscardableHandleManager() override = default;
106 
107         // Returns true if the handle was unlocked and can be safely deleted. Once
108         // successful, subsequent attempts to delete the same handle are invalid.
109         virtual bool deleteHandle(SkDiscardableHandleId) = 0;
110 
assertHandleValid(SkDiscardableHandleId)111         virtual void assertHandleValid(SkDiscardableHandleId) {}
112 
113         virtual void notifyCacheMiss(CacheMissType type, int fontSize) = 0;
114 
115         struct ReadFailureData {
116             size_t memorySize;
117             size_t bytesRead;
118             uint64_t typefaceSize;
119             uint64_t strikeCount;
120             uint64_t glyphImagesCount;
121             uint64_t glyphPathsCount;
122         };
notifyReadFailure(const ReadFailureData & data)123         virtual void notifyReadFailure(const ReadFailureData& data) {}
124     };
125 
126     SK_SPI explicit SkStrikeClient(sk_sp<DiscardableHandleManager>,
127                                    bool isLogging = true,
128                                    SkStrikeCache* strikeCache = nullptr);
129     SK_SPI ~SkStrikeClient();
130 
131     // Deserializes the typeface previously serialized using the SkStrikeServer. Returns null if the
132     // data is invalid.
133     SK_SPI sk_sp<SkTypeface> deserializeTypeface(const void* data, size_t length);
134 
135     // Deserializes the strike data from a SkStrikeServer. All messages generated
136     // from a server when serializing the ops must be deserialized before the op
137     // is rasterized.
138     // Returns false if the data is invalid.
139     SK_SPI bool readStrikeData(const volatile void* memory, size_t memorySize);
140 
141     // Given a descriptor re-write the Rec mapping the typefaceID from the renderer to the
142     // corresponding typefaceID on the GPU.
143     SK_SPI bool translateTypefaceID(SkAutoDescriptor* descriptor) const;
144 
145     // Given a buffer, unflatten into a slug making sure to do the typefaceID translation from
146     // renderer to GPU. Returns nullptr if there was a problem.
147     sk_sp<sktext::gpu::Slug> deserializeSlug(const void* data, size_t size) const;
148 
149 private:
150     std::unique_ptr<SkStrikeClientImpl> fImpl;
151 };
152 #endif  // SkChromeRemoteGlyphCache_DEFINED
153