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 #include <core/intf_engine.h>
17 #include <core/ecs/intf_ecs.h>
18 #include <core/ecs/intf_system.h>
19 #include <core/ecs/intf_component_manager.h>
20 #include <core/io/intf_file_manager.h>
21 #include <core/plugin/intf_plugin.h>
22 #include <core/plugin/intf_plugin_decl.h>
23 #include <render/implementation_uids.h>
24 #include <render/intf_render_context.h>
25 #include <render/device/intf_shader_manager.h>
26 #include <render/datastore/intf_render_data_store_manager.h>
27 #include <render/datastore/intf_render_data_store_pod.h>
28 #include <render/intf_plugin.h>
29 
30 #include <3d/implementation_uids.h>
31 #include <3d/ecs/components/transform_component.h>
32 #include <3d/ecs/systems/intf_render_system.h>
33 
34 #include "dotfield/implementation_uids.h"
35 #include "dotfield/ecs/components/dotfield_component.h"
36 #include "dotfield/ecs/systems/dotfield_system.h"
37 #include "dotfield/render/intf_render_data_store_default_dotfield.h"
38 
39 #include "render/render_node_dotfield_render.h"
40 #include "render/render_node_dotfield_simulation.h"
41 #include "render/render_data_store_default_dotfield.h"
42 
43 // Rofs Data.
44 extern "C" const void* const DOTFIELD_BIN[];
45 extern "C" const uint64_t DOTFIELD_BIN_SIZE;
46 
47 CORE_BEGIN_NAMESPACE()
48 #if defined(CORE_PLUGIN) && (CORE_PLUGIN == 1)
49 IPluginRegister* gPluginRegistry{ nullptr };
GetPluginRegister()50 IPluginRegister& GetPluginRegister()
51 {
52     return *gPluginRegistry;
53 }
54 #endif
55 CORE_END_NAMESPACE()
56 
57 namespace {
58 static constexpr RENDER_NS::IShaderManager::ShaderFilePathDesc SHADER_FILE_PATHS{
59     "dotfieldshaders://",
60     "dotfieldshaderstates://",
61     "dotfieldpipelinelayouts://",
62     "dotfieldvertexinputdeclarations://",
63 };
64 }
65 
66 namespace Dotfield {
67 using CORE_NS::GetName;
68 using namespace BASE_NS;
69 using namespace CORE_NS;
70 using namespace RENDER_NS;
71 using namespace CORE3D_NS;
72 
73 const char* GetVersionInfo();
74 
75 constexpr string_view ROFS = "dotfieldrofs";
76 constexpr string_view SHADERS = "dotfieldshaders";
77 constexpr string_view VIDS = "dotfieldvertexinputdeclarations";
78 constexpr string_view PIDS = "dotfieldpipelinelayouts";
79 constexpr string_view SSTATES = "dotfieldshaderstates";
80 
81 constexpr string_view SHADER_PATH = "dotfieldrofs://shaders/";
82 constexpr string_view VID_PATH = "dotfieldrofs://vertexinputdeclarations/";
83 constexpr string_view PID_PATH = "dotfieldrofs://pipelinelayouts/";
84 constexpr string_view SHADER_STATE_PATH = "dotfieldrofs://shaderstates/";
85 
86 constexpr BASE_NS::Uid PLUGIN_DEPENDENCIES[] = { RENDER_NS::UID_RENDER_PLUGIN, CORE3D_NS::UID_3D_PLUGIN };
87 
88 IComponentManager* IDotfieldComponentManagerInstance(IEcs&);
89 ISystem* IDotfieldSystemInstance(IEcs&);
90 
91 void IDotfieldComponentManagerDestroy(IComponentManager*);
92 void IDotfieldSystemDestroy(ISystem*);
93 
94 constexpr RenderDataStoreTypeInfo RenderDataDefaultDotfieldTypeInfo = {
95     RenderDataStoreTypeInfo::UID,
96     RenderDataStoreDefaultDotfield::UID,
97     RenderDataStoreDefaultDotfield::TYPE_NAME,
98     RenderDataStoreDefaultDotfield::Create,
99     RenderDataStoreDefaultDotfield::Destroy,
100 };
101 
102 constexpr RenderDataStoreTypeInfo gRenderDataStores[] = {
103     RenderDataDefaultDotfieldTypeInfo,
104 };
105 
106 constexpr RenderNodeTypeInfo RenderNodeDotfieldSimulationTypeInfo = {
107     RenderNodeTypeInfo::UID,
108     RenderNodeDotfieldSimulation::UID,
109     RenderNodeDotfieldSimulation::TYPE_NAME,
110     RenderNodeDotfieldSimulation::Create,
111     RenderNodeDotfieldSimulation::Destroy,
112     RenderNodeDotfieldSimulation::BACKEND_FLAGS,
113     RenderNodeDotfieldSimulation::CLASS_TYPE,
114 };
115 
116 constexpr RenderNodeTypeInfo RenderNodeDotfieldRenderTypeInfo = {
117     RenderNodeTypeInfo::UID,
118     RenderNodeDotfieldRender::UID,
119     RenderNodeDotfieldRender::TYPE_NAME,
120     RenderNodeDotfieldRender::Create,
121     RenderNodeDotfieldRender::Destroy,
122     RenderNodeDotfieldRender::BACKEND_FLAGS,
123     RenderNodeDotfieldRender::CLASS_TYPE,
124 };
125 
126 constexpr RenderNodeTypeInfo gRenderNodes[] = {
127     RenderNodeDotfieldSimulationTypeInfo,
128     RenderNodeDotfieldRenderTypeInfo,
129 };
130 
131 constexpr ComponentManagerTypeInfo DotfieldComponentTypeInfo = {
132     ComponentManagerTypeInfo::UID,
133     IDotfieldComponentManager::UID,
134     GetName<IDotfieldComponentManager>().data(),
135     IDotfieldComponentManagerInstance,
136     IDotfieldComponentManagerDestroy,
137 };
138 
139 constexpr ComponentManagerTypeInfo gComponentManagers[] = { DotfieldComponentTypeInfo };
140 
141 constexpr Uid DotfieldSourceSystemRDeps[] = {
142     ITransformComponentManager::UID,
143     IDotfieldComponentManager::UID,
144 };
145 
146 constexpr SystemTypeInfo gSystems[] = {
147     {
148         SystemTypeInfo::UID,
149         IDotfieldSystem::UID,
150         GetName<IDotfieldSystem>().data(),
151         IDotfieldSystemInstance,
152         IDotfieldSystemDestroy,
153         {},
154         DotfieldSourceSystemRDeps,
155     },
156 };
157 
GetRenderDataStores()158 array_view<const RenderDataStoreTypeInfo> GetRenderDataStores()
159 {
160     return gRenderDataStores;
161 }
162 
GetRenderNodes()163 array_view<const RenderNodeTypeInfo> GetRenderNodes()
164 {
165     return gRenderNodes;
166 }
167 
GetComponentManagers()168 array_view<const ComponentManagerTypeInfo> GetComponentManagers()
169 {
170     return gComponentManagers;
171 }
172 
GetSystems()173 array_view<const SystemTypeInfo> GetSystems()
174 {
175     return gSystems;
176 }
177 
Initialize(IRenderContext& context)178 PluginToken Initialize(IRenderContext& context)
179 {
180     auto& fm = context.GetEngine().GetFileManager();
181     // Create dotfieldrofs:// filesystem that points to embedded asset files.
182 
183     auto rofs = fm.CreateROFilesystem(DOTFIELD_BIN, DOTFIELD_BIN_SIZE);
184 
185     fm.RegisterFilesystem(ROFS, move(rofs));
186     // And register it under the needed proxy protocols.
187     fm.RegisterPath(SHADERS, SHADER_PATH, false);
188     fm.RegisterPath(VIDS, VID_PATH, false);
189     fm.RegisterPath(PIDS, PID_PATH, false);
190     fm.RegisterPath(SSTATES, SHADER_STATE_PATH, false);
191 
192     auto& renderDataStoreManager = context.GetRenderDataStoreManager();
193     renderDataStoreManager.Create(IRenderDataStoreDefaultDotfield::UID, "RenderDataStoreDefaultDotfield");
194 
195     {
196         IRenderDataStorePod* rsp =
197             static_cast<IRenderDataStorePod*>(renderDataStoreManager.Create(IRenderDataStorePod::UID, "DotfieldPodStore"));
198         if (rsp) {
199             struct {
200                 Math::Vec4 texSizeInvTexSize{ 2.f, 2.f, 1.f / 2.f, 1.f / 2.f };
201             } config;
202             rsp->CreatePod("TexSizeConfig", "TexSizeShaderConfig", arrayviewU8(config));
203         }
204     }
205 
206     context.GetDevice().GetShaderManager().LoadShaderFiles(SHADER_FILE_PATHS);
207     return &context;
208 }
209 
Uninitialize(PluginToken token)210 void Uninitialize(PluginToken token)
211 {
212     auto context = static_cast<IRenderContext*>(token);
213     context->GetDevice().GetShaderManager().UnloadShaderFiles(SHADER_FILE_PATHS);
214     auto& fm = context->GetEngine().GetFileManager();
215     fm.UnregisterPath(SHADERS, SHADER_PATH);
216     fm.UnregisterPath(VIDS, VID_PATH);
217     fm.UnregisterPath(PIDS, PID_PATH);
218     fm.UnregisterFilesystem(ROFS);
219 }
220 
InitializeEcs(IEcs&)221 PluginToken InitializeEcs(IEcs&)
222 {
223     return {};
224 }
225 
UninitializeEcs(PluginToken)226 void UninitializeEcs(PluginToken) {}
227 
228 static constexpr IRenderPlugin RENDER_PLUGIN(Initialize, Uninitialize);
229 
230 static constexpr IEcsPlugin ECS_PLUGIN(InitializeEcs, UninitializeEcs);
231 
RegisterInterfaces(IPluginRegister& pluginRegistry)232 PluginToken RegisterInterfaces(IPluginRegister& pluginRegistry)
233 {
234 #if defined(CORE_PLUGIN) && (CORE_PLUGIN == 1)
235     gPluginRegistry = &pluginRegistry;
236 #endif
237     for (const auto& info : gRenderDataStores) {
238         pluginRegistry.RegisterTypeInfo(info);
239     }
240     for (const auto& info : gRenderNodes) {
241         pluginRegistry.RegisterTypeInfo(info);
242     }
243     for (const auto& info : gComponentManagers) {
244         pluginRegistry.RegisterTypeInfo(info);
245     }
246     for (const auto& info : gSystems) {
247         pluginRegistry.RegisterTypeInfo(info);
248     }
249     pluginRegistry.RegisterTypeInfo(RENDER_PLUGIN);
250     pluginRegistry.RegisterTypeInfo(ECS_PLUGIN);
251     return &pluginRegistry;
252 }
253 
UnregisterInterfaces(PluginToken token)254 void UnregisterInterfaces(PluginToken token)
255 {
256     auto& pluginRegistry = *static_cast<IPluginRegister*>(token);
257     for (const auto& info : gRenderDataStores) {
258         pluginRegistry.UnregisterTypeInfo(info);
259     }
260     for (const auto& info : gRenderNodes) {
261         pluginRegistry.UnregisterTypeInfo(info);
262     }
263     for (const auto& info : gComponentManagers) {
264         pluginRegistry.UnregisterTypeInfo(info);
265     }
266     for (const auto& info : gSystems) {
267         pluginRegistry.UnregisterTypeInfo(info);
268     }
269     pluginRegistry.UnregisterTypeInfo(ECS_PLUGIN);
270     pluginRegistry.UnregisterTypeInfo(RENDER_PLUGIN);
271 }
272 
273 } // namespace Dotfield
274 
275 extern "C" {
PLUGIN_DATA(DotfieldPlugin)276 PLUGIN_DATA(DotfieldPlugin){
277     { CORE_NS::IPlugin::UID },
278     "DotfieldPlugin",
279     { Dotfield::UID_DOTFIELD_PLUGIN, Dotfield::GetVersionInfo },
280     Dotfield::RegisterInterfaces,
281     Dotfield::UnregisterInterfaces,
282     { Dotfield::PLUGIN_DEPENDENCIES },
283 };
284 }