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()26StrikeCache::~StrikeCache() { 27 this->freeAll(); 28 } 29 freeAll()30void StrikeCache::freeAll() { 31 fCache.reset(); 32 } 33 findOrCreateStrike(const SkStrikeSpec & strikeSpec)34sk_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)41sk_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)47const SkDescriptor& StrikeCache::HashTraits::GetKey(const sk_sp<TextStrike>& strike) { 48 return strike->fStrikeSpec.descriptor(); 49 } 50 Hash(const SkDescriptor & descriptor)51uint32_t StrikeCache::HashTraits::Hash(const SkDescriptor& descriptor) { 52 return descriptor.getChecksum(); 53 } 54 TextStrike(const SkStrikeSpec & strikeSpec)55TextStrike::TextStrike(const SkStrikeSpec& strikeSpec) : fStrikeSpec{strikeSpec} {} 56 getGlyph(SkPackedGlyphID packedGlyphID)57Glyph* 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)66const SkPackedGlyphID& TextStrike::HashTraits::GetKey(const Glyph* glyph) { 67 return glyph->fPackedID; 68 } 69 Hash(SkPackedGlyphID key)70uint32_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)77std::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