Home | History | Annotate | Download | only in core
      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