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 #include "core/components_ng/pattern/model/model_adapter_wrapper.h"
17 #include "core/components_ng/render/adapter/rosen_render_context.h"
18 #include "frameworks/core/common/container.h"
19
20 #include "render_service_client/core/ui/rs_ui_director.h"
21 #include "render_service_client/core/ui/rs_ui_share_context.h"
22
23 namespace OHOS::Ace::NG {
24
SetHapInfo()25 Render3D::HapInfo ModelAdapterWrapper::SetHapInfo()
26 {
27 auto container = Container::Current();
28 if (container == nullptr) {
29 LOGE("modle 3d fail to get container");
30 return {};
31 }
32 std::string hapPath = container->GetHapPath();
33 Render3D::HapInfo hapInfo { hapPath, bundleName_, moduleName_ };
34 return hapInfo;
35 }
36
ModelAdapterWrapper(uint32_t key,const ModelViewContext & context)37 ModelAdapterWrapper::ModelAdapterWrapper(uint32_t key, const ModelViewContext& context) : key_(key),
38 surfaceType_(context.surfaceType_), bundleName_(context.bundleName_),
39 #if defined(KIT_3D_ENABLE)
40 moduleName_(context.moduleName_), sceneAdapter_(context.sceneAdapter_)
41 #else
42 moduleName_(context.moduleName_)
43 #endif
44 {
45 touchHandler_ = MakeRefPtr<ModelTouchHandler>();
46 touchHandler_->SetCameraEventCallback([weak = WeakClaim(this)]
47 (const Render3D::PointerEvent& event) {
48 auto adapter = weak.Upgrade();
49 CHECK_NULL_VOID(adapter);
50 adapter->HandleCameraMove(event);
51 });
52
53 #if MULTI_ECS_UPDATE_AT_ONCE
54 RefPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
55 CHECK_NULL_VOID(pipeline);
56 if (pipeline) {
57 Render3D::GraphicsManager::GetInstance().AttachContext(pipeline);
58 } else {
59 LOGE("MODEL_NG: pipeline context is null");
60 }
61 #endif
62 }
63
Deinit()64 std::shared_future<void> ModelAdapterWrapper::Deinit()
65 {
66 ACE_SCOPED_TRACE("ModelAdapterWrapper::Deinit");
67 #if defined(KIT_3D_ENABLE)
68 if (sceneAdapter_) {
69 sceneAdapter_->Deinit();
70 return std::shared_future<void>();
71 }
72 #endif
73 std::shared_ptr<Render3D::WidgetAdapter> widgetAdapter(widgetAdapter_);
74 std::shared_ptr<Render3D::TextureLayer> textureLayer(textureLayer_);
75 auto key = key_;
76 return Render3D::GraphicsTask::GetInstance().PushAsyncMessage([widgetAdapter, textureLayer, key] {
77 ACE_SCOPED_TRACE("ModelAdapterWrapper::Deinit render");
78
79 CHECK_NULL_VOID(widgetAdapter);
80 widgetAdapter->DeInitEngine();
81 Render3D::GraphicsManager::GetInstance().UnRegister(key);
82 CHECK_NULL_VOID(textureLayer);
83 textureLayer->DestroyRenderTarget();
84 });
85 }
86
CreateTextureLayer()87 void ModelAdapterWrapper::CreateTextureLayer()
88 {
89 #if defined(KIT_3D_ENABLE)
90 if (sceneAdapter_) {
91 return;
92 }
93 #endif
94 Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this)] {
95 auto adapter = weak.Upgrade();
96 CHECK_NULL_VOID(adapter);
97
98 auto& gfxManager = Render3D::GraphicsManager::GetInstance();
99 const auto& key = adapter->GetKey();
100 gfxManager.Register(key);
101 adapter->textureLayer_ = std::make_shared<Render3D::TextureLayer>(key);
102 });
103 }
104
CreateWidgetAdapter()105 void ModelAdapterWrapper::CreateWidgetAdapter()
106 {
107 #if defined(KIT_3D_ENABLE)
108 if (sceneAdapter_) {
109 return;
110 }
111 #endif
112 auto key = GetKey();
113 Render3D::HapInfo hapInfo = SetHapInfo();
114 // init engine in async manager sometimes crash on screen rotation
115 Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), key, hapInfo] {
116 auto adapter = weak.Upgrade();
117 CHECK_NULL_VOID(adapter);
118
119 adapter->widgetAdapter_ = std::make_shared<Render3D::WidgetAdapter>(key);
120 auto& gfxManager = Render3D::GraphicsManager::GetInstance();
121 auto&& engine = gfxManager.GetEngine(Render3D::EngineFactory::EngineType::LUME, adapter->GetKey(),
122 hapInfo);
123 adapter->widgetAdapter_->Initialize(std::move(engine));
124 });
125 }
126
OnAttachToFrameNode(const RefPtr<RenderContext> & context)127 void ModelAdapterWrapper::OnAttachToFrameNode(const RefPtr<RenderContext>& context)
128 {
129 #if defined(KIT_3D_ENABLE)
130 // scene adapter toutine
131 if (sceneAdapter_) {
132 sceneAdapter_->LoadPluginsAndInit();
133 textureLayer_ = sceneAdapter_->CreateTextureLayer();
134 return;
135 }
136 #endif
137
138 #ifdef ENABLE_ROSEN_BACKEND
139 auto rsContext = DynamicCast<NG::RosenRenderContext>(context);
140 CHECK_NULL_VOID(rsContext);
141 auto rsNode = rsContext->GetRSNode();
142 CHECK_NULL_VOID(rsNode);
143 rsNode->SetFrameGravity(Rosen::Gravity::RESIZE);
144 #endif
145 CreateTextureLayer();
146 CreateWidgetAdapter();
147 }
148
OnDirtyLayoutWrapperSwap(const Render3D::WindowChangeInfo & windowChangeInfo)149 void ModelAdapterWrapper::OnDirtyLayoutWrapperSwap(const Render3D::WindowChangeInfo& windowChangeInfo)
150 {
151 needsSyncPaint_ = true;
152 #if defined(KIT_3D_ENABLE)
153 if (sceneAdapter_) {
154 sceneAdapter_->OnWindowChange(windowChangeInfo);
155 return;
156 }
157 #endif
158 Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), windowChangeInfo] {
159 auto adapter = weak.Upgrade();
160 CHECK_NULL_VOID(adapter);
161 CHECK_NULL_VOID(adapter->textureLayer_);
162 CHECK_NULL_VOID(adapter->widgetAdapter_);
163
164 adapter->textureLayer_->OnWindowChange(windowChangeInfo);
165 adapter->widgetAdapter_->OnWindowChange(adapter->textureLayer_->GetTextureInfo());
166 });
167 }
168
OnRebuildFrame(RefPtr<RenderContext> & context)169 void ModelAdapterWrapper::OnRebuildFrame(RefPtr<RenderContext>& context)
170 {
171 #ifdef ENABLE_ROSEN_BACKEND
172 auto rsContext = DynamicCast<NG::RosenRenderContext>(context);
173 CHECK_NULL_VOID(rsContext);
174 auto rsNode = rsContext->GetRSNode();
175 #if defined(KIT_3D_ENABLE)
176 if (sceneAdapter_) {
177 CHECK_NULL_VOID(textureLayer_);
178 textureLayer_->SetParent(rsNode);
179 return;
180 }
181 #endif
182 Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), rsNode]() mutable {
183 auto adapter = weak.Upgrade();
184 CHECK_NULL_VOID(adapter);
185 CHECK_NULL_VOID(adapter->textureLayer_);
186
187 adapter->textureLayer_->SetParent(rsNode);
188 });
189 #endif
190 }
191
OnPaint3D(const RefPtr<ModelPaintProperty> & modelPaintProperty)192 void ModelAdapterWrapper::OnPaint3D(const RefPtr<ModelPaintProperty>& modelPaintProperty)
193 {
194 CHECK_NULL_VOID(modelPaintProperty);
195
196 if (modelPaintProperty->NeedsModelSourceSetup()) {
197 UpdateScene(modelPaintProperty);
198 }
199
200 if (modelPaintProperty->NeedsModelBackgroundSetup()) {
201 UpdateEnviroment(modelPaintProperty);
202 }
203
204 if (modelPaintProperty->NeedsCustomRenderSetup()) {
205 UpdateCustomRender(modelPaintProperty);
206 }
207
208 if (modelPaintProperty->NeedsShaderPathSetup()) {
209 UpdateShaderPath(modelPaintProperty);
210 }
211
212 if (modelPaintProperty->NeedsImageTexturePathsSetup()) {
213 UpdateImageTexturePaths(modelPaintProperty);
214 }
215
216 if (modelPaintProperty->NeedsShaderInputBufferSetup()) {
217 UpdateShaderInputBuffers(modelPaintProperty);
218 }
219
220 DrawFrame();
221 }
222
DrawFrame()223 void ModelAdapterWrapper::DrawFrame()
224 {
225 ACE_FUNCTION_TRACE();
226 #if defined(KIT_3D_ENABLE)
227 if (sceneAdapter_) {
228 sceneAdapter_->RenderFrame(needsSyncPaint_);
229 needsRepaint_ = sceneAdapter_->NeedsRepaint();
230 needsSyncPaint_ = false;
231 return;
232 }
233 #endif
234 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
235 auto adapter = weak.Upgrade();
236 CHECK_NULL_VOID(adapter);
237 CHECK_NULL_VOID(adapter->widgetAdapter_);
238
239 adapter->needsRepaint_ = adapter->widgetAdapter_->NeedsRepaint();
240 });
241
242 const auto& msg = [weak = WeakClaim(this)] {
243 auto adapter = weak.Upgrade();
244 CHECK_NULL_VOID(adapter);
245 CHECK_NULL_VOID(adapter->widgetAdapter_);
246
247 adapter->widgetAdapter_->DrawFrame();
248 };
249
250 if (needsSyncPaint_) {
251 #if !defined (MULTI_ECS_UPDATE_AT_ONCE) || (MULTI_ECS_UPDATE_AT_ONCE == 0)
252 needsSyncPaint_ = false;
253 #endif
254 Render3D::GraphicsTask::GetInstance().PushSyncMessage(msg);
255 } else {
256 Render3D::GraphicsTask::GetInstance().PushAsyncMessage(msg);
257 }
258 }
259
OnPaintFinish()260 void ModelAdapterWrapper::OnPaintFinish()
261 {
262 if (callback_) {
263 callback_();
264 }
265 }
266
UnloadSceneAndBackground()267 void ModelAdapterWrapper::UnloadSceneAndBackground()
268 {
269 #if defined(KIT_3D_ENABLE)
270 if (sceneAdapter_) {
271 return;
272 }
273 #endif
274 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
275 auto adapter = weak.Upgrade();
276 CHECK_NULL_VOID(adapter);
277 CHECK_NULL_VOID(adapter->widgetAdapter_);
278
279 adapter->widgetAdapter_->UnloadSceneModel();
280 adapter->widgetAdapter_->UnloadEnvModel();
281 });
282 }
283
NeedsRepaint()284 bool ModelAdapterWrapper::NeedsRepaint()
285 {
286 return needsRepaint_;
287 }
288
~ModelAdapterWrapper()289 ModelAdapterWrapper::~ModelAdapterWrapper()
290 {
291 // Destroy resource explicitly before destruct
292 }
293
GetKey()294 uint32_t ModelAdapterWrapper::GetKey()
295 {
296 return key_;
297 }
298
SetPaintFinishCallback(PaintFinishCallback callback)299 void ModelAdapterWrapper::SetPaintFinishCallback(PaintFinishCallback callback)
300 {
301 callback_ = std::move(callback);
302 }
303
HandleTouchEvent(const TouchEventInfo & info,const RefPtr<ModelPaintProperty> & modelPaintProperty)304 bool ModelAdapterWrapper::HandleTouchEvent(const TouchEventInfo& info,
305 const RefPtr<ModelPaintProperty>& modelPaintProperty)
306 {
307 CHECK_NULL_RETURN(touchHandler_, false);
308 CHECK_NULL_RETURN(textureLayer_, false);
309 const auto& textureInfo = textureLayer_->GetTextureInfo();
310 auto width = textureInfo.width_;
311 auto height = textureInfo.height_;
312 auto cameraState = modelPaintProperty->GetModelCameraMove().value_or(true);
313 touchHandler_->HandleCameraEvents(cameraState);
314 return touchHandler_->HandleTouchEvent(info, width, height);
315 }
316
UpdateScene(const RefPtr<ModelPaintProperty> & modelPaintProperty)317 void ModelAdapterWrapper::UpdateScene(const RefPtr<ModelPaintProperty>& modelPaintProperty)
318 {
319 #if defined(KIT_3D_ENABLE)
320 if (sceneAdapter_) {
321 return;
322 }
323 #endif
324 if (modelPaintProperty->GetModelSourceValue().empty()) {
325 LOGW("UpdateScene invalid model source");
326 return;
327 }
328
329 auto& modelSource = modelPaintProperty->GetModelSource().value();
330 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), modelSource] {
331 auto adapter = weak.Upgrade();
332 CHECK_NULL_VOID(adapter);
333 CHECK_NULL_VOID(adapter->widgetAdapter_);
334
335 adapter->widgetAdapter_->LoadSceneModel(modelSource.c_str());
336 });
337 }
338
UpdateEnviroment(const RefPtr<ModelPaintProperty> & modelPaintProperty)339 void ModelAdapterWrapper::UpdateEnviroment(const RefPtr<ModelPaintProperty>& modelPaintProperty)
340 {
341 #if defined(KIT_3D_ENABLE)
342 if (sceneAdapter_) {
343 return;
344 }
345 #endif
346 if (modelPaintProperty->GetModelBackgroundValue().empty()) {
347 LOGW("UpdateEnviroment invalid model background");
348 return;
349 }
350
351 Render3D::BackgroundType backgroundType = modelPaintProperty->GetModelTransparent().value_or(false) ?
352 Render3D::BackgroundType::TRANSPARENT : Render3D::BackgroundType::CUBE_MAP;
353 auto& backgroundPath = modelPaintProperty->GetModelBackground().value();
354
355 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &backgroundPath,
356 &backgroundType] {
357 auto adapter = weak.Upgrade();
358 CHECK_NULL_VOID(adapter);
359 CHECK_NULL_VOID(adapter->widgetAdapter_);
360
361 adapter->widgetAdapter_->LoadEnvModel(backgroundPath, backgroundType);
362 });
363 }
364
HandleCameraMove(const Render3D::PointerEvent & event)365 void ModelAdapterWrapper::HandleCameraMove(const Render3D::PointerEvent& event)
366 {
367 #if defined(KIT_3D_ENABLE)
368 if (sceneAdapter_) {
369 return;
370 }
371 #endif
372 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &event] {
373 auto adapter = weak.Upgrade();
374 CHECK_NULL_VOID(adapter);
375 CHECK_NULL_VOID(adapter->widgetAdapter_);
376
377 adapter->widgetAdapter_->OnTouchEvent(event);
378 });
379 }
380
UpdateCustomRender(const RefPtr<ModelPaintProperty> & modelPaintProperty)381 void ModelAdapterWrapper::UpdateCustomRender(const RefPtr<ModelPaintProperty>& modelPaintProperty)
382 {
383 #if defined(KIT_3D_ENABLE)
384 if (sceneAdapter_) {
385 return;
386 }
387 #endif
388 auto& customRender = modelPaintProperty->GetModelCustomRender().value();
389 if (!customRender) {
390 LOGW("UpdateCustomRender invalid custom render");
391 return;
392 }
393
394 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &customRender] {
395 auto adapter = weak.Upgrade();
396 CHECK_NULL_VOID(adapter);
397 CHECK_NULL_VOID(adapter->widgetAdapter_);
398
399 adapter->widgetAdapter_->UpdateCustomRender(customRender);
400 });
401 }
402
UpdateShaderPath(const RefPtr<ModelPaintProperty> & modelPaintProperty)403 void ModelAdapterWrapper::UpdateShaderPath(const RefPtr<ModelPaintProperty>& modelPaintProperty)
404 {
405 #if defined(KIT_3D_ENABLE)
406 if (sceneAdapter_) {
407 return;
408 }
409 #endif
410 if (modelPaintProperty->GetShaderPathValue().empty()) {
411 LOGW("UpdateShaderPath invalid shader path");
412 return;
413 }
414
415 auto& shaderPath = modelPaintProperty->GetShaderPath().value();
416
417 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &shaderPath] {
418 auto adapter = weak.Upgrade();
419 CHECK_NULL_VOID(adapter);
420 CHECK_NULL_VOID(adapter->widgetAdapter_);
421
422 adapter->widgetAdapter_->UpdateShaderPath(shaderPath);
423 });
424 }
425
UpdateImageTexturePaths(const RefPtr<ModelPaintProperty> & modelPaintProperty)426 void ModelAdapterWrapper::UpdateImageTexturePaths(const RefPtr<ModelPaintProperty>& modelPaintProperty)
427 {
428 #if defined(KIT_3D_ENABLE)
429 if (sceneAdapter_) {
430 return;
431 }
432 #endif
433 if (modelPaintProperty->GetModelImageTexturePathsValue().empty()) {
434 LOGW("UpdateImageTexturePaths invalid image texture");
435 return;
436 }
437
438 auto& imageTexture = modelPaintProperty->GetModelImageTexturePaths().value();
439
440 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &imageTexture] {
441 auto adapter = weak.Upgrade();
442 CHECK_NULL_VOID(adapter);
443 CHECK_NULL_VOID(adapter->widgetAdapter_);
444
445 adapter->widgetAdapter_->UpdateImageTexturePaths(imageTexture);
446 });
447 }
448
UpdateShaderInputBuffers(const RefPtr<ModelPaintProperty> & modelPaintProperty)449 void ModelAdapterWrapper::UpdateShaderInputBuffers(const RefPtr<ModelPaintProperty>& modelPaintProperty)
450 {
451 #if defined(KIT_3D_ENABLE)
452 if (sceneAdapter_) {
453 return;
454 }
455 #endif
456 if (modelPaintProperty->GetModelShaderInputBufferValue() == nullptr) {
457 LOGW("UpdateShaderInputBuffers invalid shader input buffer");
458 return;
459 }
460
461 auto& shaderInputBuffer = modelPaintProperty->GetModelShaderInputBuffer().value();
462
463 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &shaderInputBuffer] {
464 auto adapter = weak.Upgrade();
465 CHECK_NULL_VOID(adapter);
466 CHECK_NULL_VOID(adapter->widgetAdapter_);
467
468 adapter->widgetAdapter_->UpdateShaderInputBuffer(shaderInputBuffer);
469 });
470 }
471 } // namespace OHOS::Ace::NG
472