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 "include/private/SkMacros.h" 14 #include "include/private/SkNoncopyable.h" 15 #include "src/core/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 // Assumes that getLength <= capacity of this SkDescriptor. 37 bool isValid() const; 38 39 #ifdef SK_DEBUG assertChecksum()40 void assertChecksum() const { 41 SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum); 42 } 43 #endif 44 45 const void* findEntry(uint32_t tag, uint32_t* length) const; 46 47 std::unique_ptr<SkDescriptor> copy() const; 48 49 // This assumes that all memory added has a length that is a multiple of 4. This is checked 50 // by the assert in addEntry. 51 bool operator==(const SkDescriptor& other) const; 52 bool operator!=(const SkDescriptor& other) const { return !(*this == other); } 53 getChecksum()54 uint32_t getChecksum() const { return fChecksum; } 55 56 struct Entry { 57 uint32_t fTag; 58 uint32_t fLen; 59 }; 60 61 #ifdef SK_DEBUG getCount()62 uint32_t getCount() const { return fCount; } 63 #endif 64 65 private: 66 // private so no one can create one except our factories 67 SkDescriptor() = default; 68 friend class SkDescriptorTestHelper; 69 70 static uint32_t ComputeChecksum(const SkDescriptor* desc); 71 72 uint32_t fChecksum; // must be first 73 uint32_t fLength; // must be second 74 uint32_t fCount; 75 }; 76 77 class SkAutoDescriptor { 78 public: 79 SkAutoDescriptor(); 80 explicit SkAutoDescriptor(size_t size); 81 explicit SkAutoDescriptor(const SkDescriptor& desc); 82 SkAutoDescriptor(const SkAutoDescriptor& ad); 83 SkAutoDescriptor& operator= (const SkAutoDescriptor& ad); 84 SkAutoDescriptor(SkAutoDescriptor&&) = delete; 85 SkAutoDescriptor& operator= (SkAutoDescriptor&&) = delete; 86 87 ~SkAutoDescriptor(); 88 89 void reset(size_t size); 90 void reset(const SkDescriptor& desc); getDesc()91 SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; } 92 93 private: 94 void free(); 95 static constexpr size_t kStorageSize 96 = sizeof(SkDescriptor) 97 + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec 98 + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface 99 + 32; // slop for occasional small extras 100 101 SkDescriptor* fDesc{nullptr}; 102 std::aligned_storage<kStorageSize, alignof(uint32_t)>::type fStorage; 103 }; 104 105 #endif //SkDescriptor_DEFINED 106