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 RENDER_CONTEXT_H
17 #define RENDER_CONTEXT_H
18 
19 #include <cstdint>
20 
21 #include <base/containers/string.h>
22 #include <base/containers/unique_ptr.h>
23 #include <base/containers/unordered_map.h>
24 #include <core/ecs/intf_component_manager.h>
25 #include <core/namespace.h>
26 #include <core/plugin/intf_plugin.h>
27 #include <render/implementation_uids.h>
28 #include <render/intf_render_context.h>
29 #include <render/namespace.h>
30 #include <render/resource_handle.h>
31 
32 #include "loader/render_data_configuration_loader.h"
33 #include "nodecontext/render_node_post_process_util.h"
34 
35 CORE_BEGIN_NAMESPACE()
36 class IEngine;
37 class IFileManager;
38 CORE_END_NAMESPACE()
39 
40 RENDER_BEGIN_NAMESPACE()
41 class Device;
42 class Renderer;
43 class RenderDataStoreManager;
44 class RenderNodeManager;
45 class RenderNodeGraphManager;
46 class RenderNodeGraphLoader;
47 class RenderUtil;
48 
49 class IDevice;
50 class IRenderer;
51 class IRenderDataStoreManager;
52 class IRenderNodeGraphManager;
53 class IRenderUtil;
54 
55 struct RenderPluginState;
56 struct IRenderPlugin;
57 
58 class RenderContext final : public IRenderContext,
59                             public CORE_NS::IClassRegister,
60                             CORE_NS::IPluginRegister::ITypeInfoListener {
61 public:
62     RenderContext(RenderPluginState& pluginState, CORE_NS::IEngine& engine);
63     ~RenderContext() override;
64 
65     /** Init, create device for render use.
66      *  @param createInfo Device creation info.
67      */
68     RenderResultCode Init(const RenderCreateInfo& createInfo) override;
69 
70     /** Get active device. */
71     IDevice& GetDevice() const override;
72     /** Get rendererer */
73     IRenderer& GetRenderer() const override;
74     /** Get render node graph manager */
75     IRenderNodeGraphManager& GetRenderNodeGraphManager() const override;
76     /** Get render data store manager */
77     IRenderDataStoreManager& GetRenderDataStoreManager() const override;
78 
79     /** Get render utilities */
80     IRenderUtil& GetRenderUtil() const override;
81 
82     CORE_NS::IEngine& GetEngine() const override;
83 
84     BASE_NS::string_view GetVersion() override;
85 
86     RenderCreateInfo GetCreateInfo() const;
87 
88     // IInterface
89     const IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
90     IInterface* GetInterface(const BASE_NS::Uid& uid) override;
91     void Ref() override;
92     void Unref() override;
93 
94     // IClassFactory
95     IInterface::Ptr CreateInstance(const BASE_NS::Uid& uid) override;
96 
97     // IClassRegister
98     void RegisterInterfaceType(const CORE_NS::InterfaceTypeInfo& interfaceInfo) override;
99     void UnregisterInterfaceType(const CORE_NS::InterfaceTypeInfo& interfaceInfo) override;
100     BASE_NS::array_view<const CORE_NS::InterfaceTypeInfo* const> GetInterfaceMetadata() const override;
101     const CORE_NS::InterfaceTypeInfo& GetInterfaceMetadata(const BASE_NS::Uid& uid) const override;
102     IInterface* GetInstance(const BASE_NS::Uid& uid) const override;
103 
104 private:
105     // IPluginRegister::ITypeInfoListener
106     void OnTypeInfoEvent(EventType type, BASE_NS::array_view<const CORE_NS::ITypeInfo* const> typeInfos) override;
107 
108     void RegisterDefaultPaths();
109     BASE_NS::unique_ptr<Device> CreateDevice(const DeviceCreateInfo& createInfo);
110 
111     RenderPluginState& pluginState_;
112     CORE_NS::IEngine& engine_;
113     CORE_NS::IFileManager* fileManager_ { nullptr };
114     BASE_NS::unique_ptr<Device> device_;
115     BASE_NS::unique_ptr<RenderDataStoreManager> renderDataStoreMgr_;
116     BASE_NS::unique_ptr<RenderNodeGraphManager> renderNodeGraphMgr_;
117     BASE_NS::unique_ptr<Renderer> renderer_;
118     BASE_NS::unique_ptr<RenderUtil> renderUtil_;
119     RenderDataConfigurationLoaderImpl renderDataConfigurationLoader_;
120 
121     CORE_NS::InterfaceTypeInfo interfaceInfos_[2U] {
122         CORE_NS::InterfaceTypeInfo {
123             this,
124             UID_RENDER_DATA_CONFIGURATION_LOADER,
125             CORE_NS::GetName<IRenderDataConfigurationLoader>().data(),
126             {}, // nullptr for CreateInstance
127             [](CORE_NS::IClassRegister& registry, CORE_NS::PluginToken token) -> CORE_NS::IInterface* {
128                 if (token) {
129                     return &(static_cast<RenderContext*>(token)->renderDataConfigurationLoader_);
130                 }
131                 return nullptr;
132             },
133         },
134         CORE_NS::InterfaceTypeInfo {
135             this, UID_RENDER_NODE_POST_PROCESS_UTIL, CORE_NS::GetName<IRenderNodePostProcessUtil>().data(),
136             [](CORE_NS::IClassFactory&, CORE_NS::PluginToken token) -> CORE_NS::IInterface* {
137                 if (token) {
138                     return new RenderNodePostProcessUtilImpl();
139                 }
140                 return nullptr;
141             },
142             nullptr, // nullptr for GetInstance
143         },
144     };
145 
146     uint32_t refCount_ { 0 };
147 
148     BASE_NS::vector<BASE_NS::pair<CORE_NS::PluginToken, const IRenderPlugin*>> plugins_;
149     BASE_NS::vector<const CORE_NS::InterfaceTypeInfo*> interfaceTypeInfos_;
150 
151     BASE_NS::vector<RenderHandleReference> defaultGpuResources_;
152 
153     RenderCreateInfo createInfo_ {};
154 };
155 
156 struct RenderPluginState {
157     CORE_NS::IEngine& engine_;
158     IRenderContext::Ptr context_;
159     CORE_NS::InterfaceTypeInfo interfaceInfo_ {
160         this,
161         UID_RENDER_CONTEXT,
162         CORE_NS::GetName<IRenderContext>().data(),
163         [](CORE_NS::IClassFactory& factory, CORE_NS::PluginToken token) -> CORE_NS::IInterface* {
164             if (token) {
165                 auto state = static_cast<RenderPluginState*>(token);
166                 return static_cast<RenderPluginState*>(token)->CreateInstance(state->engine_);
167             }
168             return nullptr;
169         },
170         [](CORE_NS::IClassRegister& registry, CORE_NS::PluginToken token) -> CORE_NS::IInterface* {
171             if (token) {
172                 return static_cast<RenderPluginState*>(token)->GetInstance();
173             }
174             return nullptr;
175         },
176     };
177 
178     IRenderContext* CreateInstance(CORE_NS::IEngine& engine);
179     IRenderContext* GetInstance();
180     void Destroy();
181 };
182 RENDER_END_NAMESPACE()
183 
184 #endif // RENDER_CONTEXT_H
185