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