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