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 if (textureLayer_) {
68 textureLayer_->DestroyRenderTarget();
69 }
70 return std::shared_future<void>();
71 }
72 #endif
73 std::shared_ptr<Render3D::WidgetAdapter> widgetAdapter(widgetAdapter_);
74 auto key = key_;
75 if (textureLayer_) {
76 textureLayer_->DestroyRenderTarget();
77 }
78 return Render3D::GraphicsTask::GetInstance().PushAsyncMessage([widgetAdapter, key] {
79 ACE_SCOPED_TRACE("ModelAdapterWrapper::Deinit render");
80
81 CHECK_NULL_VOID(widgetAdapter);
82 widgetAdapter->DeInitEngine();
83 Render3D::GraphicsManager::GetInstance().UnRegister(key);
84 });
85 }
86
CreateTextureLayer()87 void ModelAdapterWrapper::CreateTextureLayer()
88 {
89 #if defined(KIT_3D_ENABLE)
90 if (sceneAdapter_) {
91 return;
92 }
93 #endif
94 const auto& key = GetKey();
95 textureLayer_ = std::make_shared<Render3D::TextureLayer>(key);
96 Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), key] {
97 auto adapter = weak.Upgrade();
98 CHECK_NULL_VOID(adapter);
99
100 auto& gfxManager = Render3D::GraphicsManager::GetInstance();
101 gfxManager.Register(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 CHECK_NULL_VOID(textureLayer_);
159 textureLayer_->OnWindowChange(windowChangeInfo);
160 const auto textureInfo = textureLayer_->GetTextureInfo();
161 Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), textureInfo] {
162 auto adapter = weak.Upgrade();
163 CHECK_NULL_VOID(adapter);
164 CHECK_NULL_VOID(adapter->widgetAdapter_);
165
166 adapter->widgetAdapter_->OnWindowChange(textureInfo);
167 });
168 }
169
OnRebuildFrame(RefPtr<RenderContext> & context)170 void ModelAdapterWrapper::OnRebuildFrame(RefPtr<RenderContext>& context)
171 {
172 #ifdef ENABLE_ROSEN_BACKEND
173 auto rsContext = DynamicCast<NG::RosenRenderContext>(context);
174 CHECK_NULL_VOID(rsContext);
175 auto rsNode = rsContext->GetRSNode();
176 CHECK_NULL_VOID(textureLayer_);
177 textureLayer_->SetParent(rsNode);
178 #endif
179 }
180
OnPaint3D(const RefPtr<ModelPaintProperty> & modelPaintProperty)181 void ModelAdapterWrapper::OnPaint3D(const RefPtr<ModelPaintProperty>& modelPaintProperty)
182 {
183 CHECK_NULL_VOID(modelPaintProperty);
184
185 if (modelPaintProperty->NeedsModelSourceSetup()) {
186 UpdateScene(modelPaintProperty);
187 }
188
189 if (modelPaintProperty->NeedsModelBackgroundSetup()) {
190 UpdateEnviroment(modelPaintProperty);
191 }
192
193 if (modelPaintProperty->NeedsCustomRenderSetup()) {
194 UpdateCustomRender(modelPaintProperty);
195 }
196
197 if (modelPaintProperty->NeedsShaderPathSetup()) {
198 UpdateShaderPath(modelPaintProperty);
199 }
200
201 if (modelPaintProperty->NeedsImageTexturePathsSetup()) {
202 UpdateImageTexturePaths(modelPaintProperty);
203 }
204
205 if (modelPaintProperty->NeedsShaderInputBufferSetup()) {
206 UpdateShaderInputBuffers(modelPaintProperty);
207 }
208
209 DrawFrame();
210 }
211
DrawFrame()212 void ModelAdapterWrapper::DrawFrame()
213 {
214 ACE_FUNCTION_TRACE();
215 #if defined(KIT_3D_ENABLE)
216 if (sceneAdapter_) {
217 sceneAdapter_->RenderFrame(needsSyncPaint_);
218 needsRepaint_ = sceneAdapter_->NeedsRepaint();
219 needsSyncPaint_ = false;
220 return;
221 }
222 #endif
223 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
224 auto adapter = weak.Upgrade();
225 CHECK_NULL_VOID(adapter);
226 CHECK_NULL_VOID(adapter->widgetAdapter_);
227
228 adapter->needsRepaint_ = adapter->widgetAdapter_->NeedsRepaint();
229 });
230
231 const auto& msg = [weak = WeakClaim(this)] {
232 auto adapter = weak.Upgrade();
233 CHECK_NULL_VOID(adapter);
234 CHECK_NULL_VOID(adapter->widgetAdapter_);
235
236 adapter->widgetAdapter_->DrawFrame();
237 };
238
239 if (needsSyncPaint_) {
240 #if !defined (MULTI_ECS_UPDATE_AT_ONCE) || (MULTI_ECS_UPDATE_AT_ONCE == 0)
241 needsSyncPaint_ = false;
242 #endif
243 Render3D::GraphicsTask::GetInstance().PushSyncMessage(msg);
244 } else {
245 Render3D::GraphicsTask::GetInstance().PushAsyncMessage(msg);
246 }
247 }
248
OnPaintFinish()249 void ModelAdapterWrapper::OnPaintFinish()
250 {
251 if (callback_) {
252 callback_();
253 }
254 }
255
UnloadSceneAndBackground()256 void ModelAdapterWrapper::UnloadSceneAndBackground()
257 {
258 #if defined(KIT_3D_ENABLE)
259 if (sceneAdapter_) {
260 return;
261 }
262 #endif
263 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
264 auto adapter = weak.Upgrade();
265 CHECK_NULL_VOID(adapter);
266 CHECK_NULL_VOID(adapter->widgetAdapter_);
267
268 adapter->widgetAdapter_->UnloadSceneModel();
269 adapter->widgetAdapter_->UnloadEnvModel();
270 });
271 }
272
NeedsRepaint()273 bool ModelAdapterWrapper::NeedsRepaint()
274 {
275 return needsRepaint_;
276 }
277
~ModelAdapterWrapper()278 ModelAdapterWrapper::~ModelAdapterWrapper()
279 {
280 // Destroy resource explicitly before destruct
281 }
282
GetKey()283 uint32_t ModelAdapterWrapper::GetKey()
284 {
285 return key_;
286 }
287
SetPaintFinishCallback(PaintFinishCallback callback)288 void ModelAdapterWrapper::SetPaintFinishCallback(PaintFinishCallback callback)
289 {
290 callback_ = std::move(callback);
291 }
292
HandleTouchEvent(const TouchEventInfo & info,const RefPtr<ModelPaintProperty> & modelPaintProperty)293 bool ModelAdapterWrapper::HandleTouchEvent(const TouchEventInfo& info,
294 const RefPtr<ModelPaintProperty>& modelPaintProperty)
295 {
296 CHECK_NULL_RETURN(touchHandler_, false);
297 CHECK_NULL_RETURN(textureLayer_, false);
298 const auto& textureInfo = textureLayer_->GetTextureInfo();
299 auto width = textureInfo.width_;
300 auto height = textureInfo.height_;
301 auto cameraState = modelPaintProperty->GetModelCameraMove().value_or(true);
302 touchHandler_->HandleCameraEvents(cameraState);
303 return touchHandler_->HandleTouchEvent(info, width, height);
304 }
305
UpdateScene(const RefPtr<ModelPaintProperty> & modelPaintProperty)306 void ModelAdapterWrapper::UpdateScene(const RefPtr<ModelPaintProperty>& modelPaintProperty)
307 {
308 #if defined(KIT_3D_ENABLE)
309 if (sceneAdapter_) {
310 return;
311 }
312 #endif
313 if (modelPaintProperty->GetModelSourceValue().empty()) {
314 LOGW("UpdateScene invalid model source");
315 return;
316 }
317
318 auto& modelSource = modelPaintProperty->GetModelSource().value();
319 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), modelSource] {
320 auto adapter = weak.Upgrade();
321 CHECK_NULL_VOID(adapter);
322 CHECK_NULL_VOID(adapter->widgetAdapter_);
323
324 adapter->widgetAdapter_->LoadSceneModel(modelSource.c_str());
325 });
326 }
327
UpdateEnviroment(const RefPtr<ModelPaintProperty> & modelPaintProperty)328 void ModelAdapterWrapper::UpdateEnviroment(const RefPtr<ModelPaintProperty>& modelPaintProperty)
329 {
330 #if defined(KIT_3D_ENABLE)
331 if (sceneAdapter_) {
332 return;
333 }
334 #endif
335 if (modelPaintProperty->GetModelBackgroundValue().empty()) {
336 LOGW("UpdateEnviroment invalid model background");
337 return;
338 }
339
340 Render3D::BackgroundType backgroundType = modelPaintProperty->GetModelTransparent().value_or(false) ?
341 Render3D::BackgroundType::TRANSPARENT : Render3D::BackgroundType::CUBE_MAP;
342 auto& backgroundPath = modelPaintProperty->GetModelBackground().value();
343
344 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &backgroundPath,
345 &backgroundType] {
346 auto adapter = weak.Upgrade();
347 CHECK_NULL_VOID(adapter);
348 CHECK_NULL_VOID(adapter->widgetAdapter_);
349
350 adapter->widgetAdapter_->LoadEnvModel(backgroundPath, backgroundType);
351 });
352 }
353
HandleCameraMove(const Render3D::PointerEvent & event)354 void ModelAdapterWrapper::HandleCameraMove(const Render3D::PointerEvent& event)
355 {
356 #if defined(KIT_3D_ENABLE)
357 if (sceneAdapter_) {
358 return;
359 }
360 #endif
361 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &event] {
362 auto adapter = weak.Upgrade();
363 CHECK_NULL_VOID(adapter);
364 CHECK_NULL_VOID(adapter->widgetAdapter_);
365
366 adapter->widgetAdapter_->OnTouchEvent(event);
367 });
368 }
369
UpdateCustomRender(const RefPtr<ModelPaintProperty> & modelPaintProperty)370 void ModelAdapterWrapper::UpdateCustomRender(const RefPtr<ModelPaintProperty>& modelPaintProperty)
371 {
372 #if defined(KIT_3D_ENABLE)
373 if (sceneAdapter_) {
374 return;
375 }
376 #endif
377 auto& customRender = modelPaintProperty->GetModelCustomRender().value();
378 if (!customRender) {
379 LOGW("UpdateCustomRender invalid custom render");
380 return;
381 }
382
383 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &customRender] {
384 auto adapter = weak.Upgrade();
385 CHECK_NULL_VOID(adapter);
386 CHECK_NULL_VOID(adapter->widgetAdapter_);
387
388 adapter->widgetAdapter_->UpdateCustomRender(customRender);
389 });
390 }
391
UpdateShaderPath(const RefPtr<ModelPaintProperty> & modelPaintProperty)392 void ModelAdapterWrapper::UpdateShaderPath(const RefPtr<ModelPaintProperty>& modelPaintProperty)
393 {
394 #if defined(KIT_3D_ENABLE)
395 if (sceneAdapter_) {
396 return;
397 }
398 #endif
399 if (modelPaintProperty->GetShaderPathValue().empty()) {
400 LOGW("UpdateShaderPath invalid shader path");
401 return;
402 }
403
404 auto& shaderPath = modelPaintProperty->GetShaderPath().value();
405
406 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &shaderPath] {
407 auto adapter = weak.Upgrade();
408 CHECK_NULL_VOID(adapter);
409 CHECK_NULL_VOID(adapter->widgetAdapter_);
410
411 adapter->widgetAdapter_->UpdateShaderPath(shaderPath);
412 });
413 }
414
UpdateImageTexturePaths(const RefPtr<ModelPaintProperty> & modelPaintProperty)415 void ModelAdapterWrapper::UpdateImageTexturePaths(const RefPtr<ModelPaintProperty>& modelPaintProperty)
416 {
417 #if defined(KIT_3D_ENABLE)
418 if (sceneAdapter_) {
419 return;
420 }
421 #endif
422 if (modelPaintProperty->GetModelImageTexturePathsValue().empty()) {
423 LOGW("UpdateImageTexturePaths invalid image texture");
424 return;
425 }
426
427 auto& imageTexture = modelPaintProperty->GetModelImageTexturePaths().value();
428
429 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &imageTexture] {
430 auto adapter = weak.Upgrade();
431 CHECK_NULL_VOID(adapter);
432 CHECK_NULL_VOID(adapter->widgetAdapter_);
433
434 adapter->widgetAdapter_->UpdateImageTexturePaths(imageTexture);
435 });
436 }
437
UpdateShaderInputBuffers(const RefPtr<ModelPaintProperty> & modelPaintProperty)438 void ModelAdapterWrapper::UpdateShaderInputBuffers(const RefPtr<ModelPaintProperty>& modelPaintProperty)
439 {
440 #if defined(KIT_3D_ENABLE)
441 if (sceneAdapter_) {
442 return;
443 }
444 #endif
445 if (modelPaintProperty->GetModelShaderInputBufferValue() == nullptr) {
446 LOGW("UpdateShaderInputBuffers invalid shader input buffer");
447 return;
448 }
449
450 auto& shaderInputBuffer = modelPaintProperty->GetModelShaderInputBuffer().value();
451
452 Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &shaderInputBuffer] {
453 auto adapter = weak.Upgrade();
454 CHECK_NULL_VOID(adapter);
455 CHECK_NULL_VOID(adapter->widgetAdapter_);
456
457 adapter->widgetAdapter_->UpdateShaderInputBuffer(shaderInputBuffer);
458 });
459 }
460 } // namespace OHOS::Ace::NG
461