• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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/text/gpu/StrikeCache.h"
8 
9 #include "include/private/base/SkAssert.h"
10 #include "include/private/chromium/SkChromeRemoteGlyphCache.h"
11 #include "src/base/SkArenaAlloc.h"
12 #include "src/core/SkGlyph.h"
13 #include "src/core/SkReadBuffer.h"
14 #include "src/core/SkStrikeCache.h"
15 #include "src/core/SkStrikeSpec.h"
16 #include "src/text/StrikeForGPU.h"
17 #include "src/text/gpu/Glyph.h"
18 
19 #include <optional>
20 #include <utility>
21 
22 class SkStrike;
23 
24 namespace sktext::gpu {
25 
~StrikeCache()26 StrikeCache::~StrikeCache() {
27     this->freeAll();
28 }
29 
freeAll()30 void StrikeCache::freeAll() {
31     fCache.reset();
32 }
33 
findOrCreateStrike(const SkStrikeSpec & strikeSpec)34 sk_sp<TextStrike> StrikeCache::findOrCreateStrike(const SkStrikeSpec& strikeSpec) {
35     if (sk_sp<TextStrike>* cached = fCache.find(strikeSpec.descriptor())) {
36         return *cached;
37     }
38     return this->generateStrike(strikeSpec);
39 }
40 
generateStrike(const SkStrikeSpec & strikeSpec)41 sk_sp<TextStrike> StrikeCache::generateStrike(const SkStrikeSpec& strikeSpec) {
42     sk_sp<TextStrike> strike = sk_make_sp<TextStrike>(strikeSpec);
43     fCache.set(strike);
44     return strike;
45 }
46 
GetKey(const sk_sp<TextStrike> & strike)47 const SkDescriptor& StrikeCache::HashTraits::GetKey(const sk_sp<TextStrike>& strike) {
48     return strike->fStrikeSpec.descriptor();
49 }
50 
Hash(const SkDescriptor & descriptor)51 uint32_t StrikeCache::HashTraits::Hash(const SkDescriptor& descriptor) {
52     return descriptor.getChecksum();
53 }
54 
TextStrike(const SkStrikeSpec & strikeSpec)55 TextStrike::TextStrike(const SkStrikeSpec& strikeSpec) : fStrikeSpec{strikeSpec} {}
56 
getGlyph(SkPackedGlyphID packedGlyphID)57 Glyph* TextStrike::getGlyph(SkPackedGlyphID packedGlyphID) {
58     Glyph* glyph = fCache.findOrNull(packedGlyphID);
59     if (glyph == nullptr) {
60         glyph = fAlloc.make<Glyph>(packedGlyphID);
61         fCache.set(glyph);
62     }
63     return glyph;
64 }
65 
GetKey(const Glyph * glyph)66 const SkPackedGlyphID& TextStrike::HashTraits::GetKey(const Glyph* glyph) {
67     return glyph->fPackedID;
68 }
69 
Hash(SkPackedGlyphID key)70 uint32_t TextStrike::HashTraits::Hash(SkPackedGlyphID key) {
71     return key.hash();
72 }
73 
74 }  // namespace sktext::gpu
75 
76 namespace sktext {
MakeFromBuffer(SkReadBuffer & buffer,const SkStrikeClient * client,SkStrikeCache * strikeCache)77 std::optional<SkStrikePromise> SkStrikePromise::MakeFromBuffer(
78         SkReadBuffer& buffer, const SkStrikeClient* client, SkStrikeCache* strikeCache) {
79     std::optional<SkAutoDescriptor> descriptor = SkAutoDescriptor::MakeFromBuffer(buffer);
80     if (!buffer.validate(descriptor.has_value())) {
81         return std::nullopt;
82     }
83 
84     // If there is a client, then this from a different process. Translate the SkTypefaceID from
85     // the strike server (Renderer) process to strike client (GPU) process.
86     if (client != nullptr) {
87         if (!client->translateTypefaceID(&descriptor.value())) {
88             return std::nullopt;
89         }
90     }
91 
92     sk_sp<SkStrike> strike = strikeCache->findStrike(*descriptor->getDesc());
93     SkASSERT(strike != nullptr);
94     if (!buffer.validate(strike != nullptr)) {
95         return std::nullopt;
96     }
97 
98     return SkStrikePromise{std::move(strike)};
99 }
100 }  // namespace sktext
101