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 
prepareSerializeProcs(SkSerialProcs * procs)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 
generateScalerContext(const SkScalerContextRecDescriptor & desc,SkFontID typefaceId)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 
encodeTypeface(SkTypeface * tf)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 
SkRemoteGlyphCacheGPU(std::unique_ptr<SkRemoteScalerContext> remoteScalerContext)59 SkRemoteGlyphCacheGPU::SkRemoteGlyphCacheGPU(
60     std::unique_ptr<SkRemoteScalerContext> remoteScalerContext)
61     : fRemoteScalerContext{std::move(remoteScalerContext)} { }
62 
prepareDeserializeProcs(SkDeserialProcs * procs)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 
decodeTypeface(const void * buf,size_t len)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