/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkRemoteGlyphCache_DEFINED #define SkRemoteGlyphCache_DEFINED #include <memory> #include "SkData.h" #include "SkDescriptor.h" #include "SkSerialProcs.h" #include "SkTHash.h" #include "SkTypeface.h" #include "SkTypeface_remote.h" class SkScalerContextRecDescriptor { public: SkScalerContextRecDescriptor() {} explicit SkScalerContextRecDescriptor(const SkScalerContextRec& rec) { auto desc = reinterpret_cast<SkDescriptor*>(&fDescriptor); desc->init(); desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); SkASSERT(sizeof(fDescriptor) == desc->getLength()); } SkScalerContextRecDescriptor& operator=(const SkScalerContextRecDescriptor& rhs) { std::memcpy(&fDescriptor, &rhs.fDescriptor, rhs.desc().getLength()); return *this; } const SkDescriptor& desc() const { return *reinterpret_cast<const SkDescriptor*>(&fDescriptor); } struct Hash { uint32_t operator()(SkScalerContextRecDescriptor const& s) const { return s.desc().getChecksum(); } }; friend bool operator==(const SkScalerContextRecDescriptor& lhs, const SkScalerContextRecDescriptor& rhs ) { return lhs.desc() == rhs.desc(); } private: // The system only passes descriptors without effects. That is why it uses a fixed size // descriptor. storageFor is needed because some of the constructors below are private. template <typename T> using storageFor = typename std::aligned_storage<sizeof(T), alignof(T)>::type; struct { storageFor<SkDescriptor> dummy1; storageFor<SkDescriptor::Entry> dummy2; storageFor<SkScalerContextRec> dummy3; } fDescriptor; }; class SkRemoteGlyphCacheRenderer { public: void prepareSerializeProcs(SkSerialProcs* procs); SkScalerContext* generateScalerContext( const SkScalerContextRecDescriptor& desc, SkFontID typefaceId); private: sk_sp<SkData> encodeTypeface(SkTypeface* tf); SkTHashMap<SkFontID, sk_sp<SkTypeface>> fTypefaceMap; using DescriptorToContextMap = SkTHashMap< SkScalerContextRecDescriptor, std::unique_ptr<SkScalerContext>, SkScalerContextRecDescriptor::Hash>; DescriptorToContextMap fScalerContextMap; }; class SkRemoteGlyphCacheGPU { public: explicit SkRemoteGlyphCacheGPU(std::unique_ptr<SkRemoteScalerContext> remoteScalerContext); void prepareDeserializeProcs(SkDeserialProcs* procs); private: sk_sp<SkTypeface> decodeTypeface(const void* buf, size_t len); std::unique_ptr<SkRemoteScalerContext> fRemoteScalerContext; // TODO: Figure out how to manage the entries for the following maps. SkTHashMap<SkFontID, sk_sp<SkTypefaceProxy>> fMapIdToTypeface; }; #endif // SkRemoteGlyphCache_DEFINED