SkRemoteGlyphCache.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  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. #include "src/core/SkRemoteGlyphCache.h"
  8. #include <iterator>
  9. #include <memory>
  10. #include <new>
  11. #include <string>
  12. #include <tuple>
  13. #include "src/core/SkDevice.h"
  14. #include "src/core/SkDraw.h"
  15. #include "src/core/SkGlyphRun.h"
  16. #include "src/core/SkRemoteGlyphCacheImpl.h"
  17. #include "src/core/SkStrike.h"
  18. #include "src/core/SkStrikeCache.h"
  19. #include "src/core/SkTLazy.h"
  20. #include "src/core/SkTraceEvent.h"
  21. #include "src/core/SkTypeface_remote.h"
  22. #if SK_SUPPORT_GPU
  23. #include "src/gpu/GrDrawOpAtlas.h"
  24. #include "src/gpu/text/GrTextContext.h"
  25. #endif
  26. static SkDescriptor* auto_descriptor_from_desc(const SkDescriptor* source_desc,
  27. SkFontID font_id,
  28. SkAutoDescriptor* ad) {
  29. ad->reset(source_desc->getLength());
  30. auto* desc = ad->getDesc();
  31. desc->init();
  32. // Rec.
  33. {
  34. uint32_t size;
  35. auto ptr = source_desc->findEntry(kRec_SkDescriptorTag, &size);
  36. SkScalerContextRec rec;
  37. std::memcpy(&rec, ptr, size);
  38. rec.fFontID = font_id;
  39. desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
  40. }
  41. // Effects.
  42. {
  43. uint32_t size;
  44. auto ptr = source_desc->findEntry(kEffects_SkDescriptorTag, &size);
  45. if (ptr) { desc->addEntry(kEffects_SkDescriptorTag, size, ptr); }
  46. }
  47. desc->computeChecksum();
  48. return desc;
  49. }
  50. static const SkDescriptor* create_descriptor(
  51. const SkPaint& paint, const SkFont& font, const SkMatrix& m,
  52. const SkSurfaceProps& props, SkScalerContextFlags flags,
  53. SkAutoDescriptor* ad, SkScalerContextEffects* effects) {
  54. SkScalerContextRec rec;
  55. SkScalerContext::MakeRecAndEffects(font, paint, props, flags, m, &rec, effects);
  56. return SkScalerContext::AutoDescriptorGivenRecAndEffects(rec, *effects, ad);
  57. }
  58. // -- Serializer ----------------------------------------------------------------------------------
  59. size_t pad(size_t size, size_t alignment) { return (size + (alignment - 1)) & ~(alignment - 1); }
  60. // Alignment between x86 and x64 differs for some types, in particular
  61. // int64_t and doubles have 4 and 8-byte alignment, respectively.
  62. // Be consistent even when writing and reading across different architectures.
  63. template<typename T>
  64. size_t serialization_alignment() {
  65. return sizeof(T) == 8 ? 8 : alignof(T);
  66. }
  67. class Serializer {
  68. public:
  69. Serializer(std::vector<uint8_t>* buffer) : fBuffer{buffer} { }
  70. template <typename T, typename... Args>
  71. T* emplace(Args&&... args) {
  72. auto result = allocate(sizeof(T), serialization_alignment<T>());
  73. return new (result) T{std::forward<Args>(args)...};
  74. }
  75. template <typename T>
  76. void write(const T& data) {
  77. T* result = (T*)allocate(sizeof(T), serialization_alignment<T>());
  78. memcpy(result, &data, sizeof(T));
  79. }
  80. template <typename T>
  81. T* allocate() {
  82. T* result = (T*)allocate(sizeof(T), serialization_alignment<T>());
  83. return result;
  84. }
  85. void writeDescriptor(const SkDescriptor& desc) {
  86. write(desc.getLength());
  87. auto result = allocate(desc.getLength(), alignof(SkDescriptor));
  88. memcpy(result, &desc, desc.getLength());
  89. }
  90. void* allocate(size_t size, size_t alignment) {
  91. size_t aligned = pad(fBuffer->size(), alignment);
  92. fBuffer->resize(aligned + size);
  93. return &(*fBuffer)[aligned];
  94. }
  95. private:
  96. std::vector<uint8_t>* fBuffer;
  97. };
  98. // -- Deserializer -------------------------------------------------------------------------------
  99. // Note that the Deserializer is reading untrusted data, we need to guard against invalid data.
  100. class Deserializer {
  101. public:
  102. Deserializer(const volatile char* memory, size_t memorySize)
  103. : fMemory(memory), fMemorySize(memorySize) {}
  104. template <typename T>
  105. bool read(T* val) {
  106. auto* result = this->ensureAtLeast(sizeof(T), serialization_alignment<T>());
  107. if (!result) return false;
  108. memcpy(val, const_cast<const char*>(result), sizeof(T));
  109. return true;
  110. }
  111. bool readDescriptor(SkAutoDescriptor* ad) {
  112. uint32_t descLength = 0u;
  113. if (!read<uint32_t>(&descLength)) return false;
  114. if (descLength < sizeof(SkDescriptor)) return false;
  115. if (descLength != SkAlign4(descLength)) return false;
  116. auto* result = this->ensureAtLeast(descLength, alignof(SkDescriptor));
  117. if (!result) return false;
  118. ad->reset(descLength);
  119. memcpy(ad->getDesc(), const_cast<const char*>(result), descLength);
  120. if (ad->getDesc()->getLength() > descLength) return false;
  121. return ad->getDesc()->isValid();
  122. }
  123. const volatile void* read(size_t size, size_t alignment) {
  124. return this->ensureAtLeast(size, alignment);
  125. }
  126. size_t bytesRead() const { return fBytesRead; }
  127. private:
  128. const volatile char* ensureAtLeast(size_t size, size_t alignment) {
  129. size_t padded = pad(fBytesRead, alignment);
  130. // Not enough data.
  131. if (padded > fMemorySize) return nullptr;
  132. if (size > fMemorySize - padded) return nullptr;
  133. auto* result = fMemory + padded;
  134. fBytesRead = padded + size;
  135. return result;
  136. }
  137. // Note that we read each piece of memory only once to guard against TOCTOU violations.
  138. const volatile char* fMemory;
  139. size_t fMemorySize;
  140. size_t fBytesRead = 0u;
  141. };
  142. // Paths use a SkWriter32 which requires 4 byte alignment.
  143. static const size_t kPathAlignment = 4u;
  144. size_t SkDescriptorMapOperators::operator()(const SkDescriptor* key) const {
  145. return key->getChecksum();
  146. }
  147. bool SkDescriptorMapOperators::operator()(const SkDescriptor* lhs, const SkDescriptor* rhs) const {
  148. return *lhs == *rhs;
  149. }
  150. struct StrikeSpec {
  151. StrikeSpec() {}
  152. StrikeSpec(SkFontID typefaceID_, SkDiscardableHandleId discardableHandleId_)
  153. : typefaceID{typefaceID_}, discardableHandleId(discardableHandleId_) {}
  154. SkFontID typefaceID = 0u;
  155. SkDiscardableHandleId discardableHandleId = 0u;
  156. /* desc */
  157. /* n X (glyphs ids) */
  158. };
  159. // -- TrackLayerDevice -----------------------------------------------------------------------------
  160. SkTextBlobCacheDiffCanvas::TrackLayerDevice::TrackLayerDevice(
  161. const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
  162. sk_sp<SkColorSpace> colorSpace, const SkTextBlobCacheDiffCanvas::Settings& settings)
  163. : SkNoPixelsDevice(bounds, props, std::move(colorSpace))
  164. , fStrikeServer(server)
  165. , fSettings(settings)
  166. , fPainter{props, kUnknown_SkColorType, imageInfo().colorSpace(), fStrikeServer} {
  167. SkASSERT(fStrikeServer);
  168. }
  169. SkBaseDevice* SkTextBlobCacheDiffCanvas::TrackLayerDevice::onCreateDevice(
  170. const CreateInfo& cinfo, const SkPaint*) {
  171. const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
  172. return new TrackLayerDevice(this->getGlobalBounds(), surfaceProps, fStrikeServer,
  173. cinfo.fInfo.refColorSpace(), fSettings);
  174. }
  175. void SkTextBlobCacheDiffCanvas::TrackLayerDevice::drawGlyphRunList(
  176. const SkGlyphRunList& glyphRunList) {
  177. #if SK_SUPPORT_GPU
  178. GrTextContext::Options options;
  179. options.fMinDistanceFieldFontSize = fSettings.fMinDistanceFieldFontSize;
  180. options.fMaxDistanceFieldFontSize = fSettings.fMaxDistanceFieldFontSize;
  181. GrTextContext::SanitizeOptions(&options);
  182. fPainter.processGlyphRunList(glyphRunList,
  183. this->ctm(),
  184. this->surfaceProps(),
  185. fSettings.fContextSupportsDistanceFieldText,
  186. options,
  187. nullptr);
  188. #endif // SK_SUPPORT_GPU
  189. }
  190. // -- SkTextBlobCacheDiffCanvas -------------------------------------------------------------------
  191. SkTextBlobCacheDiffCanvas::Settings::Settings() = default;
  192. SkTextBlobCacheDiffCanvas::SkTextBlobCacheDiffCanvas(
  193. int width, int height, const SkSurfaceProps& props,
  194. SkStrikeServer* strikeServer, Settings settings)
  195. : SkNoDrawCanvas{sk_make_sp<TrackLayerDevice>(
  196. SkIRect::MakeWH(width, height), props, strikeServer, nullptr, settings)} {}
  197. SkTextBlobCacheDiffCanvas::SkTextBlobCacheDiffCanvas(int width, int height,
  198. const SkSurfaceProps& props,
  199. SkStrikeServer* strikeServer,
  200. sk_sp<SkColorSpace> colorSpace,
  201. Settings settings)
  202. : SkNoDrawCanvas{sk_make_sp<TrackLayerDevice>(SkIRect::MakeWH(width, height), props,
  203. strikeServer, std::move(colorSpace), settings)} {}
  204. SkTextBlobCacheDiffCanvas::~SkTextBlobCacheDiffCanvas() = default;
  205. SkCanvas::SaveLayerStrategy SkTextBlobCacheDiffCanvas::getSaveLayerStrategy(
  206. const SaveLayerRec& rec) {
  207. return kFullLayer_SaveLayerStrategy;
  208. }
  209. bool SkTextBlobCacheDiffCanvas::onDoSaveBehind(const SkRect*) {
  210. return false;
  211. }
  212. void SkTextBlobCacheDiffCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
  213. const SkPaint& paint) {
  214. ///
  215. SkCanvas::onDrawTextBlob(blob, x, y, paint);
  216. }
  217. struct WireTypeface {
  218. WireTypeface() = default;
  219. WireTypeface(SkFontID typeface_id, int glyph_count, SkFontStyle style, bool is_fixed)
  220. : typefaceID(typeface_id), glyphCount(glyph_count), style(style), isFixed(is_fixed) {}
  221. SkFontID typefaceID;
  222. int glyphCount;
  223. SkFontStyle style;
  224. bool isFixed;
  225. };
  226. // SkStrikeServer -----------------------------------------
  227. SkStrikeServer::SkStrikeServer(DiscardableHandleManager* discardableHandleManager)
  228. : fDiscardableHandleManager(discardableHandleManager) {
  229. SkASSERT(fDiscardableHandleManager);
  230. }
  231. SkStrikeServer::~SkStrikeServer() = default;
  232. sk_sp<SkData> SkStrikeServer::serializeTypeface(SkTypeface* tf) {
  233. auto* data = fSerializedTypefaces.find(SkTypeface::UniqueID(tf));
  234. if (data) {
  235. return *data;
  236. }
  237. WireTypeface wire(SkTypeface::UniqueID(tf), tf->countGlyphs(), tf->fontStyle(),
  238. tf->isFixedPitch());
  239. data = fSerializedTypefaces.set(SkTypeface::UniqueID(tf),
  240. SkData::MakeWithCopy(&wire, sizeof(wire)));
  241. return *data;
  242. }
  243. void SkStrikeServer::writeStrikeData(std::vector<uint8_t>* memory) {
  244. if (fLockedDescs.empty() && fTypefacesToSend.empty()) {
  245. return;
  246. }
  247. Serializer serializer(memory);
  248. serializer.emplace<uint64_t>(fTypefacesToSend.size());
  249. for (const auto& tf : fTypefacesToSend) serializer.write<WireTypeface>(tf);
  250. fTypefacesToSend.clear();
  251. serializer.emplace<uint64_t>(fLockedDescs.size());
  252. for (const auto* desc : fLockedDescs) {
  253. auto it = fRemoteGlyphStateMap.find(desc);
  254. SkASSERT(it != fRemoteGlyphStateMap.end());
  255. it->second->writePendingGlyphs(&serializer);
  256. }
  257. fLockedDescs.clear();
  258. }
  259. SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
  260. const SkPaint& paint,
  261. const SkFont& font,
  262. const SkSurfaceProps& props,
  263. const SkMatrix& matrix,
  264. SkScalerContextFlags flags,
  265. SkScalerContextEffects* effects) {
  266. SkAutoDescriptor descStorage;
  267. auto desc = create_descriptor(paint, font, matrix, props, flags, &descStorage, effects);
  268. return this->getOrCreateCache(*desc, *font.getTypefaceOrDefault(), *effects);
  269. }
  270. SkScopedStrike SkStrikeServer::findOrCreateScopedStrike(const SkDescriptor& desc,
  271. const SkScalerContextEffects& effects,
  272. const SkTypeface& typeface) {
  273. return SkScopedStrike{this->getOrCreateCache(desc, typeface, effects)};
  274. }
  275. void SkStrikeServer::checkForDeletedEntries() {
  276. auto it = fRemoteGlyphStateMap.begin();
  277. while (fRemoteGlyphStateMap.size() > fMaxEntriesInDescriptorMap &&
  278. it != fRemoteGlyphStateMap.end()) {
  279. if (fDiscardableHandleManager->isHandleDeleted(it->second->discardableHandleId())) {
  280. it = fRemoteGlyphStateMap.erase(it);
  281. } else {
  282. ++it;
  283. }
  284. }
  285. }
  286. SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
  287. const SkDescriptor& desc, const SkTypeface& typeface, SkScalerContextEffects effects) {
  288. // In cases where tracing is turned off, make sure not to get an unused function warning.
  289. // Lambdaize the function.
  290. TRACE_EVENT1("skia", "RecForDesc", "rec",
  291. TRACE_STR_COPY(
  292. [&desc](){
  293. auto ptr = desc.findEntry(kRec_SkDescriptorTag, nullptr);
  294. SkScalerContextRec rec;
  295. std::memcpy(&rec, ptr, sizeof(rec));
  296. return rec.dump();
  297. }().c_str()
  298. )
  299. );
  300. // Already locked.
  301. if (fLockedDescs.find(&desc) != fLockedDescs.end()) {
  302. auto it = fRemoteGlyphStateMap.find(&desc);
  303. SkASSERT(it != fRemoteGlyphStateMap.end());
  304. SkGlyphCacheState* cache = it->second.get();
  305. cache->setTypefaceAndEffects(&typeface, effects);
  306. return cache;
  307. }
  308. // Try to lock.
  309. auto it = fRemoteGlyphStateMap.find(&desc);
  310. if (it != fRemoteGlyphStateMap.end()) {
  311. SkGlyphCacheState* cache = it->second.get();
  312. bool locked = fDiscardableHandleManager->lockHandle(it->second->discardableHandleId());
  313. if (locked) {
  314. fLockedDescs.insert(it->first);
  315. cache->setTypefaceAndEffects(&typeface, effects);
  316. return cache;
  317. }
  318. // If the lock failed, the entry was deleted on the client. Remove our
  319. // tracking.
  320. fRemoteGlyphStateMap.erase(it);
  321. }
  322. const SkFontID typefaceId = typeface.uniqueID();
  323. if (!fCachedTypefaces.contains(typefaceId)) {
  324. fCachedTypefaces.add(typefaceId);
  325. fTypefacesToSend.emplace_back(typefaceId, typeface.countGlyphs(),
  326. typeface.fontStyle(),
  327. typeface.isFixedPitch());
  328. }
  329. auto context = typeface.createScalerContext(effects, &desc);
  330. // Create a new cache state and insert it into the map.
  331. auto newHandle = fDiscardableHandleManager->createHandle();
  332. auto cacheState = skstd::make_unique<SkGlyphCacheState>(desc, std::move(context), newHandle);
  333. auto* cacheStatePtr = cacheState.get();
  334. fLockedDescs.insert(&cacheStatePtr->getDescriptor());
  335. fRemoteGlyphStateMap[&cacheStatePtr->getDescriptor()] = std::move(cacheState);
  336. checkForDeletedEntries();
  337. cacheStatePtr->setTypefaceAndEffects(&typeface, effects);
  338. return cacheStatePtr;
  339. }
  340. // -- SkGlyphCacheState ----------------------------------------------------------------------------
  341. SkStrikeServer::SkGlyphCacheState::SkGlyphCacheState(
  342. const SkDescriptor& descriptor,
  343. std::unique_ptr<SkScalerContext> context,
  344. uint32_t discardableHandleId)
  345. : fDescriptor{descriptor}
  346. , fDiscardableHandleId(discardableHandleId)
  347. , fIsSubpixel{context->isSubpixel()}
  348. , fAxisAlignment{context->computeAxisAlignmentForHText()}
  349. // N.B. context must come last because it is used above.
  350. , fContext{std::move(context)} {
  351. SkASSERT(fDescriptor.getDesc() != nullptr);
  352. SkASSERT(fContext != nullptr);
  353. }
  354. SkStrikeServer::SkGlyphCacheState::~SkGlyphCacheState() = default;
  355. void SkStrikeServer::SkGlyphCacheState::addGlyph(SkPackedGlyphID glyph, bool asPath) {
  356. auto* cache = asPath ? &fCachedGlyphPaths : &fCachedGlyphImages;
  357. auto* pending = asPath ? &fPendingGlyphPaths : &fPendingGlyphImages;
  358. // Already cached.
  359. if (cache->contains(glyph)) {
  360. return;
  361. }
  362. // A glyph is going to be sent. Make sure we have a scaler context to send it.
  363. this->ensureScalerContext();
  364. // Serialize and cache. Also create the scalar context to use when serializing
  365. // this glyph.
  366. cache->add(glyph);
  367. pending->push_back(glyph);
  368. }
  369. // No need to write fForceBW because it is a flag private to SkScalerContext_DW, which will never
  370. // be called on the GPU side.
  371. static void writeGlyph(SkGlyph* glyph, Serializer* serializer) {
  372. serializer->write<SkPackedGlyphID>(glyph->getPackedID());
  373. serializer->write<float>(glyph->advanceX());
  374. serializer->write<float>(glyph->advanceY());
  375. serializer->write<uint16_t>(glyph->width());
  376. serializer->write<uint16_t>(glyph->height());
  377. serializer->write<int16_t>(glyph->top());
  378. serializer->write<int16_t>(glyph->left());
  379. serializer->write<uint8_t>(glyph->maskFormat());
  380. }
  381. void SkStrikeServer::SkGlyphCacheState::writePendingGlyphs(Serializer* serializer) {
  382. // TODO(khushalsagar): Write a strike only if it has any pending glyphs.
  383. serializer->emplace<bool>(this->hasPendingGlyphs());
  384. if (!this->hasPendingGlyphs()) {
  385. this->resetScalerContext();
  386. return;
  387. }
  388. // Write the desc.
  389. serializer->emplace<StrikeSpec>(fContext->getTypeface()->uniqueID(), fDiscardableHandleId);
  390. serializer->writeDescriptor(*fDescriptor.getDesc());
  391. // Write FontMetrics.
  392. // TODO(khushalsagar): Do we need to re-send each time?
  393. SkFontMetrics fontMetrics;
  394. fContext->getFontMetrics(&fontMetrics);
  395. serializer->write<SkFontMetrics>(fontMetrics);
  396. // Write glyphs images.
  397. serializer->emplace<uint64_t>(fPendingGlyphImages.size());
  398. for (const auto& glyphID : fPendingGlyphImages) {
  399. SkGlyph glyph{glyphID};
  400. fContext->getMetrics(&glyph);
  401. SkASSERT(SkMask::IsValidFormat(glyph.fMaskFormat));
  402. writeGlyph(&glyph, serializer);
  403. auto imageSize = glyph.imageSize();
  404. if (imageSize == 0u) continue;
  405. glyph.fImage = serializer->allocate(imageSize, glyph.formatAlignment());
  406. fContext->getImage(glyph);
  407. // TODO: Generating the image can change the mask format, do we need to update it in the
  408. // serialized glyph?
  409. }
  410. fPendingGlyphImages.clear();
  411. // Write glyphs paths.
  412. serializer->emplace<uint64_t>(fPendingGlyphPaths.size());
  413. for (const auto& glyphID : fPendingGlyphPaths) {
  414. SkGlyph glyph{glyphID};
  415. fContext->getMetrics(&glyph);
  416. SkASSERT(SkMask::IsValidFormat(glyph.fMaskFormat));
  417. writeGlyph(&glyph, serializer);
  418. writeGlyphPath(glyphID, serializer);
  419. }
  420. fPendingGlyphPaths.clear();
  421. this->resetScalerContext();
  422. }
  423. void SkStrikeServer::SkGlyphCacheState::ensureScalerContext() {
  424. if (fContext == nullptr) {
  425. fContext = fTypeface->createScalerContext(fEffects, fDescriptor.getDesc());
  426. }
  427. }
  428. void SkStrikeServer::SkGlyphCacheState::resetScalerContext() {
  429. fContext.reset();
  430. fTypeface = nullptr;
  431. }
  432. void SkStrikeServer::SkGlyphCacheState::setTypefaceAndEffects(
  433. const SkTypeface* typeface, SkScalerContextEffects effects) {
  434. fTypeface = typeface;
  435. fEffects = effects;
  436. }
  437. SkVector SkStrikeServer::SkGlyphCacheState::rounding() const {
  438. return SkStrikeCommon::PixelRounding(fIsSubpixel, fAxisAlignment);
  439. }
  440. void SkStrikeServer::SkGlyphCacheState::writeGlyphPath(const SkPackedGlyphID& glyphID,
  441. Serializer* serializer) const {
  442. SkPath path;
  443. if (!fContext->getPath(glyphID, &path)) {
  444. serializer->write<uint64_t>(0u);
  445. return;
  446. }
  447. size_t pathSize = path.writeToMemory(nullptr);
  448. serializer->write<uint64_t>(pathSize);
  449. path.writeToMemory(serializer->allocate(pathSize, kPathAlignment));
  450. }
  451. // Be sure to read and understand the comment for prepareForDrawing in SkStrikeInterface.h before
  452. // working on this code.
  453. SkSpan<const SkGlyphPos>
  454. SkStrikeServer::SkGlyphCacheState::prepareForDrawing(const SkPackedGlyphID packedGlyphIDs[],
  455. const SkPoint positions[], size_t n,
  456. int maxDimension, PreparationDetail detail,
  457. SkGlyphPos results[]) {
  458. for (size_t i = 0; i < n; i++) {
  459. SkPoint glyphPos = positions[i];
  460. // Check the cache for the glyph.
  461. SkGlyph* glyphPtr = fGlyphMap.findOrNull(packedGlyphIDs[i]);
  462. // Has this glyph ever been seen before?
  463. if (glyphPtr == nullptr) {
  464. // Never seen before. Make a new glyph.
  465. glyphPtr = fAlloc.make<SkGlyph>(packedGlyphIDs[i]);
  466. fGlyphMap.set(glyphPtr);
  467. this->ensureScalerContext();
  468. fContext->getMetrics(glyphPtr);
  469. if (glyphPtr->maxDimension() <= maxDimension) {
  470. // do nothing
  471. } else if (!glyphPtr->isColor()) {
  472. // The glyph is too big for the atlas, but it is not color, so it is handled with a
  473. // path.
  474. if (glyphPtr->setPath(&fAlloc, fContext.get())) {
  475. // Always send the path data, even if its not available, to make sure empty
  476. // paths are not incorrectly assumed to be cache misses.
  477. fCachedGlyphPaths.add(glyphPtr->getPackedID());
  478. fPendingGlyphPaths.push_back(glyphPtr->getPackedID());
  479. }
  480. } else {
  481. // This will be handled by the fallback strike.
  482. SkASSERT(glyphPtr->maxDimension() > maxDimension && glyphPtr->isColor());
  483. }
  484. // Make sure to send the glyph to the GPU because we always send the image for a glyph.
  485. fCachedGlyphImages.add(packedGlyphIDs[i]);
  486. fPendingGlyphImages.push_back(packedGlyphIDs[i]);
  487. }
  488. // Each glyph needs to be added as per the contract for prepareForDrawing.
  489. // TODO(herb): check if the empty glyphs need to be added here. They certainly need to be
  490. // sent, but do the need to be processed by the painter?
  491. results[i] = {i, glyphPtr, glyphPos};
  492. }
  493. return SkSpan<const SkGlyphPos>{results, n};
  494. }
  495. // SkStrikeClient -----------------------------------------
  496. class SkStrikeClient::DiscardableStrikePinner : public SkStrikePinner {
  497. public:
  498. DiscardableStrikePinner(SkDiscardableHandleId discardableHandleId,
  499. sk_sp<DiscardableHandleManager> manager)
  500. : fDiscardableHandleId(discardableHandleId), fManager(std::move(manager)) {}
  501. ~DiscardableStrikePinner() override = default;
  502. bool canDelete() override { return fManager->deleteHandle(fDiscardableHandleId); }
  503. private:
  504. const SkDiscardableHandleId fDiscardableHandleId;
  505. sk_sp<DiscardableHandleManager> fManager;
  506. };
  507. SkStrikeClient::SkStrikeClient(sk_sp<DiscardableHandleManager> discardableManager,
  508. bool isLogging,
  509. SkStrikeCache* strikeCache)
  510. : fDiscardableHandleManager(std::move(discardableManager))
  511. , fStrikeCache{strikeCache ? strikeCache : SkStrikeCache::GlobalStrikeCache()}
  512. , fIsLogging{isLogging} {}
  513. SkStrikeClient::~SkStrikeClient() = default;
  514. #define READ_FAILURE \
  515. { \
  516. SkDebugf("Bad font data serialization line: %d", __LINE__); \
  517. DiscardableHandleManager::ReadFailureData data = { \
  518. memorySize, deserializer.bytesRead(), typefaceSize, \
  519. strikeCount, glyphImagesCount, glyphPathsCount}; \
  520. fDiscardableHandleManager->notifyReadFailure(data); \
  521. return false; \
  522. }
  523. // No need to read fForceBW because it is a flag private to SkScalerContext_DW, which will never
  524. // be called on the GPU side.
  525. bool SkStrikeClient::ReadGlyph(SkTLazy<SkGlyph>& glyph, Deserializer* deserializer) {
  526. SkPackedGlyphID glyphID;
  527. if (!deserializer->read<SkPackedGlyphID>(&glyphID)) return false;
  528. glyph.init(glyphID);
  529. if (!deserializer->read<float>(&glyph->fAdvanceX)) return false;
  530. if (!deserializer->read<float>(&glyph->fAdvanceY)) return false;
  531. if (!deserializer->read<uint16_t>(&glyph->fWidth)) return false;
  532. if (!deserializer->read<uint16_t>(&glyph->fHeight)) return false;
  533. if (!deserializer->read<int16_t>(&glyph->fTop)) return false;
  534. if (!deserializer->read<int16_t>(&glyph->fLeft)) return false;
  535. if (!deserializer->read<uint8_t>(&glyph->fMaskFormat)) return false;
  536. if (!SkMask::IsValidFormat(glyph->fMaskFormat)) return false;
  537. return true;
  538. }
  539. bool SkStrikeClient::readStrikeData(const volatile void* memory, size_t memorySize) {
  540. SkASSERT(memorySize != 0u);
  541. Deserializer deserializer(static_cast<const volatile char*>(memory), memorySize);
  542. uint64_t typefaceSize = 0u;
  543. uint64_t strikeCount = 0u;
  544. uint64_t glyphImagesCount = 0u;
  545. uint64_t glyphPathsCount = 0u;
  546. if (!deserializer.read<uint64_t>(&typefaceSize)) READ_FAILURE
  547. for (size_t i = 0; i < typefaceSize; ++i) {
  548. WireTypeface wire;
  549. if (!deserializer.read<WireTypeface>(&wire)) READ_FAILURE
  550. // TODO(khushalsagar): The typeface no longer needs a reference to the
  551. // SkStrikeClient, since all needed glyphs must have been pushed before
  552. // raster.
  553. addTypeface(wire);
  554. }
  555. if (!deserializer.read<uint64_t>(&strikeCount)) READ_FAILURE
  556. for (size_t i = 0; i < strikeCount; ++i) {
  557. bool has_glyphs = false;
  558. if (!deserializer.read<bool>(&has_glyphs)) READ_FAILURE
  559. if (!has_glyphs) continue;
  560. StrikeSpec spec;
  561. if (!deserializer.read<StrikeSpec>(&spec)) READ_FAILURE
  562. SkAutoDescriptor sourceAd;
  563. if (!deserializer.readDescriptor(&sourceAd)) READ_FAILURE
  564. SkFontMetrics fontMetrics;
  565. if (!deserializer.read<SkFontMetrics>(&fontMetrics)) READ_FAILURE
  566. // Get the local typeface from remote fontID.
  567. auto* tfPtr = fRemoteFontIdToTypeface.find(spec.typefaceID);
  568. // Received strikes for a typeface which doesn't exist.
  569. if (!tfPtr) READ_FAILURE
  570. auto* tf = tfPtr->get();
  571. // Replace the ContextRec in the desc from the server to create the client
  572. // side descriptor.
  573. // TODO: Can we do this in-place and re-compute checksum? Instead of a complete copy.
  574. SkAutoDescriptor ad;
  575. auto* client_desc = auto_descriptor_from_desc(sourceAd.getDesc(), tf->uniqueID(), &ad);
  576. auto strike = fStrikeCache->findStrikeExclusive(*client_desc);
  577. if (strike == nullptr) {
  578. // Note that we don't need to deserialize the effects since we won't be generating any
  579. // glyphs here anyway, and the desc is still correct since it includes the serialized
  580. // effects.
  581. SkScalerContextEffects effects;
  582. auto scaler = SkStrikeCache::CreateScalerContext(*client_desc, effects, *tf);
  583. strike = fStrikeCache->createStrikeExclusive(
  584. *client_desc, std::move(scaler), &fontMetrics,
  585. skstd::make_unique<DiscardableStrikePinner>(spec.discardableHandleId,
  586. fDiscardableHandleManager));
  587. auto proxyContext = static_cast<SkScalerContextProxy*>(strike->getScalerContext());
  588. proxyContext->initCache(strike.get(), fStrikeCache);
  589. }
  590. if (!deserializer.read<uint64_t>(&glyphImagesCount)) READ_FAILURE
  591. for (size_t j = 0; j < glyphImagesCount; j++) {
  592. SkTLazy<SkGlyph> glyph;
  593. if (!ReadGlyph(glyph, &deserializer)) READ_FAILURE
  594. if (!glyph->isEmpty()) {
  595. const volatile void* image =
  596. deserializer.read(glyph->imageSize(), glyph->formatAlignment());
  597. if (!image) READ_FAILURE
  598. glyph->fImage = (void*)image;
  599. }
  600. strike->mergeGlyphAndImage(glyph->getPackedID(), *glyph);
  601. }
  602. if (!deserializer.read<uint64_t>(&glyphPathsCount)) READ_FAILURE
  603. for (size_t j = 0; j < glyphPathsCount; j++) {
  604. SkTLazy<SkGlyph> glyph;
  605. if (!ReadGlyph(glyph, &deserializer)) READ_FAILURE
  606. SkGlyph* allocatedGlyph = strike->mergeGlyphAndImage(glyph->getPackedID(), *glyph);
  607. SkPath* pathPtr = nullptr;
  608. SkPath path;
  609. uint64_t pathSize = 0u;
  610. if (!deserializer.read<uint64_t>(&pathSize)) READ_FAILURE
  611. if (pathSize > 0) {
  612. auto* pathData = deserializer.read(pathSize, kPathAlignment);
  613. if (!pathData) READ_FAILURE
  614. if (!path.readFromMemory(const_cast<const void*>(pathData), pathSize)) READ_FAILURE
  615. pathPtr = &path;
  616. }
  617. strike->preparePath(allocatedGlyph, pathPtr);
  618. }
  619. }
  620. return true;
  621. }
  622. sk_sp<SkTypeface> SkStrikeClient::deserializeTypeface(const void* buf, size_t len) {
  623. WireTypeface wire;
  624. if (len != sizeof(wire)) return nullptr;
  625. memcpy(&wire, buf, sizeof(wire));
  626. return this->addTypeface(wire);
  627. }
  628. sk_sp<SkTypeface> SkStrikeClient::addTypeface(const WireTypeface& wire) {
  629. auto* typeface = fRemoteFontIdToTypeface.find(wire.typefaceID);
  630. if (typeface) return *typeface;
  631. auto newTypeface = sk_make_sp<SkTypefaceProxy>(
  632. wire.typefaceID, wire.glyphCount, wire.style, wire.isFixed,
  633. fDiscardableHandleManager, fIsLogging);
  634. fRemoteFontIdToTypeface.set(wire.typefaceID, newTypeface);
  635. return std::move(newTypeface);
  636. }