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 #ifndef SkRemoteGlyphCache_DEFINED 9 #define SkRemoteGlyphCache_DEFINED 10 11 #include <memory> 12 #include "SkData.h" 13 #include "SkDescriptor.h" 14 #include "SkSerialProcs.h" 15 #include "SkTHash.h" 16 #include "SkTypeface.h" 17 #include "SkTypeface_remote.h" 18 19 class SkScalerContextRecDescriptor { 20 public: SkScalerContextRecDescriptor()21 SkScalerContextRecDescriptor() {} SkScalerContextRecDescriptor(const SkScalerContextRec & rec)22 explicit SkScalerContextRecDescriptor(const SkScalerContextRec& rec) { 23 auto desc = reinterpret_cast<SkDescriptor*>(&fDescriptor); 24 desc->init(); 25 desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 26 SkASSERT(sizeof(fDescriptor) == desc->getLength()); 27 } 28 29 SkScalerContextRecDescriptor& operator=(const SkScalerContextRecDescriptor& rhs) { 30 std::memcpy(&fDescriptor, &rhs.fDescriptor, rhs.desc().getLength()); 31 return *this; 32 } 33 desc()34 const SkDescriptor& desc() const { 35 return *reinterpret_cast<const SkDescriptor*>(&fDescriptor); 36 } 37 38 struct Hash { operatorHash39 uint32_t operator()(SkScalerContextRecDescriptor const& s) const { 40 return s.desc().getChecksum(); 41 } 42 }; 43 44 friend bool operator==(const SkScalerContextRecDescriptor& lhs, 45 const SkScalerContextRecDescriptor& rhs ) { 46 return lhs.desc() == rhs.desc(); 47 } 48 49 private: 50 // The system only passes descriptors without effects. That is why it uses a fixed size 51 // descriptor. storageFor is needed because some of the constructors below are private. 52 template <typename T> 53 using storageFor = typename std::aligned_storage<sizeof(T), alignof(T)>::type; 54 struct { 55 storageFor<SkDescriptor> dummy1; 56 storageFor<SkDescriptor::Entry> dummy2; 57 storageFor<SkScalerContextRec> dummy3; 58 } fDescriptor; 59 }; 60 61 class SkRemoteGlyphCacheRenderer { 62 public: 63 void prepareSerializeProcs(SkSerialProcs* procs); 64 65 SkScalerContext* generateScalerContext( 66 const SkScalerContextRecDescriptor& desc, SkFontID typefaceId); 67 68 private: 69 sk_sp<SkData> encodeTypeface(SkTypeface* tf); 70 71 SkTHashMap<SkFontID, sk_sp<SkTypeface>> fTypefaceMap; 72 73 using DescriptorToContextMap = 74 SkTHashMap< 75 SkScalerContextRecDescriptor, 76 std::unique_ptr<SkScalerContext>, 77 SkScalerContextRecDescriptor::Hash>; 78 79 DescriptorToContextMap fScalerContextMap; 80 }; 81 82 class SkRemoteGlyphCacheGPU { 83 public: 84 explicit SkRemoteGlyphCacheGPU(std::unique_ptr<SkRemoteScalerContext> remoteScalerContext); 85 86 void prepareDeserializeProcs(SkDeserialProcs* procs); 87 88 private: 89 sk_sp<SkTypeface> decodeTypeface(const void* buf, size_t len); 90 91 std::unique_ptr<SkRemoteScalerContext> fRemoteScalerContext; 92 // TODO: Figure out how to manage the entries for the following maps. 93 SkTHashMap<SkFontID, sk_sp<SkTypefaceProxy>> fMapIdToTypeface; 94 }; 95 96 #endif // SkRemoteGlyphCache_DEFINED 97