• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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