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