SkRemoteGlyphCache.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. #ifndef SkRemoteGlyphCache_DEFINED
  8. #define SkRemoteGlyphCache_DEFINED
  9. #include <memory>
  10. #include <tuple>
  11. #include <unordered_map>
  12. #include <unordered_set>
  13. #include <vector>
  14. #include "include/core/SkData.h"
  15. #include "include/core/SkDrawLooper.h"
  16. #include "include/core/SkRefCnt.h"
  17. #include "include/core/SkSerialProcs.h"
  18. #include "include/core/SkTypeface.h"
  19. #include "include/private/SkTHash.h"
  20. #include "include/utils/SkNoDrawCanvas.h"
  21. #include "src/core/SkDevice.h"
  22. #include "src/core/SkMakeUnique.h"
  23. #include "src/core/SkStrikeInterface.h"
  24. #include "src/core/SkTLazy.h"
  25. class Deserializer;
  26. class Serializer;
  27. enum SkAxisAlignment : uint32_t;
  28. class SkDescriptor;
  29. class SkStrike;
  30. struct SkPackedGlyphID;
  31. enum SkScalerContextFlags : uint32_t;
  32. class SkStrikeCache;
  33. class SkTypefaceProxy;
  34. struct WireTypeface;
  35. class SkStrikeServer;
  36. struct SkDescriptorMapOperators {
  37. size_t operator()(const SkDescriptor* key) const;
  38. bool operator()(const SkDescriptor* lhs, const SkDescriptor* rhs) const;
  39. };
  40. template <typename T>
  41. using SkDescriptorMap = std::unordered_map<const SkDescriptor*, T, SkDescriptorMapOperators,
  42. SkDescriptorMapOperators>;
  43. using SkDescriptorSet =
  44. std::unordered_set<const SkDescriptor*, SkDescriptorMapOperators, SkDescriptorMapOperators>;
  45. // A SkTextBlobCacheDiffCanvas is used to populate the SkStrikeServer with ops
  46. // which will be serialized and renderered using the SkStrikeClient.
  47. class SK_API SkTextBlobCacheDiffCanvas : public SkNoDrawCanvas {
  48. public:
  49. struct SK_API Settings {
  50. Settings();
  51. bool fContextSupportsDistanceFieldText = true;
  52. SkScalar fMinDistanceFieldFontSize = -1.f;
  53. SkScalar fMaxDistanceFieldFontSize = -1.f;
  54. int fMaxTextureSize = 0;
  55. size_t fMaxTextureBytes = 0u;
  56. };
  57. SkTextBlobCacheDiffCanvas(int width, int height, const SkSurfaceProps& props,
  58. SkStrikeServer* strikeServer, Settings settings = Settings());
  59. SkTextBlobCacheDiffCanvas(int width, int height, const SkSurfaceProps& props,
  60. SkStrikeServer* strikeServer, sk_sp<SkColorSpace> colorSpace,
  61. Settings settings = Settings());
  62. ~SkTextBlobCacheDiffCanvas() override;
  63. protected:
  64. SkCanvas::SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override;
  65. bool onDoSaveBehind(const SkRect*) override;
  66. void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
  67. const SkPaint& paint) override;
  68. private:
  69. class TrackLayerDevice;
  70. static SkScalar SetupForPath(SkPaint* paint, SkFont* font);
  71. };
  72. using SkDiscardableHandleId = uint32_t;
  73. // This class is not thread-safe.
  74. class SK_API SkStrikeServer final : public SkStrikeCacheInterface {
  75. public:
  76. // An interface used by the server to create handles for pinning SkStrike
  77. // entries on the remote client.
  78. class SK_API DiscardableHandleManager {
  79. public:
  80. virtual ~DiscardableHandleManager() = default;
  81. // Creates a new *locked* handle and returns a unique ID that can be used to identify
  82. // it on the remote client.
  83. virtual SkDiscardableHandleId createHandle() = 0;
  84. // Returns true if the handle could be successfully locked. The server can
  85. // assume it will remain locked until the next set of serialized entries is
  86. // pulled from the SkStrikeServer.
  87. // If returns false, the cache entry mapped to the handle has been deleted
  88. // on the client. Any subsequent attempts to lock the same handle are not
  89. // allowed.
  90. virtual bool lockHandle(SkDiscardableHandleId) = 0;
  91. // Returns true if a handle has been deleted on the remote client. It is
  92. // invalid to use a handle id again with this manager once this returns true.
  93. // TODO(khushalsagar): Make pure virtual once chrome implementation lands.
  94. virtual bool isHandleDeleted(SkDiscardableHandleId) { return false; }
  95. };
  96. explicit SkStrikeServer(DiscardableHandleManager* discardableHandleManager);
  97. ~SkStrikeServer() override;
  98. // Serializes the typeface to be remoted using this server.
  99. sk_sp<SkData> serializeTypeface(SkTypeface*);
  100. // Serializes the strike data captured using a SkTextBlobCacheDiffCanvas. Any
  101. // handles locked using the DiscardableHandleManager will be assumed to be
  102. // unlocked after this call.
  103. void writeStrikeData(std::vector<uint8_t>* memory);
  104. // Methods used internally in skia ------------------------------------------
  105. class SkGlyphCacheState;
  106. SkGlyphCacheState* getOrCreateCache(const SkPaint&,
  107. const SkFont& font,
  108. const SkSurfaceProps&,
  109. const SkMatrix&,
  110. SkScalerContextFlags flags,
  111. SkScalerContextEffects* effects);
  112. SkScopedStrike findOrCreateScopedStrike(const SkDescriptor& desc,
  113. const SkScalerContextEffects& effects,
  114. const SkTypeface& typeface) override;
  115. void setMaxEntriesInDescriptorMapForTesting(size_t count) {
  116. fMaxEntriesInDescriptorMap = count;
  117. }
  118. size_t remoteGlyphStateMapSizeForTesting() const { return fRemoteGlyphStateMap.size(); }
  119. private:
  120. static constexpr size_t kMaxEntriesInDescriptorMap = 2000u;
  121. void checkForDeletedEntries();
  122. SkGlyphCacheState* getOrCreateCache(const SkDescriptor& desc,
  123. const SkTypeface& typeface,
  124. SkScalerContextEffects effects);
  125. SkDescriptorMap<std::unique_ptr<SkGlyphCacheState>> fRemoteGlyphStateMap;
  126. DiscardableHandleManager* const fDiscardableHandleManager;
  127. SkTHashSet<SkFontID> fCachedTypefaces;
  128. size_t fMaxEntriesInDescriptorMap = kMaxEntriesInDescriptorMap;
  129. // Cached serialized typefaces.
  130. SkTHashMap<SkFontID, sk_sp<SkData>> fSerializedTypefaces;
  131. // State cached until the next serialization.
  132. SkDescriptorSet fLockedDescs;
  133. std::vector<WireTypeface> fTypefacesToSend;
  134. };
  135. class SK_API SkStrikeClient {
  136. public:
  137. // This enum is used in histogram reporting in chromium. Please don't re-order the list of
  138. // entries, and consider it to be append-only.
  139. enum CacheMissType : uint32_t {
  140. // Hard failures where no fallback could be found.
  141. kFontMetrics = 0,
  142. kGlyphMetrics = 1,
  143. kGlyphImage = 2,
  144. kGlyphPath = 3,
  145. // The original glyph could not be found and a fallback was used.
  146. kGlyphMetricsFallback = 4,
  147. kGlyphPathFallback = 5,
  148. kLast = kGlyphPathFallback
  149. };
  150. // An interface to delete handles that may be pinned by the remote server.
  151. class DiscardableHandleManager : public SkRefCnt {
  152. public:
  153. virtual ~DiscardableHandleManager() = default;
  154. // Returns true if the handle was unlocked and can be safely deleted. Once
  155. // successful, subsequent attempts to delete the same handle are invalid.
  156. virtual bool deleteHandle(SkDiscardableHandleId) = 0;
  157. virtual void notifyCacheMiss(CacheMissType) {}
  158. struct ReadFailureData {
  159. size_t memorySize;
  160. size_t bytesRead;
  161. uint64_t typefaceSize;
  162. uint64_t strikeCount;
  163. uint64_t glyphImagesCount;
  164. uint64_t glyphPathsCount;
  165. };
  166. virtual void notifyReadFailure(const ReadFailureData& data) {}
  167. };
  168. explicit SkStrikeClient(sk_sp<DiscardableHandleManager>,
  169. bool isLogging = true,
  170. SkStrikeCache* strikeCache = nullptr);
  171. ~SkStrikeClient();
  172. // Deserializes the typeface previously serialized using the SkStrikeServer. Returns null if the
  173. // data is invalid.
  174. sk_sp<SkTypeface> deserializeTypeface(const void* data, size_t length);
  175. static bool ReadGlyph(SkTLazy<SkGlyph>& glyph, Deserializer* deserializer);
  176. // Deserializes the strike data from a SkStrikeServer. All messages generated
  177. // from a server when serializing the ops must be deserialized before the op
  178. // is rasterized.
  179. // Returns false if the data is invalid.
  180. bool readStrikeData(const volatile void* memory, size_t memorySize);
  181. private:
  182. class DiscardableStrikePinner;
  183. sk_sp<SkTypeface> addTypeface(const WireTypeface& wire);
  184. SkTHashMap<SkFontID, sk_sp<SkTypeface>> fRemoteFontIdToTypeface;
  185. sk_sp<DiscardableHandleManager> fDiscardableHandleManager;
  186. SkStrikeCache* const fStrikeCache;
  187. const bool fIsLogging;
  188. };
  189. #endif // SkRemoteGlyphCache_DEFINED