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