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 CORE_ECS_RENDERSYSTEM_H
17 #define CORE_ECS_RENDERSYSTEM_H
18 
19 #include <ComponentTools/component_query.h>
20 #include <PropertyTools/property_api_impl.h>
21 #include <limits>
22 
23 #include <3d/ecs/components/layer_defines.h>
24 #include <3d/ecs/components/render_configuration_component.h>
25 #include <3d/ecs/systems/intf_render_system.h>
26 #include <3d/render/render_data_defines_3d.h>
27 #include <base/math/vector.h>
28 #include <core/namespace.h>
29 #include <render/namespace.h>
30 #include <render/resource_handle.h>
31 
32 #include "property/property_handle.h"
33 
BASE_BEGIN_NAMESPACE()34 BASE_BEGIN_NAMESPACE()
35 namespace Math {
36 class Mat4X4;
37 } // namespace Math
38 BASE_END_NAMESPACE()
39 
40 CORE_BEGIN_NAMESPACE()
41 class IFrustumUtil;
42 CORE_END_NAMESPACE()
43 
44 RENDER_BEGIN_NAMESPACE()
45 class IShaderManager;
46 class IRenderContext;
47 RENDER_END_NAMESPACE()
48 
49 CORE3D_BEGIN_NAMESPACE()
50 class IEnvironmentComponentManager;
51 class IFogComponentManager;
52 class IRenderHandleComponentManager;
53 class INameComponentManager;
54 class INodeComponentManager;
55 class IRenderMeshBatchComponentManager;
56 class IRenderMeshComponentManager;
57 class IWorldMatrixComponentManager;
58 class IPreviousWorldMatrixComponentManager;
59 class IRenderConfigurationComponentManager;
60 class ICameraComponentManager;
61 class ILayerComponentManager;
62 class ILightComponentManager;
63 class IJointMatricesComponentManager;
64 class IMaterialExtensionComponentManager;
65 class IMaterialComponentManager;
66 class IMeshComponentManager;
67 class ISkinJointsComponentManager;
68 class IPlanarReflectionComponentManager;
69 class IPreviousJointMatricesComponentManager;
70 class IPostProcessComponentManager;
71 class IPostProcessConfigurationComponentManager;
72 class IUriComponentManager;
73 class IRenderDataStoreDefaultCamera;
74 class IRenderDataStoreDefaultLight;
75 class IRenderDataStoreDefaultMaterial;
76 class IRenderDataStoreDefaultScene;
77 
78 class IRenderPreprocessorSystem;
79 
80 class IMesh;
81 class IMaterial;
82 class IPicking;
83 class IRenderUtil;
84 class IGraphicsContext;
85 
86 struct RenderMeshComponent;
87 struct JointMatricesComponent;
88 struct PreviousJointMatricesComponent;
89 struct MaterialComponent;
90 struct WorldMatrixComponent;
91 struct LightComponent;
92 struct MinAndMax;
93 
94 class RenderSystem final : public IRenderSystem {
95 public:
96     explicit RenderSystem(CORE_NS::IEcs& ecs);
97     ~RenderSystem() override;
98     BASE_NS::string_view GetName() const override;
99     BASE_NS::Uid GetUid() const override;
100     CORE_NS::IPropertyHandle* GetProperties() override;
101     const CORE_NS::IPropertyHandle* GetProperties() const override;
102     void SetProperties(const CORE_NS::IPropertyHandle&) override;
103     bool IsActive() const override;
104     void SetActive(bool state) override;
105 
106     void Initialize() override;
107     bool Update(bool frameRenderingQueued, uint64_t totalTime, uint64_t deltaTime) override;
108     void Uninitialize() override;
109 
110     const CORE_NS::IEcs& GetECS() const override;
111 
112     BASE_NS::array_view<const RENDER_NS::RenderHandleReference> GetRenderNodeGraphs() const override;
113 
114     struct BatchData {
115         CORE_NS::Entity entity; // node, render mesh component
116         CORE_NS::Entity mesh;   // mesh component
117         uint64_t layerMask { LayerConstants::DEFAULT_LAYER_MASK };
118         CORE_NS::IComponentManager::ComponentId jointId { CORE_NS::IComponentManager::INVALID_COMPONENT_ID };
119         CORE_NS::IComponentManager::ComponentId prevJointId { CORE_NS::IComponentManager::INVALID_COMPONENT_ID };
120 
121         BASE_NS::Math::Mat4X4 mtx;       // world matrix
122         BASE_NS::Math::Mat4X4 prevWorld; // previous world matrix
123     };
124     using BatchDataVector = BASE_NS::vector<BatchData>;
125 
126     struct DefaultMaterialShaderData {
127         struct SingleShaderData {
128             CORE_NS::EntityReference shader;
129             CORE_NS::EntityReference gfxState;
130             CORE_NS::EntityReference gfxStateDoubleSided;
131         };
132         SingleShaderData opaque;
133         SingleShaderData blend;
134         SingleShaderData depth;
135     };
136     struct CameraRenderNodeGraphs {
137         // camera
138         RENDER_NS::RenderHandleReference rngHandle;
139         // camera post process
140         RENDER_NS::RenderHandleReference ppRngHandle;
141     };
142     struct CameraRngsOutput {
143         CameraRenderNodeGraphs rngs;
144         // multi-view post processes
145         RENDER_NS::RenderHandleReference
146             multiviewPpHandles[RenderSceneDataConstants::MAX_MULTI_VIEW_LAYER_CAMERA_COUNT] { {}, {}, {} };
147     };
148 
149 private:
150     struct MeshProcessData {
151         const uint64_t layerMask { 0 };
152         const uint32_t batchInstanceCount { 0 };
153         const bool duplicateMaterialInstances { false };
154         const CORE_NS::Entity& renderMeshEntity;
155         const CORE_NS::Entity& meshEntity;
156         const MeshComponent& meshComponent;
157         const RenderMeshComponent& renderMeshComponent;
158         const BASE_NS::Math::Mat4X4& world;
159         const BASE_NS::Math::Mat4X4& prevWorld;
160     };
161     struct LightProcessData {
162         const uint64_t layerMask { 0 };
163         const CORE_NS::Entity& entity;
164         const LightComponent& lightComponent;
165         const BASE_NS::Math::Mat4X4& world;
166         RenderScene& renderScene;
167         uint32_t& spotLightIndex;
168     };
169     struct SkinProcessData {
170         const JointMatricesComponent* const jointMatricesComponent { nullptr };
171         const PreviousJointMatricesComponent* const prevJointMatricesComponent { nullptr };
172     };
173 
174     void SetDataStorePointers(RENDER_NS::IRenderDataStoreManager& manager);
175     // returns the instance's valid scene component
176     RenderConfigurationComponent GetRenderConfigurationComponent();
177     CORE_NS::Entity ProcessScene(const RenderConfigurationComponent& sc);
178     uint32_t ProcessSubmesh(const MeshProcessData& mpd, const MeshComponent::Submesh& submesh, const uint32_t meshIndex,
179         const uint32_t subMeshIdx, const uint32_t skinJointIndex, const MinAndMax& mam, const bool isNegative);
180     void ProcessMesh(const MeshProcessData& mpd, const MinAndMax& batchMam, const SkinProcessData& spd,
181         BASE_NS::vector<uint32_t>* submeshMaterials);
182     void ProcessRenderMeshBatch(const CORE_NS::Entity renderMeshBatch, const CORE_NS::ComponentQuery::ResultRow* row);
183     void ProcessRenderMeshBatch(BASE_NS::array_view<const CORE_NS::Entity> renderMeshComponents);
184     void ProcessSingleRenderMesh(CORE_NS::Entity renderMeshComponent);
185     void ProcessRenderables();
186     void ProcessBatchRenderables();
187     void ProcessEnvironments(const RenderConfigurationComponent& sceneComponent);
188     void ProcessCameras(const RenderConfigurationComponent& sceneComponent, const CORE_NS::Entity& mainCameraEntity,
189         RenderScene& renderScene);
190     void ProcessLight(const LightProcessData& lightProcessData);
191     void ProcessLights(RenderScene& renderScene);
192     void ProcessShadowCamera(const LightProcessData lightProcessData, RenderLight& light);
193     void ProcessReflection(const CORE_NS::ComponentQuery::ResultRow& row, const RenderCamera& camera);
194     void ProcessReflections(const RenderScene& renderScene);
195     void ProcessPostProcesses();
196     void FetchFullScene();
197     void EvaluateMaterialModifications(const MaterialComponent& matComp);
198     // calculates min max from all submeshes and does min max for inout
199     struct BatchIndices {
200         uint32_t submeshIndex { ~0u };
201         uint32_t batchStartIndex { ~0u };
202         uint32_t batchEndCount { ~0u };
203     };
204     // with submeshIndex == ~0u processes all submeshes
205     void CombineBatchWorldMinAndMax(const BatchDataVector& batchData, const BatchIndices& batchIndices,
206         const MeshComponent& mesh, MinAndMax& mam) const;
207 
208     void ProcessRenderNodeGraphs(const RenderConfigurationComponent& renderConfig, const RenderScene& renderScene);
209     void DestroyRenderDataStores();
210     CameraRngsOutput GetCameraRenderNodeGraphs(const RenderScene& renderScene, const RenderCamera& renderCamera);
211     RENDER_NS::RenderHandleReference GetSceneRenderNodeGraph(const RenderScene& renderScene);
212 
213     struct CameraData;
214     CameraData UpdateAndGetPreviousFrameCameraData(
215         const CORE_NS::Entity& entity, const BASE_NS::Math::Mat4X4& view, const BASE_NS::Math::Mat4X4& proj);
216     BASE_NS::vector<RenderCamera> GetMultiviewCameras(const RenderCamera& renderCamera);
217 
218     bool active_ = true;
219     CORE_NS::IEcs& ecs_;
220 
221     IRenderSystem::Properties properties_;
222 
223     IRenderDataStoreDefaultCamera* dsCamera_ = nullptr;
224     IRenderDataStoreDefaultLight* dsLight_ = nullptr;
225     IRenderDataStoreDefaultMaterial* dsMaterial_ = nullptr;
226     IRenderDataStoreDefaultScene* dsScene_ = nullptr;
227     RENDER_NS::IShaderManager* shaderMgr_ = nullptr;
228     RENDER_NS::IGpuResourceManager* gpuResourceMgr_ = nullptr;
229     CORE_NS::IFrustumUtil* frustumUtil_ = nullptr;
230 
231     INodeComponentManager* nodeMgr_ = nullptr;
232     IRenderMeshBatchComponentManager* renderMeshBatchMgr_ = nullptr;
233     IRenderMeshComponentManager* renderMeshMgr_ = nullptr;
234     IWorldMatrixComponentManager* worldMatrixMgr_ = nullptr;
235     IPreviousWorldMatrixComponentManager* prevWorldMatrixMgr_ = nullptr;
236     IRenderConfigurationComponentManager* renderConfigMgr_ = nullptr;
237     ICameraComponentManager* cameraMgr_ = nullptr;
238     ILightComponentManager* lightMgr_ = nullptr;
239     IPlanarReflectionComponentManager* planarReflectionMgr_ = nullptr;
240     IMaterialExtensionComponentManager* materialExtensionMgr_ = nullptr;
241     IMaterialComponentManager* materialMgr_ = nullptr;
242     IMeshComponentManager* meshMgr_ = nullptr;
243     IUriComponentManager* uriMgr_ = nullptr;
244     INameComponentManager* nameMgr_ = nullptr;
245     IEnvironmentComponentManager* environmentMgr_ = nullptr;
246     IFogComponentManager* fogMgr_ = nullptr;
247     IRenderHandleComponentManager* gpuHandleMgr_ = nullptr;
248     ILayerComponentManager* layerMgr_ = nullptr;
249 
250     IJointMatricesComponentManager* jointMatricesMgr_ = nullptr;
251     IPreviousJointMatricesComponentManager* prevJointMatricesMgr_ = nullptr;
252 
253     IPostProcessComponentManager* postProcessMgr_ = nullptr;
254     IPostProcessConfigurationComponentManager* postProcessConfigMgr_ = nullptr;
255 
256     uint32_t renderConfigurationGeneration_ = 0;
257     uint32_t cameraGeneration_ = 0;
258     uint32_t lightGeneration_ = 0;
259     uint32_t planarReflectionGeneration_ = 0;
260     uint32_t materialExtensionGeneration_ = 0;
261     uint32_t environmentGeneration_ = 0;
262     uint32_t fogGeneration_ = 0;
263     uint32_t postprocessGeneration_ = 0;
264     uint32_t postprocessConfigurationGeneration_ = 0;
265 
266     IPicking* picking_ = nullptr;
267 
268     IGraphicsContext* graphicsContext_ = nullptr;
269     IRenderUtil* renderUtil_ = nullptr;
270     RENDER_NS::IRenderContext* renderContext_ = nullptr;
271 
272     IRenderPreprocessorSystem* renderPreprocessorSystem_ = nullptr;
273 
274     CORE_NS::ComponentQuery lightQuery_;
275     CORE_NS::ComponentQuery renderableQuery_;
276     CORE_NS::ComponentQuery reflectionsQuery_;
277 
278     BASE_NS::Math::Vec3 sceneBoundingSpherePosition_ { 0.0f, 0.0f, 0.0f };
279     float sceneBoundingSphereRadius_ { 0.0f };
280 
281     CORE_NS::PropertyApiImpl<IRenderSystem::Properties> RENDER_SYSTEM_PROPERTIES;
282 
283     uint64_t totalTime_ { 0u };
284     uint64_t deltaTime_ { 0u };
285     uint64_t frameIndex_ { 0u };
286 
287     // additionally these could be stored to somewhere else
288     // though this is ECS render system and the render node graphs are owned by ECS (RS)
289     // these do not add overhead if the property bits are not set (only clear per frame)
290     struct RenderProcessing {
291         struct AdditionalCameraContainer {
292             CameraRenderNodeGraphs rngs;
293             RenderCamera::Flags flags { 0 };
294             RenderCamera::RenderPipelineType renderPipelineType { RenderCamera::RenderPipelineType::FORWARD };
295             uint64_t lastFrameIndex { 0 };   // frame when used
296             bool enableAutoDestroy { true }; // always true with all cameras
297             BASE_NS::fixed_string<RENDER_NS::RenderDataConstants::MAX_DEFAULT_NAME_LENGTH> postProcessName;
298             BASE_NS::string customRngFile;
299             BASE_NS::string customPostProcessRngFile;
300             uint32_t multiViewCameraCount { 0U };
301         };
302         struct SceneRngContainer {
303             BASE_NS::string customRngFile;
304             BASE_NS::string customPostSceneRngFile;
305 
306             RENDER_NS::RenderHandleReference rng;
307             RENDER_NS::RenderHandleReference customRng;
308             RENDER_NS::RenderHandleReference customPostRng;
309         };
310 
311         // all render node graphs (scene rng is always the first and this needs to be in order)
312         BASE_NS::vector<RENDER_NS::RenderHandleReference> orderedRenderNodeGraphs;
313         // camera component id with generation hash
314         BASE_NS::unordered_map<uint64_t, AdditionalCameraContainer> camIdToRng;
315 
316         SceneRngContainer sceneRngs;
317         uint64_t sceneMainCamId { 0 };
318 
319         // reset every frame (flags for rendering hints)
320         uint32_t frameFlags { 0u };
321 
322         // store created pods
323         BASE_NS::vector<BASE_NS::string> postProcessPods;
324         // store created post process data stores
325         BASE_NS::vector<BASE_NS::string> postProcessConfigs;
326 
327         bool frameProcessed { false };
328     };
329     RenderProcessing renderProcessing_;
330 
331     struct CameraData {
332         BASE_NS::Math::Mat4X4 view;
333         BASE_NS::Math::Mat4X4 proj;
334         uint64_t lastFrameIndex { 0 }; // frame when used
335     };
336     // store previous frame matrices
337     BASE_NS::unordered_map<CORE_NS::Entity, CameraData> cameraData_;
338 
339     BASE_NS::unordered_map<CORE_NS::Entity, BatchDataVector> batches_;
340     BASE_NS::vector<uint32_t> materialIndices_;
341 
342     // store default shader data for default materials in this ECS
343     DefaultMaterialShaderData dmShaderData_;
344 };
345 CORE3D_END_NAMESPACE()
346 
347 #endif // CORE_ECS_RENDERSYSTEM_H
348