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