Home | History | Annotate | Download | only in core
      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:
     21     SkScalerContextRecDescriptor() {}
     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 
     34     const SkDescriptor& desc() const {
     35         return *reinterpret_cast<const SkDescriptor*>(&fDescriptor);
     36     }
     37 
     38     struct Hash {
     39         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