/* * 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 #include #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(&fDescriptor); desc->init(); desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); desc->computeChecksum(); SkASSERT(sizeof(fDescriptor) == desc->getLength()); } explicit SkScalerContextRecDescriptor(const SkDescriptor& desc) : SkScalerContextRecDescriptor(ExtractRec(desc)) { } SkScalerContextRecDescriptor& operator=(const SkScalerContextRecDescriptor& rhs) { std::memcpy(&fDescriptor, &rhs.fDescriptor, rhs.desc().getLength()); return *this; } const SkDescriptor& desc() const { return *reinterpret_cast(&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: static SkScalerContextRec ExtractRec(const SkDescriptor& desc) { uint32_t size; auto recPtr = desc.findEntry(kRec_SkDescriptorTag, &size); SkScalerContextRec result; std::memcpy(&result, recPtr, size); return result; } // 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 using storageFor = typename std::aligned_storage::type; struct { storageFor dummy1; storageFor dummy2; storageFor dummy3; } fDescriptor; }; class SkRemoteGlyphCacheRenderer { public: void prepareSerializeProcs(SkSerialProcs* procs); SkScalerContext* generateScalerContext( const SkScalerContextRecDescriptor& desc, SkFontID typefaceId); private: sk_sp encodeTypeface(SkTypeface* tf); SkTHashMap> fTypefaceMap; using DescriptorToContextMap = SkTHashMap, SkScalerContextRecDescriptor::Hash>; DescriptorToContextMap fScalerContextMap; }; class SkRemoteGlyphCacheGPU { public: explicit SkRemoteGlyphCacheGPU(std::unique_ptr remoteScalerContext); void prepareDeserializeProcs(SkDeserialProcs* procs); SkTypeface* lookupTypeface(SkFontID id); private: sk_sp decodeTypeface(const void* buf, size_t len); std::unique_ptr fRemoteScalerContext; // TODO: Figure out how to manage the entries for the following maps. SkTHashMap> fMapIdToTypeface; }; #endif // SkRemoteGlyphCache_DEFINED