/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkRemoteGlyphCache.h" struct WireTypeface { // std::thread::id thread_id; // TODO:need to figure a good solution SkFontID typeface_id; SkFontStyle style; bool is_fixed; }; void SkRemoteGlyphCacheRenderer::prepareSerializeProcs(SkSerialProcs* procs) { auto encode = [](SkTypeface* tf, void* ctx) { return reinterpret_cast(ctx)->encodeTypeface(tf); }; procs->fTypefaceProc = encode; procs->fTypefaceCtx = this; } SkScalerContext* SkRemoteGlyphCacheRenderer::generateScalerContext( const SkScalerContextRecDescriptor& desc, SkFontID typefaceId) { auto scaler = fScalerContextMap.find(desc); if (scaler == nullptr) { auto typefaceIter = fTypefaceMap.find(typefaceId); if (typefaceIter == nullptr) { // TODO: handle this with some future fallback strategy. SK_ABORT("unknown type face"); // Should never happen return nullptr; } auto tf = typefaceIter->get(); SkScalerContextEffects effects; auto mapSc = tf->createScalerContext(effects, &desc.desc(), false); scaler = fScalerContextMap.set(desc, std::move(mapSc)); } return scaler->get(); } sk_sp SkRemoteGlyphCacheRenderer::encodeTypeface(SkTypeface* tf) { WireTypeface wire = { SkTypeface::UniqueID(tf), tf->fontStyle(), tf->isFixedPitch() }; auto typeFace = fTypefaceMap.find(SkTypeface::UniqueID(tf)); if (typeFace == nullptr) { fTypefaceMap.set(SkTypeface::UniqueID(tf), sk_ref_sp(tf)); } // Can this be done with no copy? return SkData::MakeWithCopy(&wire, sizeof(wire)); } SkRemoteGlyphCacheGPU::SkRemoteGlyphCacheGPU( std::unique_ptr remoteScalerContext) : fRemoteScalerContext{std::move(remoteScalerContext)} { } void SkRemoteGlyphCacheGPU::prepareDeserializeProcs(SkDeserialProcs* procs) { auto decode = [](const void* buf, size_t len, void* ctx) { return reinterpret_cast(ctx)->decodeTypeface(buf, len); }; procs->fTypefaceProc = decode; procs->fTypefaceCtx = this; } sk_sp SkRemoteGlyphCacheGPU::decodeTypeface(const void* buf, size_t len) { WireTypeface wire; if (len < sizeof(wire)) { SK_ABORT("Incomplete transfer"); return nullptr; } memcpy(&wire, buf, sizeof(wire)); auto typeFace = fMapIdToTypeface.find(wire.typeface_id); if (typeFace == nullptr) { auto newTypeface = sk_make_sp( wire.typeface_id, wire.style, wire.is_fixed, fRemoteScalerContext.get()); typeFace = fMapIdToTypeface.set(wire.typeface_id, newTypeface); } return *typeFace; }