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 "render_node_default_camera_post_process_controller.h"
17
18 #include <3d/render/default_material_constants.h>
19 #include <3d/render/intf_render_data_store_default_camera.h>
20 #include <3d/render/intf_render_data_store_default_scene.h>
21 #include <core/plugin/intf_class_register.h>
22 #include <render/datastore/intf_render_data_store_manager.h>
23 #include <render/implementation_uids.h>
24 #include <render/intf_render_context.h>
25 #include <render/namespace.h>
26 #include <render/nodecontext/intf_render_command_list.h>
27 #include <render/nodecontext/intf_render_node_context_manager.h>
28 #include <render/nodecontext/intf_render_node_graph_share_manager.h>
29 #include <render/nodecontext/intf_render_node_parser_util.h>
30 #include <render/nodecontext/intf_render_node_post_process_util.h>
31 #include <render/nodecontext/intf_render_node_util.h>
32
33 #include "render/render_node_scene_util.h"
34
35 using namespace BASE_NS;
36 using namespace CORE_NS;
37 using namespace RENDER_NS;
38
39 CORE3D_BEGIN_NAMESPACE()
40 namespace {
FillPostProcessImages(const RenderCamera & cam,const uint32_t layer,const array_view<const IRenderNodeGraphShareManager::NamedResource> namedResources,IRenderNodePostProcessUtil::PostProcessInfo & info)41 void FillPostProcessImages(const RenderCamera& cam, const uint32_t layer,
42 const array_view<const IRenderNodeGraphShareManager::NamedResource> namedResources,
43 IRenderNodePostProcessUtil::PostProcessInfo& info)
44 {
45 RenderHandle outputHandle {};
46 const bool mvLayerCam = ((layer != 0U) && (layer != PipelineStateConstants::GPU_IMAGE_ALL_LAYERS));
47 if (mvLayerCam) {
48 if (cam.colorTargets[0U]) {
49 outputHandle = cam.colorTargets[0U].GetHandle();
50 } else {
51 #if (CORE3D_VALIDATION_ENABLED == 1)
52 CORE_LOG_ONCE_W(to_string(cam.id) + "FillPostProcessImages_",
53 "Multi-view target output not found for layer (%u)", layer);
54 #endif
55 }
56 }
57 // NOTE: history not currently supported for multi-view only camera
58 for (const auto& ref : namedResources) {
59 if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_OUTPUT) {
60 auto& res = info.imageData.output;
61 if ((layer != 0U) && (layer != PipelineStateConstants::GPU_IMAGE_ALL_LAYERS)) {
62 res.handle = outputHandle;
63 } else {
64 res.handle = ref.handle;
65 }
66 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_COLOR) {
67 auto& res = info.imageData.input;
68 res.layer = layer;
69 res.handle = ref.handle;
70 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_DEPTH) {
71 auto& res = info.imageData.depth;
72 res.layer = layer;
73 res.handle = ref.handle;
74 } else if (ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_VELOCITY_NORMAL) {
75 auto& res = info.imageData.velocity;
76 res.layer = layer;
77 res.handle = ref.handle;
78 } else if ((ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY) && (!mvLayerCam)) {
79 info.imageData.history.handle = ref.handle;
80 } else if ((ref.name == DefaultMaterialRenderNodeConstants::CORE_DM_CAMERA_HISTORY_NEXT) && (!mvLayerCam)) {
81 info.imageData.historyNext.handle = ref.handle;
82 }
83 }
84 }
85 } // namespace
86
InitNode(IRenderNodeContextManager & renderNodeContextMgr)87 void RenderNodeDefaultCameraPostProcessController::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
88 {
89 renderNodeContextMgr_ = &renderNodeContextMgr;
90
91 rnPostProcessUtil_ = CORE_NS::CreateInstance<IRenderNodePostProcessUtil>(
92 renderNodeContextMgr_->GetRenderContext(), UID_RENDER_NODE_POST_PROCESS_UTIL);
93
94 validPostProcessInputs_ = false;
95 ParseRenderNodeInputs();
96
97 const auto& renderNodeGraphData = renderNodeContextMgr_->GetRenderNodeGraphData();
98 stores_ = RenderNodeSceneUtil::GetSceneRenderDataStores(
99 renderNodeContextMgr, renderNodeGraphData.renderNodeGraphDataStoreName);
100
101 currentScene_ = {};
102
103 // id checked first for custom camera
104 if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
105 currentScene_.customCameraId = jsonInputs_.customCameraId;
106 } else if (!jsonInputs_.customCameraName.empty()) {
107 currentScene_.customCameraName = jsonInputs_.customCameraName;
108 }
109
110 {
111 const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
112 const auto* dataStoreScene = static_cast<IRenderDataStoreDefaultScene*>(
113 renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
114 const auto* dataStoreCamera = static_cast<IRenderDataStoreDefaultCamera*>(
115 renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
116 const bool validRenderDataStore = dataStoreScene && dataStoreCamera;
117 if (validRenderDataStore) {
118 UpdateCurrentScene(*dataStoreScene, *dataStoreCamera);
119 }
120 }
121
122 if (rnPostProcessUtil_) {
123 IRenderNodeGraphShareManager& shrMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
124 // fetch from global render node graph register
125 const array_view<const IRenderNodeGraphShareManager::NamedResource> namedResources =
126 shrMgr.GetRegisteredGlobalRenderNodeOutputs(currentScene_.cameraControllerRenderNodeName);
127 IRenderNodePostProcessUtil::PostProcessInfo info;
128 info.parseRenderNodeInputs = false;
129 FillPostProcessImages(currentScene_.camera, currentScene_.multiviewLayer, namedResources, info);
130 if (info.parseRenderNodeInputs || RenderHandleUtil::IsValid(info.imageData.output.handle)) {
131 validPostProcessInputs_ = true;
132 }
133
134 rnPostProcessUtil_->Init(*renderNodeContextMgr_, info);
135 }
136
137 RegisterOutputs();
138 }
139
PreExecuteFrame()140 void RenderNodeDefaultCameraPostProcessController::PreExecuteFrame()
141 {
142 {
143 const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
144 const auto* dataStoreScene = static_cast<IRenderDataStoreDefaultScene*>(
145 renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameScene));
146 const auto* dataStoreCamera = static_cast<IRenderDataStoreDefaultCamera*>(
147 renderDataStoreMgr.GetRenderDataStore(stores_.dataStoreNameCamera));
148 const bool validRenderDataStore = dataStoreScene && dataStoreCamera;
149 if (validRenderDataStore) {
150 UpdateCurrentScene(*dataStoreScene, *dataStoreCamera);
151 }
152 }
153
154 validPostProcessInputs_ = false;
155 if (rnPostProcessUtil_) {
156 IRenderNodeGraphShareManager& shrMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
157 // fetch from global render node graph register
158 const array_view<const IRenderNodeGraphShareManager::NamedResource> namedResources =
159 shrMgr.GetRegisteredGlobalRenderNodeOutputs(currentScene_.cameraControllerRenderNodeName);
160 IRenderNodePostProcessUtil::PostProcessInfo info;
161 info.parseRenderNodeInputs = false;
162 FillPostProcessImages(currentScene_.camera, currentScene_.multiviewLayer, namedResources, info);
163
164 if (info.parseRenderNodeInputs || RenderHandleUtil::IsValid(info.imageData.output.handle)) {
165 validPostProcessInputs_ = true;
166 }
167
168 if (validPostProcessInputs_) {
169 rnPostProcessUtil_->PreExecute(info);
170 }
171 }
172
173 RegisterOutputs();
174 }
175
ExecuteFrame(IRenderCommandList & cmdList)176 void RenderNodeDefaultCameraPostProcessController::ExecuteFrame(IRenderCommandList& cmdList)
177 {
178 if (rnPostProcessUtil_ && validPostProcessInputs_) {
179 rnPostProcessUtil_->Execute(cmdList);
180 }
181 }
182
RegisterOutputs()183 void RenderNodeDefaultCameraPostProcessController::RegisterOutputs()
184 {
185 if ((currentScene_.customCameraId == INVALID_CAM_ID) && currentScene_.customCameraName.empty()) {
186 return;
187 }
188
189 IRenderNodeGraphShareManager& shrMgr = renderNodeContextMgr_->GetRenderNodeGraphShareManager();
190 // fetch from global render node graph register
191 const array_view<const IRenderNodeGraphShareManager::NamedResource> namedResources =
192 shrMgr.GetRegisteredGlobalRenderNodeOutputs(currentScene_.cameraControllerRenderNodeName);
193 for (const auto& ref : namedResources) {
194 shrMgr.RegisterRenderNodeOutput(ref.name, ref.handle);
195 }
196 }
197
UpdateCurrentScene(const IRenderDataStoreDefaultScene & dataStoreScene,const IRenderDataStoreDefaultCamera & dataStoreCamera)198 void RenderNodeDefaultCameraPostProcessController::UpdateCurrentScene(
199 const IRenderDataStoreDefaultScene& dataStoreScene, const IRenderDataStoreDefaultCamera& dataStoreCamera)
200 {
201 const auto scene = dataStoreScene.GetScene();
202 uint32_t cameraIdx = scene.cameraIndex;
203 if (jsonInputs_.customCameraId != INVALID_CAM_ID) {
204 cameraIdx = dataStoreCamera.GetCameraIndex(jsonInputs_.customCameraId);
205 } else if (!(jsonInputs_.customCameraName.empty())) {
206 cameraIdx = dataStoreCamera.GetCameraIndex(jsonInputs_.customCameraName);
207 }
208
209 currentScene_.multiviewLayer = PipelineStateConstants::GPU_IMAGE_ALL_LAYERS;
210 const auto cameras = dataStoreCamera.GetCameras();
211 const uint32_t cameraCount = static_cast<uint32_t>(cameras.size());
212 if (cameraIdx < cameraCount) {
213 // store current frame camera
214 currentScene_.camera = cameras[cameraIdx];
215 if (currentScene_.camera.multiViewParentCameraId != INVALID_CAM_ID) {
216 // find the base multiview camera
217 if (const uint32_t multiviewBaseCamIdx =
218 dataStoreCamera.GetCameraIndex(currentScene_.camera.multiViewParentCameraId);
219 multiviewBaseCamIdx < cameraCount) {
220 const auto& multiviewBaseCam = cameras[multiviewBaseCamIdx];
221 for (uint32_t camIdx = 0; camIdx < multiviewBaseCam.multiViewCameraCount; ++camIdx) {
222 if (multiviewBaseCam.multiViewCameraIds[camIdx] == currentScene_.camera.id) {
223 // set our layer
224 currentScene_.multiviewLayer = camIdx + 1U;
225 }
226 }
227 }
228 }
229 // if base multiview camera
230 if (currentScene_.camera.multiViewCameraCount > 0U) {
231 currentScene_.multiviewLayer = 0U;
232 }
233 }
234 // full name for fetching data
235 const uint64_t fetchCamId = (currentScene_.camera.multiViewParentCameraId != INVALID_CAM_ID)
236 ? currentScene_.camera.multiViewParentCameraId
237 : currentScene_.camera.id;
238 currentScene_.cameraControllerRenderNodeName = string(scene.name) + to_hex(fetchCamId) + "CORE3D_RN_CAM_CTRL";
239 }
240
ParseRenderNodeInputs()241 void RenderNodeDefaultCameraPostProcessController::ParseRenderNodeInputs()
242 {
243 const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
244 const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
245 jsonInputs_.customCameraName = parserUtil.GetStringValue(jsonVal, "customCameraName");
246 jsonInputs_.customCameraId = parserUtil.GetUintValue(jsonVal, "customCameraId");
247 }
248
249 // for plugin / factory interface
Create()250 IRenderNode* RenderNodeDefaultCameraPostProcessController::Create()
251 {
252 return new RenderNodeDefaultCameraPostProcessController();
253 }
254
Destroy(IRenderNode * instance)255 void RenderNodeDefaultCameraPostProcessController::Destroy(IRenderNode* instance)
256 {
257 delete static_cast<RenderNodeDefaultCameraPostProcessController*>(instance);
258 }
259 CORE3D_END_NAMESPACE()
260