1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef API_RENDER_RESOURCE_HANDLE_H
17 #define API_RENDER_RESOURCE_HANDLE_H
18
19 #include <cstdint>
20
21 #include <base/containers/generic_iterator.h>
22 #include <base/containers/refcnt_ptr.h>
23 #include <base/containers/string.h>
24 #include <core/property/property.h>
25 #include <render/namespace.h>
26
RENDER_BEGIN_NAMESPACE()27 RENDER_BEGIN_NAMESPACE()
28 /** \addtogroup group_resourcehandle
29 * @{
30 */
31 constexpr const uint64_t INVALID_RESOURCE_HANDLE { 0xFFFFFFFFffffffff };
32
33 /** Render handle (used for various renderer and rendering related handles) */
34 struct RenderHandle {
35 /** ID */
36 uint64_t id { INVALID_RESOURCE_HANDLE };
37 };
38 /** @} */
39
40 /** Render handle equals comparison */
41 inline bool operator==(const RenderHandle& lhs, const RenderHandle& rhs) noexcept
42 {
43 return (lhs.id == rhs.id);
44 }
45
46 /** Render handle not equals comparison */
47 inline bool operator!=(const RenderHandle& lhs, const RenderHandle& rhs) noexcept
48 {
49 return (lhs.id != rhs.id);
50 }
51
52 /** Render handle hash */
hash(const RenderHandle & handle)53 inline uint64_t hash(const RenderHandle& handle)
54 {
55 return handle.id;
56 }
57
58 /** Render handle types */
59 enum class RenderHandleType : uint8_t {
60 /** Undefined. */
61 UNDEFINED = 0,
62 /** Generic data. Often just handle to specific data. */
63 GENERIC_DATA = 1,
64 /** GPU buffer. */
65 GPU_BUFFER = 2,
66 /** GPU image. */
67 GPU_IMAGE = 3,
68 /** GPU buffer. */
69 GPU_SAMPLER = 4,
70 /** Graphics pipe shader. */
71 SHADER_STATE_OBJECT = 6,
72 /** Compute shader. */
73 COMPUTE_SHADER_STATE_OBJECT = 7,
74 /** Pipeline layout. */
75 PIPELINE_LAYOUT = 8,
76 /** Vertex input declaration. */
77 VERTEX_INPUT_DECLARATION = 9,
78 /** Graphics state. */
79 GRAPHICS_STATE = 10,
80 /** Render node graph. */
81 RENDER_NODE_GRAPH = 11,
82 /** Graphics pso. */
83 GRAPHICS_PSO = 12,
84 /** Compute pso. */
85 COMPUTE_PSO = 13,
86 /** Descriptor set. */
87 DESCRIPTOR_SET = 14,
88 };
89
90 /** Render handle util */
91 namespace RenderHandleUtil {
92 /** Render handle type mask */
93 constexpr const uint64_t RENDER_HANDLE_TYPE_MASK { 0xf };
94
95 /** Checks validity of a handle */
IsValid(const RenderHandle handle)96 inline bool IsValid(const RenderHandle handle)
97 {
98 return (handle.id != INVALID_RESOURCE_HANDLE);
99 }
100
101 /** Returns handle type */
GetHandleType(const RenderHandle handle)102 inline RenderHandleType GetHandleType(const RenderHandle handle)
103 {
104 return (RenderHandleType)(handle.id & RENDER_HANDLE_TYPE_MASK);
105 }
106 }; // namespace RenderHandleUtil
107
108 class RenderHandleReference;
109
110 /** Ref counted generic render resource counter. */
111 class IRenderReferenceCounter {
112 public:
113 using Ptr = BASE_NS::refcnt_ptr<IRenderReferenceCounter>;
114
115 protected:
116 virtual void Ref() = 0;
117 virtual void Unref() = 0;
118 virtual int32_t GetRefCount() const = 0;
119 friend Ptr;
120 friend RenderHandleReference;
121
122 IRenderReferenceCounter() = default;
123 virtual ~IRenderReferenceCounter() = default;
124 IRenderReferenceCounter(const IRenderReferenceCounter&) = delete;
125 IRenderReferenceCounter& operator=(const IRenderReferenceCounter&) = delete;
126 IRenderReferenceCounter(IRenderReferenceCounter&&) = delete;
127 IRenderReferenceCounter& operator=(IRenderReferenceCounter&&) = delete;
128 };
129
130 /** Reference to a render handle. */
131 class RenderHandleReference final {
132 public:
133 /** Destructor releases the reference from the owner.
134 */
135 ~RenderHandleReference() = default;
136
137 /** Construct an empty reference. */
138 RenderHandleReference() = default;
139
140 /** Copy a reference. Reference count will be increased. */
141 inline RenderHandleReference(const RenderHandleReference& other) noexcept;
142
143 /** Copy a reference. Previous reference will be released and the new one aquired. */
144 inline RenderHandleReference& operator=(const RenderHandleReference& other) noexcept;
145
146 /** Construct a reference for tracking the given handle.
147 * @param handle referenced handle
148 * @param counter owner of the referenced handle.
149 */
150 inline RenderHandleReference(const RenderHandle handle, const IRenderReferenceCounter::Ptr& counter) noexcept;
151
152 /** Move a reference. Moved from reference will be empty and reusable. */
153 inline RenderHandleReference(RenderHandleReference&& other) noexcept;
154
155 /** Move a reference. Previous reference will be released and the moved from reference will be empty and
156 * reusable. */
157 inline RenderHandleReference& operator=(RenderHandleReference&& other) noexcept;
158
159 /** Check validity of the reference.
160 * @return true if the reference is valid.
161 */
162 inline explicit operator bool() const noexcept;
163
164 /** Get raw handle.
165 * @return RenderHandle.
166 */
167 inline RenderHandle GetHandle() const noexcept;
168
169 /** Check validity of the reference.
170 * @return RenderHandleType.
171 */
172 inline RenderHandleType GetHandleType() const noexcept;
173
174 /** Get ref count. Return 0, if invalid.
175 * @return Get reference count of render handle reference.
176 */
177 inline int32_t GetRefCount() const noexcept;
178
179 private:
180 RenderHandle handle_ {};
181 IRenderReferenceCounter::Ptr counter_;
182 };
183
RenderHandleReference(const RenderHandle handle,const IRenderReferenceCounter::Ptr & counter)184 RenderHandleReference::RenderHandleReference(
185 const RenderHandle handle, const IRenderReferenceCounter::Ptr& counter) noexcept
186 : handle_(handle), counter_(counter)
187 {}
188
RenderHandleReference(const RenderHandleReference & other)189 RenderHandleReference::RenderHandleReference(const RenderHandleReference& other) noexcept
190 : handle_(other.handle_), counter_(other.counter_)
191 {}
192
193 RenderHandleReference& RenderHandleReference::operator=(const RenderHandleReference& other) noexcept
194 {
195 if (&other != this) {
196 handle_ = other.handle_;
197 counter_ = other.counter_;
198 }
199 return *this;
200 }
201
RenderHandleReference(RenderHandleReference && other)202 RenderHandleReference::RenderHandleReference(RenderHandleReference&& other) noexcept
203 : handle_(BASE_NS::exchange(other.handle_, {})), counter_(BASE_NS::exchange(other.counter_, nullptr))
204 {}
205
206 RenderHandleReference& RenderHandleReference::operator=(RenderHandleReference&& other) noexcept
207 {
208 if (&other != this) {
209 handle_ = BASE_NS::exchange(other.handle_, {});
210 counter_ = BASE_NS::exchange(other.counter_, nullptr);
211 }
212 return *this;
213 }
214
215 RenderHandleReference::operator bool() const noexcept
216 {
217 return (handle_.id != INVALID_RESOURCE_HANDLE) && (counter_);
218 }
219
GetHandle()220 RenderHandle RenderHandleReference::GetHandle() const noexcept
221 {
222 return handle_;
223 }
224
GetHandleType()225 RenderHandleType RenderHandleReference::GetHandleType() const noexcept
226 {
227 return RenderHandleUtil::GetHandleType(handle_);
228 }
229
GetRefCount()230 int32_t RenderHandleReference::GetRefCount() const noexcept
231 {
232 if (counter_) {
233 return counter_->GetRefCount();
234 } else {
235 return 0u;
236 }
237 }
238
239 /** Render handle description */
240 struct RenderHandleDesc {
241 /** Type */
242 RenderHandleType type { RenderHandleType::UNDEFINED };
243 /** Additional ID */
244 uint64_t id { 0 };
245 /** Reference count for this handle as seen from the client side */
246 int32_t refCount { 0 };
247 /** Name and/or path of the resource */
248 BASE_NS::string name;
249 /** Additional name of the resource */
250 BASE_NS::string additionalName;
251 };
252
253 RENDER_END_NAMESPACE()
254
CORE_BEGIN_NAMESPACE()255 CORE_BEGIN_NAMESPACE()
256 namespace PropertyType {
257 inline constexpr PropertyTypeDecl RENDER_HANDLE_T = PROPERTYTYPE(RENDER_NS::RenderHandle);
258 inline constexpr PropertyTypeDecl RENDER_HANDLE_ARRAY_T = PROPERTYTYPE_ARRAY(RENDER_NS::RenderHandle);
259 inline constexpr PropertyTypeDecl RENDER_HANDLE_REFERENCE_T = PROPERTYTYPE(RENDER_NS::RenderHandleReference);
260 inline constexpr PropertyTypeDecl RENDER_HANDLE_REFERENCE_ARRAY_T =
261 PROPERTYTYPE_ARRAY(RENDER_NS::RenderHandleReference);
262 } // namespace PropertyType
263 #ifdef DECLARE_PROPERTY_TYPE
264 DECLARE_PROPERTY_TYPE(RENDER_NS::RenderHandle);
265 DECLARE_PROPERTY_TYPE(RENDER_NS::RenderHandleReference);
266 #endif
267 CORE_END_NAMESPACE()
268 #endif // API_RENDER_RESOURCE_HANDLE_H
269