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