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