blob: 67b94fd6d0aa79c1cb8ebc7d2cd2759e637a15e7 [file] [log] [blame]
/*
* 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