• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "custom/lume_custom_render.h"
17 
18 #include <securec.h>
19 
20 #include <3d/ecs/components/camera_component.h>
21 #include <3d/ecs/components/environment_component.h>
22 #include <3d/ecs/components/light_component.h>
23 #include <3d/ecs/components/render_configuration_component.h>
24 #include <3d/ecs/components/render_handle_component.h>
25 #include <3d/ecs/components/transform_component.h>
26 #include <3d/ecs/systems/intf_node_system.h>
27 #include <3d/util/intf_scene_util.h>
28 
29 #include <base/containers/string_view.h>
30 #include <base/math/matrix_util.h>
31 #include <base/math/quaternion.h>
32 #include <base/math/quaternion_util.h>
33 #include <base/math/vector.h>
34 #include <base/math/vector_util.h>
35 
36 #include <core/ecs/intf_system_graph_loader.h>
37 #include <core/image/intf_image_loader_manager.h>
38 #include <core/io/intf_file_manager.h>
39 
40 #include <render/device/intf_shader_manager.h>
41 #include <render/nodecontext/intf_render_node_graph_manager.h>
42 
43 #include "3d_widget_adapter_log.h"
44 
45 namespace OHOS::Render3D {
Initialize(const CustomRenderInput & input)46 void LumeCustomRender::Initialize(const CustomRenderInput& input)
47 {
48     ecs_ = input.ecs_;
49     graphicsContext_ = input.graphicsContext_;
50     engine_ = input.engine_;
51     renderContext_ = input.renderContext_;
52 
53     if (!ecs_ || !graphicsContext_ || !renderContext_ || !engine_) {
54         WIDGET_LOGD("invalid input ecs %d, graphic context%d, render context %d, engine %d",
55             ecs_ != nullptr, graphicsContext_ != nullptr, renderContext_ != nullptr, engine_ != nullptr);
56         return;
57     }
58 
59     PrepareResolutionInputBuffer();
60     GetDefaultStaging();
61     OnSizeChange(input.width_, input.height_);
62 }
63 
RegistorShaderPath(const std::string & shaderPath)64 void LumeCustomRender::RegistorShaderPath(const std::string& shaderPath)
65 {
66     WIDGET_LOGD("lume custom render registor shader path");
67     engine_->GetFileManager().RegisterPath("shaders", shaderPath.c_str(), false);
68     static constexpr const RENDER_NS::IShaderManager::ShaderFilePathDesc desc { "shaders://" };
69     renderContext_->GetDevice().GetShaderManager().LoadShaderFiles(desc);
70 }
71 
SetRenderOutput(const RENDER_NS::RenderHandleReference & output)72 void LumeCustomRender::SetRenderOutput(const RENDER_NS::RenderHandleReference& output)
73 {
74     if (output) {
75         RENDER_NS::IRenderNodeGraphManager& graphManager = renderContext_->GetRenderNodeGraphManager();
76         graphManager.SetRenderNodeGraphResources(GetRenderHandle(), {}, { &output, 1u });
77     }
78 }
79 
GetDefaultStaging()80 void LumeCustomRender::GetDefaultStaging()
81 {
82     renderDataStoreDefaultStaging_ = reinterpret_cast<RENDER_NS::IRenderDataStoreDefaultStaging*>(
83         renderContext_->GetRenderDataStoreManager().GetRenderDataStore(RENDER_DATA_STORE_DEFAULT_STAGING));
84     if (renderDataStoreDefaultStaging_ == nullptr) {
85         WIDGET_LOGE("Get default staging error");
86     }
87 }
88 
PrepareResolutionInputBuffer()89 void LumeCustomRender::PrepareResolutionInputBuffer()
90 {
91     const uint32_t resolutionSize = 2U;
92     if (!resolutionBuffer_.Alloc(resolutionSize)) {
93         WIDGET_LOGE("alloc resolution input buffer error!");
94     }
95     resolutionBuffer_.Update(0.0, 0U);
96     resolutionBuffer_.Update(0.0, 1U);
97 }
98 
DestroyBuffer()99 void LumeCustomRender::DestroyBuffer()
100 {
101     shaderInputBufferHandle_ = {};
102     resolutionBuffer_ = {};
103 }
104 
UpdateShaderSpecialization(const std::vector<uint32_t> & values)105 void LumeCustomRender::UpdateShaderSpecialization(const std::vector<uint32_t>& values)
106 {
107     RENDER_NS::IRenderDataStorePod* dataStore = static_cast<RENDER_NS::IRenderDataStorePod*>(
108         renderContext_->GetRenderDataStoreManager().GetRenderDataStore(RENDER_DATA_STORE_POD));
109     if (dataStore) {
110         RENDER_NS::ShaderSpecializationRenderPod shaderSpecialization;
111         auto count = std::min(static_cast<uint32_t>(values.size()),
112             RENDER_NS::ShaderSpecializationRenderPod::MAX_SPECIALIZATION_CONSTANT_COUNT);
113         shaderSpecialization.specializationConstantCount = count;
114 
115         for (auto i = 0U; i < count; i++) {
116             shaderSpecialization.specializationFlags[i].value = values[i];
117         }
118         dataStore->Set(SPECIALIZATION_CONFIG_NAME, BASE_NS::arrayviewU8(shaderSpecialization));
119     }
120 }
121 
DestroyDataStorePod()122 void LumeCustomRender::DestroyDataStorePod()
123 {
124 }
125 
LoadImages(const std::vector<std::string> & imageUris)126 void  LumeCustomRender::LoadImages(const std::vector<std::string>& imageUris)
127 {
128     WIDGET_LOGD("lume custom render load images");
129     for (auto& imageUri : imageUris) {
130         LoadImage(imageUri);
131     }
132 }
133 
LoadImage(const std::string & imageUri)134 void LumeCustomRender::LoadImage(const std::string& imageUri)
135 {
136     auto find = std::find_if(images_.begin(), images_.end(),
137         [&imageUri](const std::pair<std::string, CORE_NS::EntityReference>& image) {
138             return image.first == imageUri;
139         });
140     if (find != images_.end()) {
141         return;
142     }
143     auto& imageManager = engine_->GetImageLoaderManager();
144     auto& gpuResourceMgr = renderContext_->GetDevice().GetGpuResourceManager();
145     auto handleManager = CORE_NS::GetManager<CORE3D_NS::IRenderHandleComponentManager>(*ecs_);
146 
147     auto result = imageManager.LoadImage(imageUri.c_str(), 0);
148     if (!result.success) {
149         WIDGET_LOGE("3D image update fail %s error", imageUri.c_str());
150         return;
151     }
152 
153     RENDER_NS::GpuImageDesc gpuImageDesc = gpuResourceMgr.CreateGpuImageDesc(result.image->GetImageDesc());
154     std::string name = std::string(IMAGE_NAME) + "_" + std::to_string(images_.size());
155     auto handle = gpuResourceMgr.Create(name.c_str(), gpuImageDesc, std::move(result.image));
156 
157     auto entity = ecs_->GetEntityManager().CreateReferenceCounted();
158     handleManager->Create(entity);
159     handleManager->Write(entity)->reference = BASE_NS::move(handle);
160     images_.push_back(std::make_pair(imageUri, entity));
161 }
162 
UnloadImages()163 void LumeCustomRender::UnloadImages()
164 {
165     images_.clear();
166 }
167 
DestroyRes()168 void LumeCustomRender::DestroyRes()
169 {
170     DestroyBuffer();
171     DestroyDataStorePod();
172     UnloadImages();
173     UnloadRenderNodeGraph();
174 }
175 
~LumeCustomRender()176 LumeCustomRender::~LumeCustomRender()
177 {
178     DestroyRes();
179 }
180 
OnSizeChange(int32_t width,int32_t height)181 void LumeCustomRender::OnSizeChange(int32_t width, int32_t height)
182 {
183     uint32_t floatSize = 2u;
184     const float* buffer = resolutionBuffer_.Map(floatSize);
185     if (!buffer) {
186         WIDGET_LOGE("custom render resolution resolutionBuffer error!");
187         return;
188     }
189 
190     auto bSize = resolutionBuffer_.ByteSize();
191     if (!resolutionBufferHandle_) {
192         RENDER_NS::GpuBufferDesc bufferDesc {
193             RENDER_NS::CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT | RENDER_NS::CORE_BUFFER_USAGE_TRANSFER_DST_BIT,
194             RENDER_NS::CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT | RENDER_NS::CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT,
195             RENDER_NS::CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, 0u };
196         bufferDesc.byteSize = bSize;
197         resolutionBufferHandle_ =
198             renderContext_->GetDevice().GetGpuResourceManager().Create(RESOLUTION_BUFFER, bufferDesc);
199         WIDGET_LOGD("create resolution buffer handle");
200     }
201 
202     auto fWidth = static_cast<float>(width);
203     auto fHeight = static_cast<float>(height);
204     if ((buffer[0] == fWidth) && (buffer[1] == fHeight)) {
205         return;
206     }
207 
208     WIDGET_LOGD("update custom shader resolution %f X %f", fWidth, fHeight);
209     resolutionBuffer_.Update(fWidth, 0U);
210     resolutionBuffer_.Update(fHeight, 1U);
211     BASE_NS::array_view<const uint8_t> data(reinterpret_cast<const uint8_t*>(buffer), bSize);
212     const RENDER_NS::BufferCopy bufferCopy { 0, 0, bSize };
213     renderDataStoreDefaultStaging_->CopyDataToBufferOnCpu(data, resolutionBufferHandle_, bufferCopy);
214 }
215 
GetRenderHandle()216 const RENDER_NS::RenderHandleReference LumeCustomRender::GetRenderHandle()
217 {
218     return renderHandle_;
219 }
220 
LoadRenderNodeGraph(const std::string & rngUri,const RENDER_NS::RenderHandleReference & output)221 void LumeCustomRender::LoadRenderNodeGraph(const std::string& rngUri,
222     const RENDER_NS::RenderHandleReference& output)
223 {
224     RENDER_NS::IRenderNodeGraphManager& graphManager = renderContext_->GetRenderNodeGraphManager();
225     auto* loader = &graphManager.GetRenderNodeGraphLoader();
226     auto graphUri = BASE_NS::string_view(rngUri.c_str());
227 
228     auto const result = loader->Load(graphUri);
229     if (!result.error.empty()) {
230         WIDGET_LOGE("3D render node graph load fail: %s, uri %s", result.error.c_str(),
231             rngUri.c_str());
232         return;
233     }
234 
235     renderHandle_ = graphManager.Create(
236         RENDER_NS::IRenderNodeGraphManager::RenderNodeGraphUsageType::RENDER_NODE_GRAPH_STATIC, result.desc);
237     SetRenderOutput(output);
238 }
239 
UnloadRenderNodeGraph()240 void LumeCustomRender::UnloadRenderNodeGraph()
241 {
242     renderHandle_ = {};
243 }
244 
UpdateShaderInputBuffer(const std::shared_ptr<ShaderInputBuffer> & shaderInputBuffer)245 bool LumeCustomRender::UpdateShaderInputBuffer(const std::shared_ptr<ShaderInputBuffer>& shaderInputBuffer)
246 {
247     if (!shaderInputBuffer || !shaderInputBuffer->IsValid()) {
248         WIDGET_LOGE("3D shader input buffer update fail: invalid shaderInputBuffer");
249         return false;
250     }
251 
252     if (renderContext_ == nullptr) {
253         WIDGET_LOGE("3D shader input buffer update fail: Call UpdateBuffer before Initiliaze error");
254         return false;
255     }
256 
257     auto fSize = shaderInputBuffer->FloatSize();
258     auto bSize = shaderInputBuffer->ByteSize();
259     if (bufferDesc_.byteSize != bSize) {
260         bufferDesc_.byteSize = bSize;
261         shaderInputBufferHandle_ = renderContext_->GetDevice().GetGpuResourceManager().Create(INPUT_BUFFER,
262             bufferDesc_);
263     }
264 
265     const float* buffer = shaderInputBuffer->Map(fSize);
266     if (!buffer) {
267         WIDGET_LOGE("3D shader input buffer update fail: map shaderInputBuffer error!");
268         return false;
269     }
270 
271     BASE_NS::array_view<const uint8_t> data(reinterpret_cast<const uint8_t*>(buffer), bSize);
272     const RENDER_NS::BufferCopy bufferCopy{0, 0, bSize};
273 
274     renderDataStoreDefaultStaging_->CopyDataToBufferOnCpu(data, shaderInputBufferHandle_, bufferCopy);
275     return true;
276 }
277 
OnDrawFrame()278 void LumeCustomRender::OnDrawFrame()
279 {
280 }
281 
282 } // namespace name
283