/* * 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 #include class SkStrike; namespace sktext::gpu { StrikeCache::~StrikeCache() { this->freeAll(); } void StrikeCache::freeAll() { fCache.reset(); } sk_sp StrikeCache::findOrCreateStrike(const SkStrikeSpec& strikeSpec) { if (sk_sp* cached = fCache.find(strikeSpec.descriptor())) { return *cached; } return this->generateStrike(strikeSpec); } sk_sp StrikeCache::generateStrike(const SkStrikeSpec& strikeSpec) { sk_sp strike = sk_make_sp(strikeSpec); fCache.set(strike); return strike; } const SkDescriptor& StrikeCache::HashTraits::GetKey(const sk_sp& 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(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::MakeFromBuffer( SkReadBuffer& buffer, const SkStrikeClient* client, SkStrikeCache* strikeCache) { std::optional 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 strike = strikeCache->findStrike(*descriptor->getDesc()); SkASSERT(strike != nullptr); if (!buffer.validate(strike != nullptr)) { return std::nullopt; } return SkStrikePromise{std::move(strike)}; } } // namespace sktext