| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| #include "src/text/gpu/StrikeCache.h" |
| |
| #include "include/private/base/SkAssert.h" |
| #include "include/private/chromium/SkChromeRemoteGlyphCache.h" |
| #include "src/base/SkArenaAlloc.h" |
| #include "src/core/SkGlyph.h" |
| #include "src/core/SkReadBuffer.h" |
| #include "src/core/SkStrikeCache.h" |
| #include "src/core/SkStrikeSpec.h" |
| #include "src/text/StrikeForGPU.h" |
| #include "src/text/gpu/Glyph.h" |
| |
| #include <optional> |
| #include <utility> |
| |
| class SkStrike; |
| |
| namespace sktext::gpu { |
| |
| StrikeCache::~StrikeCache() { |
| this->freeAll(); |
| } |
| |
| void StrikeCache::freeAll() { |
| fCache.reset(); |
| } |
| |
| sk_sp<TextStrike> StrikeCache::findOrCreateStrike(const SkStrikeSpec& strikeSpec) { |
| if (sk_sp<TextStrike>* cached = fCache.find(strikeSpec.descriptor())) { |
| return *cached; |
| } |
| return this->generateStrike(strikeSpec); |
| } |
| |
| sk_sp<TextStrike> StrikeCache::generateStrike(const SkStrikeSpec& strikeSpec) { |
| sk_sp<TextStrike> strike = sk_make_sp<TextStrike>(strikeSpec); |
| fCache.set(strike); |
| return strike; |
| } |
| |
| const SkDescriptor& StrikeCache::HashTraits::GetKey(const sk_sp<TextStrike>& strike) { |
| return strike->fStrikeSpec.descriptor(); |
| } |
| |
| uint32_t StrikeCache::HashTraits::Hash(const SkDescriptor& descriptor) { |
| return descriptor.getChecksum(); |
| } |
| |
| TextStrike::TextStrike(const SkStrikeSpec& strikeSpec) : fStrikeSpec{strikeSpec} {} |
| |
| Glyph* TextStrike::getGlyph(SkPackedGlyphID packedGlyphID) { |
| Glyph* glyph = fCache.findOrNull(packedGlyphID); |
| if (glyph == nullptr) { |
| glyph = fAlloc.make<Glyph>(packedGlyphID); |
| fCache.set(glyph); |
| } |
| return glyph; |
| } |
| |
| const SkPackedGlyphID& TextStrike::HashTraits::GetKey(const Glyph* glyph) { |
| return glyph->fPackedID; |
| } |
| |
| uint32_t TextStrike::HashTraits::Hash(SkPackedGlyphID key) { |
| return key.hash(); |
| } |
| |
| } // namespace sktext::gpu |
| |
| namespace sktext { |
| std::optional<SkStrikePromise> SkStrikePromise::MakeFromBuffer( |
| SkReadBuffer& buffer, const SkStrikeClient* client, SkStrikeCache* strikeCache) { |
| std::optional<SkAutoDescriptor> descriptor = SkAutoDescriptor::MakeFromBuffer(buffer); |
| if (!buffer.validate(descriptor.has_value())) { |
| return std::nullopt; |
| } |
| |
| // If there is a client, then this from a different process. Translate the SkTypefaceID from |
| // the strike server (Renderer) process to strike client (GPU) process. |
| if (client != nullptr) { |
| if (!client->translateTypefaceID(&descriptor.value())) { |
| return std::nullopt; |
| } |
| } |
| |
| sk_sp<SkStrike> strike = strikeCache->findStrike(*descriptor->getDesc()); |
| SkASSERT(strike != nullptr); |
| if (!buffer.validate(strike != nullptr)) { |
| return std::nullopt; |
| } |
| |
| return SkStrikePromise{std::move(strike)}; |
| } |
| } // namespace sktext |