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