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