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