1 /* 2 * Copyright 2006 The Android Open Source Project 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 SkDescriptor_DEFINED 9 #define SkDescriptor_DEFINED 10 11 #include <memory> 12 13 #include "SkMacros.h" 14 #include "SkNoncopyable.h" 15 #include "SkScalerContext.h" 16 17 class SkDescriptor : SkNoncopyable { 18 public: ComputeOverhead(int entryCount)19 static size_t ComputeOverhead(int entryCount) { 20 SkASSERT(entryCount >= 0); 21 return sizeof(SkDescriptor) + entryCount * sizeof(Entry); 22 } 23 24 static std::unique_ptr<SkDescriptor> Alloc(size_t length); 25 26 // Ensure the unsized delete is called. 27 void operator delete(void* p); init()28 void init() { 29 fLength = sizeof(SkDescriptor); 30 fCount = 0; 31 } getLength()32 uint32_t getLength() const { return fLength; } 33 void* addEntry(uint32_t tag, size_t length, const void* data = nullptr); 34 void computeChecksum(); 35 36 #ifdef SK_DEBUG assertChecksum()37 void assertChecksum() const { 38 SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum); 39 } 40 #endif 41 42 const void* findEntry(uint32_t tag, uint32_t* length) const; 43 44 std::unique_ptr<SkDescriptor> copy() const; 45 46 // This assumes that all memory added has a length that is a multiple of 4. This is checked 47 // by the assert in addEntry. 48 bool operator==(const SkDescriptor& other) const; 49 bool operator!=(const SkDescriptor& other) const { return !(*this == other); } 50 getChecksum()51 uint32_t getChecksum() const { return fChecksum; } 52 53 struct Entry { 54 uint32_t fTag; 55 uint32_t fLen; 56 }; 57 58 #ifdef SK_DEBUG getCount()59 uint32_t getCount() const { return fCount; } 60 #endif 61 62 private: 63 // private so no one can create one except our factories 64 SkDescriptor() = default; 65 66 static uint32_t ComputeChecksum(const SkDescriptor* desc); 67 68 uint32_t fChecksum; // must be first 69 uint32_t fLength; // must be second 70 uint32_t fCount; 71 }; 72 73 class SkAutoDescriptor : SkNoncopyable { 74 public: 75 SkAutoDescriptor(); 76 SkAutoDescriptor(size_t size); 77 SkAutoDescriptor(const SkDescriptor& desc); 78 SkAutoDescriptor(SkAutoDescriptor&&) = delete; 79 SkAutoDescriptor& operator =(SkAutoDescriptor&&) = delete; 80 81 ~SkAutoDescriptor(); 82 83 void reset(size_t size); 84 void reset(const SkDescriptor& desc); getDesc()85 SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; } 86 87 private: 88 void free(); 89 static constexpr size_t kStorageSize 90 = sizeof(SkDescriptor) 91 + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec 92 + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface 93 + 32; // slop for occasional small extras 94 95 SkDescriptor* fDesc{nullptr}; 96 std::aligned_storage<kStorageSize, alignof(uint32_t)>::type fStorage; 97 }; 98 99 #endif //SkDescriptor_DEFINED 100