1 /* 2 * Copyright 2018 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 8 #include "SkRemoteGlyphCache.h" 9 10 struct WireTypeface { 11 // std::thread::id thread_id; // TODO:need to figure a good solution 12 SkFontID typeface_id; 13 SkFontStyle style; 14 bool is_fixed; 15 }; 16 17 void SkRemoteGlyphCacheRenderer::prepareSerializeProcs(SkSerialProcs* procs) { 18 auto encode = [](SkTypeface* tf, void* ctx) { 19 return reinterpret_cast<SkRemoteGlyphCacheRenderer*>(ctx)->encodeTypeface(tf); 20 }; 21 procs->fTypefaceProc = encode; 22 procs->fTypefaceCtx = this; 23 } 24 25 SkScalerContext* SkRemoteGlyphCacheRenderer::generateScalerContext( 26 const SkScalerContextRecDescriptor& desc, SkFontID typefaceId) 27 { 28 auto scaler = fScalerContextMap.find(desc); 29 if (scaler == nullptr) { 30 auto typefaceIter = fTypefaceMap.find(typefaceId); 31 if (typefaceIter == nullptr) { 32 // TODO: handle this with some future fallback strategy. 33 SK_ABORT("unknown type face"); 34 // Should never happen 35 return nullptr; 36 } 37 auto tf = typefaceIter->get(); 38 SkScalerContextEffects effects; 39 auto mapSc = tf->createScalerContext(effects, &desc.desc(), false); 40 scaler = fScalerContextMap.set(desc, std::move(mapSc)); 41 } 42 return scaler->get(); 43 } 44 45 sk_sp<SkData> SkRemoteGlyphCacheRenderer::encodeTypeface(SkTypeface* tf) { 46 WireTypeface wire = { 47 SkTypeface::UniqueID(tf), 48 tf->fontStyle(), 49 tf->isFixedPitch() 50 }; 51 auto typeFace = fTypefaceMap.find(SkTypeface::UniqueID(tf)); 52 if (typeFace == nullptr) { 53 fTypefaceMap.set(SkTypeface::UniqueID(tf), sk_ref_sp(tf)); 54 } 55 // Can this be done with no copy? 56 return SkData::MakeWithCopy(&wire, sizeof(wire)); 57 } 58 59 SkRemoteGlyphCacheGPU::SkRemoteGlyphCacheGPU( 60 std::unique_ptr<SkRemoteScalerContext> remoteScalerContext) 61 : fRemoteScalerContext{std::move(remoteScalerContext)} { } 62 63 void SkRemoteGlyphCacheGPU::prepareDeserializeProcs(SkDeserialProcs* procs) { 64 auto decode = [](const void* buf, size_t len, void* ctx) { 65 return reinterpret_cast<SkRemoteGlyphCacheGPU*>(ctx)->decodeTypeface(buf, len); 66 }; 67 procs->fTypefaceProc = decode; 68 procs->fTypefaceCtx = this; 69 } 70 71 72 sk_sp<SkTypeface> SkRemoteGlyphCacheGPU::decodeTypeface(const void* buf, size_t len) { 73 WireTypeface wire; 74 if (len < sizeof(wire)) { 75 SK_ABORT("Incomplete transfer"); 76 return nullptr; 77 } 78 memcpy(&wire, buf, sizeof(wire)); 79 80 auto typeFace = fMapIdToTypeface.find(wire.typeface_id); 81 if (typeFace == nullptr) { 82 83 auto newTypeface = sk_make_sp<SkTypefaceProxy>( 84 wire.typeface_id, 85 wire.style, 86 wire.is_fixed, 87 fRemoteScalerContext.get()); 88 89 typeFace = fMapIdToTypeface.set(wire.typeface_id, newTypeface); 90 } 91 return *typeFace; 92 } 93 94 95