18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef API_RENDER_RESOURCE_HANDLE_H 178bf80f4bSopenharmony_ci#define API_RENDER_RESOURCE_HANDLE_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <cstdint> 208bf80f4bSopenharmony_ci 218bf80f4bSopenharmony_ci#include <base/containers/generic_iterator.h> 228bf80f4bSopenharmony_ci#include <base/containers/refcnt_ptr.h> 238bf80f4bSopenharmony_ci#include <core/property/property.h> 248bf80f4bSopenharmony_ci#include <render/namespace.h> 258bf80f4bSopenharmony_ci 268bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 278bf80f4bSopenharmony_ci/** \addtogroup group_resourcehandle 288bf80f4bSopenharmony_ci * @{ 298bf80f4bSopenharmony_ci */ 308bf80f4bSopenharmony_ciconstexpr const uint64_t INVALID_RESOURCE_HANDLE { 0xFFFFFFFFffffffff }; 318bf80f4bSopenharmony_ci 328bf80f4bSopenharmony_ci/** Render handle (used for various renderer and rendering related handles) */ 338bf80f4bSopenharmony_cistruct RenderHandle { 348bf80f4bSopenharmony_ci /** ID */ 358bf80f4bSopenharmony_ci uint64_t id { INVALID_RESOURCE_HANDLE }; 368bf80f4bSopenharmony_ci}; 378bf80f4bSopenharmony_ci/** @} */ 388bf80f4bSopenharmony_ci 398bf80f4bSopenharmony_ci/** Render handle equals comparison */ 408bf80f4bSopenharmony_ciinline bool operator==(const RenderHandle& lhs, const RenderHandle& rhs) noexcept 418bf80f4bSopenharmony_ci{ 428bf80f4bSopenharmony_ci return (lhs.id == rhs.id); 438bf80f4bSopenharmony_ci} 448bf80f4bSopenharmony_ci 458bf80f4bSopenharmony_ci/** Render handle not equals comparison */ 468bf80f4bSopenharmony_ciinline bool operator!=(const RenderHandle& lhs, const RenderHandle& rhs) noexcept 478bf80f4bSopenharmony_ci{ 488bf80f4bSopenharmony_ci return (lhs.id != rhs.id); 498bf80f4bSopenharmony_ci} 508bf80f4bSopenharmony_ci 518bf80f4bSopenharmony_ci/** Render handle hash */ 528bf80f4bSopenharmony_ciinline uint64_t hash(const RenderHandle& handle) 538bf80f4bSopenharmony_ci{ 548bf80f4bSopenharmony_ci return handle.id; 558bf80f4bSopenharmony_ci} 568bf80f4bSopenharmony_ci 578bf80f4bSopenharmony_ci/** Render handle types */ 588bf80f4bSopenharmony_cienum class RenderHandleType : uint8_t { 598bf80f4bSopenharmony_ci /** Undefined. */ 608bf80f4bSopenharmony_ci UNDEFINED = 0, 618bf80f4bSopenharmony_ci /** Generic data. Often just handle to specific data. */ 628bf80f4bSopenharmony_ci GENERIC_DATA = 1, 638bf80f4bSopenharmony_ci /** GPU buffer. */ 648bf80f4bSopenharmony_ci GPU_BUFFER = 2, 658bf80f4bSopenharmony_ci /** GPU image. */ 668bf80f4bSopenharmony_ci GPU_IMAGE = 3, 678bf80f4bSopenharmony_ci /** GPU buffer. */ 688bf80f4bSopenharmony_ci GPU_SAMPLER = 4, 698bf80f4bSopenharmony_ci /** Graphics pipe shader. */ 708bf80f4bSopenharmony_ci SHADER_STATE_OBJECT = 6, 718bf80f4bSopenharmony_ci /** Compute shader. */ 728bf80f4bSopenharmony_ci COMPUTE_SHADER_STATE_OBJECT = 7, 738bf80f4bSopenharmony_ci /** Pipeline layout. */ 748bf80f4bSopenharmony_ci PIPELINE_LAYOUT = 8, 758bf80f4bSopenharmony_ci /** Vertex input declaration. */ 768bf80f4bSopenharmony_ci VERTEX_INPUT_DECLARATION = 9, 778bf80f4bSopenharmony_ci /** Graphics state. */ 788bf80f4bSopenharmony_ci GRAPHICS_STATE = 10, 798bf80f4bSopenharmony_ci /** Render node graph. */ 808bf80f4bSopenharmony_ci RENDER_NODE_GRAPH = 11, 818bf80f4bSopenharmony_ci /** Graphics pso. */ 828bf80f4bSopenharmony_ci GRAPHICS_PSO = 12, 838bf80f4bSopenharmony_ci /** Compute pso. */ 848bf80f4bSopenharmony_ci COMPUTE_PSO = 13, 858bf80f4bSopenharmony_ci /** Descriptor set. */ 868bf80f4bSopenharmony_ci DESCRIPTOR_SET = 14, 878bf80f4bSopenharmony_ci}; 888bf80f4bSopenharmony_ci 898bf80f4bSopenharmony_ci/** Render handle util */ 908bf80f4bSopenharmony_cinamespace RenderHandleUtil { 918bf80f4bSopenharmony_ci/** Render handle type mask */ 928bf80f4bSopenharmony_ciconstexpr const uint64_t RENDER_HANDLE_TYPE_MASK { 0xf }; 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_ci/** Checks validity of a handle */ 958bf80f4bSopenharmony_ciinline constexpr bool IsValid(const RenderHandle handle) 968bf80f4bSopenharmony_ci{ 978bf80f4bSopenharmony_ci return (handle.id != INVALID_RESOURCE_HANDLE); 988bf80f4bSopenharmony_ci} 998bf80f4bSopenharmony_ci 1008bf80f4bSopenharmony_ci/** Returns handle type */ 1018bf80f4bSopenharmony_ciinline constexpr RenderHandleType GetHandleType(const RenderHandle handle) 1028bf80f4bSopenharmony_ci{ 1038bf80f4bSopenharmony_ci return (RenderHandleType)(handle.id & RENDER_HANDLE_TYPE_MASK); 1048bf80f4bSopenharmony_ci} 1058bf80f4bSopenharmony_ci}; // namespace RenderHandleUtil 1068bf80f4bSopenharmony_ci 1078bf80f4bSopenharmony_ciclass RenderHandleReference; 1088bf80f4bSopenharmony_ci 1098bf80f4bSopenharmony_ci/** Ref counted generic render resource counter. */ 1108bf80f4bSopenharmony_ciclass IRenderReferenceCounter { 1118bf80f4bSopenharmony_cipublic: 1128bf80f4bSopenharmony_ci using Ptr = BASE_NS::refcnt_ptr<IRenderReferenceCounter>; 1138bf80f4bSopenharmony_ci 1148bf80f4bSopenharmony_ciprotected: 1158bf80f4bSopenharmony_ci virtual void Ref() = 0; 1168bf80f4bSopenharmony_ci virtual void Unref() = 0; 1178bf80f4bSopenharmony_ci virtual int32_t GetRefCount() const = 0; 1188bf80f4bSopenharmony_ci friend Ptr; 1198bf80f4bSopenharmony_ci friend RenderHandleReference; 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_ci IRenderReferenceCounter() = default; 1228bf80f4bSopenharmony_ci virtual ~IRenderReferenceCounter() = default; 1238bf80f4bSopenharmony_ci IRenderReferenceCounter(const IRenderReferenceCounter&) = delete; 1248bf80f4bSopenharmony_ci IRenderReferenceCounter& operator=(const IRenderReferenceCounter&) = delete; 1258bf80f4bSopenharmony_ci IRenderReferenceCounter(IRenderReferenceCounter&&) = delete; 1268bf80f4bSopenharmony_ci IRenderReferenceCounter& operator=(IRenderReferenceCounter&&) = delete; 1278bf80f4bSopenharmony_ci}; 1288bf80f4bSopenharmony_ci 1298bf80f4bSopenharmony_ci/** Reference to a render handle. */ 1308bf80f4bSopenharmony_ciclass RenderHandleReference final { 1318bf80f4bSopenharmony_cipublic: 1328bf80f4bSopenharmony_ci /** Destructor releases the reference from the owner. 1338bf80f4bSopenharmony_ci */ 1348bf80f4bSopenharmony_ci ~RenderHandleReference() = default; 1358bf80f4bSopenharmony_ci 1368bf80f4bSopenharmony_ci /** Construct an empty reference. */ 1378bf80f4bSopenharmony_ci RenderHandleReference() = default; 1388bf80f4bSopenharmony_ci 1398bf80f4bSopenharmony_ci /** Copy a reference. Reference count will be increased. */ 1408bf80f4bSopenharmony_ci inline RenderHandleReference(const RenderHandleReference& other) noexcept; 1418bf80f4bSopenharmony_ci 1428bf80f4bSopenharmony_ci /** Copy a reference. Previous reference will be released and the new one aquired. */ 1438bf80f4bSopenharmony_ci inline RenderHandleReference& operator=(const RenderHandleReference& other) noexcept; 1448bf80f4bSopenharmony_ci 1458bf80f4bSopenharmony_ci /** Construct a reference for tracking the given handle. 1468bf80f4bSopenharmony_ci * @param handle referenced handle 1478bf80f4bSopenharmony_ci * @param counter owner of the referenced handle. 1488bf80f4bSopenharmony_ci */ 1498bf80f4bSopenharmony_ci inline RenderHandleReference(const RenderHandle handle, const IRenderReferenceCounter::Ptr& counter) noexcept; 1508bf80f4bSopenharmony_ci 1518bf80f4bSopenharmony_ci /** Move a reference. Moved from reference will be empty and reusable. */ 1528bf80f4bSopenharmony_ci inline RenderHandleReference(RenderHandleReference&& other) noexcept; 1538bf80f4bSopenharmony_ci 1548bf80f4bSopenharmony_ci /** Move a reference. Previous reference will be released and the moved from reference will be empty and 1558bf80f4bSopenharmony_ci * reusable. */ 1568bf80f4bSopenharmony_ci inline RenderHandleReference& operator=(RenderHandleReference&& other) noexcept; 1578bf80f4bSopenharmony_ci 1588bf80f4bSopenharmony_ci /** Check validity of the reference. 1598bf80f4bSopenharmony_ci * @return true if the reference is valid. 1608bf80f4bSopenharmony_ci */ 1618bf80f4bSopenharmony_ci inline explicit operator bool() const noexcept; 1628bf80f4bSopenharmony_ci 1638bf80f4bSopenharmony_ci /** Get raw handle. 1648bf80f4bSopenharmony_ci * @return RenderHandle. 1658bf80f4bSopenharmony_ci */ 1668bf80f4bSopenharmony_ci inline RenderHandle GetHandle() const noexcept; 1678bf80f4bSopenharmony_ci 1688bf80f4bSopenharmony_ci /** Check validity of the reference. 1698bf80f4bSopenharmony_ci * @return RenderHandleType. 1708bf80f4bSopenharmony_ci */ 1718bf80f4bSopenharmony_ci inline RenderHandleType GetHandleType() const noexcept; 1728bf80f4bSopenharmony_ci 1738bf80f4bSopenharmony_ci /** Get ref count. Return 0, if invalid. 1748bf80f4bSopenharmony_ci * @return Get reference count of render handle reference. 1758bf80f4bSopenharmony_ci */ 1768bf80f4bSopenharmony_ci inline int32_t GetRefCount() const noexcept; 1778bf80f4bSopenharmony_ci 1788bf80f4bSopenharmony_ciprivate: 1798bf80f4bSopenharmony_ci RenderHandle handle_ {}; 1808bf80f4bSopenharmony_ci IRenderReferenceCounter::Ptr counter_; 1818bf80f4bSopenharmony_ci}; 1828bf80f4bSopenharmony_ci 1838bf80f4bSopenharmony_ciRenderHandleReference::RenderHandleReference( 1848bf80f4bSopenharmony_ci const RenderHandle handle, const IRenderReferenceCounter::Ptr& counter) noexcept 1858bf80f4bSopenharmony_ci : handle_(handle), counter_(counter) 1868bf80f4bSopenharmony_ci{} 1878bf80f4bSopenharmony_ci 1888bf80f4bSopenharmony_ciRenderHandleReference::RenderHandleReference(const RenderHandleReference& other) noexcept 1898bf80f4bSopenharmony_ci : handle_(other.handle_), counter_(other.counter_) 1908bf80f4bSopenharmony_ci{} 1918bf80f4bSopenharmony_ci 1928bf80f4bSopenharmony_ciRenderHandleReference& RenderHandleReference::operator=(const RenderHandleReference& other) noexcept 1938bf80f4bSopenharmony_ci{ 1948bf80f4bSopenharmony_ci if (&other != this) { 1958bf80f4bSopenharmony_ci handle_ = other.handle_; 1968bf80f4bSopenharmony_ci counter_ = other.counter_; 1978bf80f4bSopenharmony_ci } 1988bf80f4bSopenharmony_ci return *this; 1998bf80f4bSopenharmony_ci} 2008bf80f4bSopenharmony_ci 2018bf80f4bSopenharmony_ciRenderHandleReference::RenderHandleReference(RenderHandleReference&& other) noexcept 2028bf80f4bSopenharmony_ci : handle_(BASE_NS::exchange(other.handle_, {})), counter_(BASE_NS::exchange(other.counter_, nullptr)) 2038bf80f4bSopenharmony_ci{} 2048bf80f4bSopenharmony_ci 2058bf80f4bSopenharmony_ciRenderHandleReference& RenderHandleReference::operator=(RenderHandleReference&& other) noexcept 2068bf80f4bSopenharmony_ci{ 2078bf80f4bSopenharmony_ci if (&other != this) { 2088bf80f4bSopenharmony_ci handle_ = BASE_NS::exchange(other.handle_, {}); 2098bf80f4bSopenharmony_ci counter_ = BASE_NS::exchange(other.counter_, nullptr); 2108bf80f4bSopenharmony_ci } 2118bf80f4bSopenharmony_ci return *this; 2128bf80f4bSopenharmony_ci} 2138bf80f4bSopenharmony_ci 2148bf80f4bSopenharmony_ciRenderHandleReference::operator bool() const noexcept 2158bf80f4bSopenharmony_ci{ 2168bf80f4bSopenharmony_ci return (handle_.id != INVALID_RESOURCE_HANDLE) && (counter_); 2178bf80f4bSopenharmony_ci} 2188bf80f4bSopenharmony_ci 2198bf80f4bSopenharmony_ciRenderHandle RenderHandleReference::GetHandle() const noexcept 2208bf80f4bSopenharmony_ci{ 2218bf80f4bSopenharmony_ci return handle_; 2228bf80f4bSopenharmony_ci} 2238bf80f4bSopenharmony_ci 2248bf80f4bSopenharmony_ciRenderHandleType RenderHandleReference::GetHandleType() const noexcept 2258bf80f4bSopenharmony_ci{ 2268bf80f4bSopenharmony_ci return RenderHandleUtil::GetHandleType(handle_); 2278bf80f4bSopenharmony_ci} 2288bf80f4bSopenharmony_ci 2298bf80f4bSopenharmony_ciint32_t RenderHandleReference::GetRefCount() const noexcept 2308bf80f4bSopenharmony_ci{ 2318bf80f4bSopenharmony_ci if (counter_) { 2328bf80f4bSopenharmony_ci return counter_->GetRefCount(); 2338bf80f4bSopenharmony_ci } else { 2348bf80f4bSopenharmony_ci return 0u; 2358bf80f4bSopenharmony_ci } 2368bf80f4bSopenharmony_ci} 2378bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 2388bf80f4bSopenharmony_ci 2398bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE() 2408bf80f4bSopenharmony_cinamespace PropertyType { 2418bf80f4bSopenharmony_ciinline constexpr PropertyTypeDecl RENDER_HANDLE_T = PROPERTYTYPE(RENDER_NS::RenderHandle); 2428bf80f4bSopenharmony_ciinline constexpr PropertyTypeDecl RENDER_HANDLE_ARRAY_T = PROPERTYTYPE_ARRAY(RENDER_NS::RenderHandle); 2438bf80f4bSopenharmony_ciinline constexpr PropertyTypeDecl RENDER_HANDLE_REFERENCE_T = PROPERTYTYPE(RENDER_NS::RenderHandleReference); 2448bf80f4bSopenharmony_ciinline constexpr PropertyTypeDecl RENDER_HANDLE_REFERENCE_ARRAY_T = 2458bf80f4bSopenharmony_ci PROPERTYTYPE_ARRAY(RENDER_NS::RenderHandleReference); 2468bf80f4bSopenharmony_ci} // namespace PropertyType 2478bf80f4bSopenharmony_ci#ifdef DECLARE_PROPERTY_TYPE 2488bf80f4bSopenharmony_ciDECLARE_PROPERTY_TYPE(RENDER_NS::RenderHandle); 2498bf80f4bSopenharmony_ciDECLARE_PROPERTY_TYPE(RENDER_NS::RenderHandleReference); 2508bf80f4bSopenharmony_ci#endif 2518bf80f4bSopenharmony_ciCORE_END_NAMESPACE() 2528bf80f4bSopenharmony_ci#endif // API_RENDER_RESOURCE_HANDLE_H 253