1 /*
2 * Copyright (c) 2024 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 #include "window_scene_layout_manager.h"
16
17 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
18 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
19 #include "core/components_ng/pattern/window_scene/scene/window_scene.h"
20 #include "core/components_ng/pattern/window_scene/scene/panel_scene.h"
21 #include "core/components_ng/pattern/window_scene/scene/input_scene.h"
22 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
23 #include "core/components_ng/pattern/window_scene/screen/screen_pattern.h"
24 #include "core/components_ng/render/adapter/rosen_render_context.h"
25 #include "core/pipeline_ng/pipeline_context.h"
26 #include "parameters.h"
27 #include "session/host/include/session.h"
28 #include "session_manager/include/scene_session_manager.h"
29
30 namespace {
31 constexpr uint64_t SCREEN_ID_INVALID = -1ULL;
32 constexpr float EPSILON = 1e-3;
33 }
34 namespace OHOS::Ace::NG {
GetInstance()35 WindowSceneLayoutManager* WindowSceneLayoutManager::GetInstance()
36 {
37 auto container = Container::Current();
38 if (!container || !container->IsScenceBoardWindow() || !Rosen::Session::IsScbCoreEnabled()) {
39 return nullptr;
40 }
41 static WindowSceneLayoutManager* instance = nullptr;
42 if (instance == nullptr) {
43 instance = new WindowSceneLayoutManager();
44 instance->Init();
45 }
46 return instance;
47 }
48
Init()49 void WindowSceneLayoutManager::Init()
50 {
51 Rosen::SceneSessionManager::GetInstance().SetDumpUITreeFunc(
52 [this](std::string& info) {
53 isCoreDebugEnable_ = system::GetParameter("debug.window.coredebug.enabled", "0") == "1";
54 GetTotalUITreeInfo(info);
55 }
56 );
57 }
58
IsNodeDirty(const RefPtr<FrameNode> & node)59 bool WindowSceneLayoutManager::IsNodeDirty(const RefPtr<FrameNode>& node)
60 {
61 auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
62 CHECK_NULL_RETURN(context, false);
63 auto rsNode = context->GetRSNode();
64 CHECK_NULL_RETURN(rsNode, false);
65 return rsNode->IsAppearanceDirty() || rsNode->IsGeometryDirty();
66 }
67
IsNodeVisible(const RefPtr<FrameNode> & node)68 bool WindowSceneLayoutManager::IsNodeVisible(const RefPtr<FrameNode>& node)
69 {
70 CHECK_NULL_RETURN(node, false);
71 auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
72 CHECK_NULL_RETURN(context, false);
73 auto rsNode = context->GetRSNode();
74 CHECK_NULL_RETURN(rsNode, false);
75 bool isVisible = node->IsVisible();
76 float opacityVal = context->GetOpacityValue(1.0f);
77 bool opaque = (opacityVal - 0.0f) > std::numeric_limits<float>::epsilon();
78 bool ret = isVisible && opaque;
79 if (isCoreDebugEnable_) {
80 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "winId:%{public}d name:%{public}s frameNodeId:%{public}d"
81 "isVisible:%{public}d opaque:%{public}f ret:%{public}d", GetWindowId(node),
82 GetWindowName(node).c_str(), node->GetId(), isVisible, opacityVal, ret);
83 }
84 return ret;
85 }
86
GetNodeZIndex(const RefPtr<FrameNode> & node)87 int32_t WindowSceneLayoutManager::GetNodeZIndex(const RefPtr<FrameNode>& node)
88 {
89 CHECK_NULL_RETURN(node, ZINDEX_DEFAULT_VALUE);
90 auto context = node->GetRenderContext();
91 CHECK_NULL_RETURN(context, ZINDEX_DEFAULT_VALUE);
92 return context->GetZIndexValue(ZINDEX_DEFAULT_VALUE);
93 }
94
GetScreenId(const RefPtr<FrameNode> & screenNode)95 uint64_t WindowSceneLayoutManager::GetScreenId(const RefPtr<FrameNode>& screenNode)
96 {
97 CHECK_NULL_RETURN(screenNode, SCREEN_ID_INVALID);
98 auto pattern = screenNode->GetPattern<ScreenPattern>();
99 CHECK_NULL_RETURN(pattern, SCREEN_ID_INVALID);
100 auto screenSession = pattern->GetScreenSession();
101 CHECK_NULL_RETURN(screenSession, SCREEN_ID_INVALID);
102 return screenSession->GetScreenId();
103 }
104
UpdateGeometry(const RefPtr<FrameNode> & node,const RefPtr<FrameNode> & parentNode,bool isParentTransformScene)105 void WindowSceneLayoutManager::UpdateGeometry(const RefPtr<FrameNode>& node, const RefPtr<FrameNode>& parentNode,
106 bool isParentTransformScene)
107 {
108 CHECK_NULL_VOID(node);
109 auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
110 CHECK_NULL_VOID(context);
111 auto rsNode = context->GetRSNode();
112 CHECK_NULL_VOID(rsNode);
113 auto globalGeometry = isParentTransformScene ? std::make_shared<Rosen::RSObjAbsGeometry>()
114 : GetGlobalGeometry(parentNode);
115 if (!globalGeometry) {
116 if (!WindowSceneHelper::IsScreenScene(node->GetWindowPatternType())) {
117 TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE, "windowName:%{public}s, global geo is null and new",
118 GetWindowName(node).c_str());
119 }
120 globalGeometry = std::make_shared<Rosen::RSObjAbsGeometry>();
121 }
122 rsNode->UpdateLocalGeometry();
123 if (WindowSceneHelper::IsTransformScene(node->GetWindowPatternType())) {
124 // once current transform scene, set pos/trans 0, to make global position relative to transform scene
125 if (auto localGeo = rsNode->GetLocalGeometry()) {
126 localGeo->SetPosition(0.0f, 0.0f);
127 localGeo->SetTranslateX(0.0f);
128 localGeo->SetTranslateY(0.0f);
129 } else {
130 TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE, "windowName:%{public}s, local geo is null",
131 GetWindowName(node).c_str());
132 }
133 }
134 rsNode->UpdateGlobalGeometry(globalGeometry);
135 rsNode->MarkDirty(Rosen::NodeDirtyType::GEOMETRY, false);
136 rsNode->MarkDirty(Rosen::NodeDirtyType::APPEARANCE, false);
137 DumpNodeInfo(node, parentNode, "UpdateGeometry");
138 }
139
GetRSNode(const RefPtr<FrameNode> & node)140 std::shared_ptr<Rosen::RSNode> WindowSceneLayoutManager::GetRSNode(const RefPtr<FrameNode>& node)
141 {
142 CHECK_NULL_RETURN(node, nullptr);
143 auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
144 CHECK_NULL_RETURN(context, nullptr);
145 return context->GetRSNode();
146 }
147
GetGlobalGeometry(const RefPtr<FrameNode> & node)148 std::shared_ptr<Rosen::RSObjAbsGeometry> WindowSceneLayoutManager::GetGlobalGeometry(const RefPtr<FrameNode>& node)
149 {
150 auto rsNode = GetRSNode(node);
151 CHECK_NULL_RETURN(rsNode, nullptr);
152 return rsNode->GetGlobalGeometry();
153 }
154
GetLocalGeometry(const RefPtr<FrameNode> & node)155 std::shared_ptr<Rosen::RSObjAbsGeometry> WindowSceneLayoutManager::GetLocalGeometry(const RefPtr<FrameNode>& node)
156 {
157 auto rsNode = GetRSNode(node);
158 CHECK_NULL_RETURN(rsNode, nullptr);
159 return rsNode->GetLocalGeometry();
160 }
161
FillWindowSceneInfo(const RefPtr<FrameNode> & node,TraverseResult & res,bool isAncestorRecent,bool notSyncPosition)162 void WindowSceneLayoutManager::FillWindowSceneInfo(const RefPtr<FrameNode>& node,
163 TraverseResult& res, bool isAncestorRecent, bool notSyncPosition)
164 {
165 auto rsNode = GetRSNode(node);
166 if (!rsNode) {
167 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s rsNode is null", GetWindowName(node).c_str());
168 return;
169 }
170 IsFrameNodeAbnormal(node);
171 auto globalGeometry = isAncestorRecent ? std::make_shared<Rosen::RSObjAbsGeometry>()
172 : rsNode->GetGlobalGeometry();
173 auto localGeometry = rsNode->GetLocalGeometry();
174 if (isAncestorRecent && !localGeometry) {
175 localGeometry = std::make_shared<Rosen::RSObjAbsGeometry>();
176 }
177 if (!globalGeometry || !localGeometry) {
178 if (isCoreDebugEnable_) {
179 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s globalGeo is null:%{public}d localGeo:%{public}d",
180 GetWindowName(node).c_str(), globalGeometry == nullptr, localGeometry == nullptr);
181 }
182 return;
183 }
184 Rosen::SessionUIParam uiParam;
185 auto width = localGeometry->GetWidth();
186 auto height = localGeometry->GetHeight();
187 if (std::abs(width - 0.0f) < EPSILON || std::abs(height - 0.0f) < EPSILON) {
188 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s w:%{public}f h:%{public}f is 0",
189 GetWindowName(node).c_str(), width, height);
190 return;
191 }
192 if (isAncestorRecent) {
193 uiParam.rect_ = { localGeometry->GetX(), localGeometry->GetY(), width, height };
194 } else {
195 auto absRect = globalGeometry->GetAbsRect();
196 uiParam.rect_ = { absRect.GetLeft(), absRect.GetTop(), width, height };
197 uiParam.scaleX_ = absRect.GetWidth() / width;
198 uiParam.scaleY_ = absRect.GetHeight() / height;
199 }
200 uiParam.needSync_ = notSyncPosition ? false : true;
201 auto matrix = globalGeometry->GetAbsMatrix();
202 uiParam.transX_ = std::round(matrix.Get(Rosen::Drawing::Matrix::TRANS_X) - rsNode->GetGlobalPositionX());
203 uiParam.transY_ = std::round(matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) - rsNode->GetGlobalPositionY());
204 uiParam.pivotX_ = globalGeometry->GetPivotX();
205 uiParam.pivotY_ = globalGeometry->GetPivotY();
206 uiParam.zOrder_ = res.zOrderCnt_;
207 auto windowId = GetWindowId(node);
208 uiParam.sessionName_ = GetWindowName(node);
209 if (isAncestorRecent) {
210 // panel scene self should be interactive, others should be false
211 // default interactive is true
212 uiParam.interactive_ = WindowSceneHelper::IsPanelScene(node->GetWindowPatternType());
213 }
214 res.uiParams_[windowId] = std::move(uiParam);
215 }
216
FlushWindowPatternInfo(const RefPtr<FrameNode> & screenNode)217 void WindowSceneLayoutManager::FlushWindowPatternInfo(const RefPtr<FrameNode>& screenNode)
218 {
219 if (isCoreDebugEnable_) {
220 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "------------------- Begin FlushWindowPatternInfo ------------------");
221 }
222 auto screenId = GetScreenId(screenNode);
223 if (screenId == SCREEN_ID_INVALID) {
224 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE,
225 "tag:%{public}s screenId:%{public}" PRIu64, screenNode->GetTag().c_str(), screenId);
226 return;
227 }
228 TraverseResult res;
229 res.zOrderCnt_ = 0;
230 res.screenId_ = screenId;
231 UpdateGeometry(screenNode, nullptr, false);
232 TraverseTree(screenNode, res, false, IsNodeDirty(screenNode), false);
233 if (isCoreDebugEnable_) {
234 DumpFlushInfo(screenId, res);
235 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "------------------- End FlushWindowPatternInfo ------------------");
236 }
237 // cannot post ui task, since flush may not excute on next frame
238 Rosen::SceneSessionManager::GetInstance().FlushUIParams(screenId, std::move(res.uiParams_));
239 }
240
IsRecentContainerState(const RefPtr<FrameNode> & node)241 bool WindowSceneLayoutManager::IsRecentContainerState(const RefPtr<FrameNode>& node)
242 {
243 CHECK_NULL_RETURN(node, false);
244 if (!WindowSceneHelper::IsPanelScene(node->GetWindowPatternType())) {
245 return false;
246 }
247 auto windowPattern = node->GetPattern<PanelScene>();
248 if (windowPattern == nullptr) {
249 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent SystemWindowScene is null. node:%{public}s",
250 GetWindowName(node).c_str());
251 return false;
252 }
253 auto session = windowPattern->GetSession();
254 if (session == nullptr) {
255 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent session is null. node:%{public}s",
256 GetWindowName(node).c_str());
257 return false;
258 }
259 return session->GetSystemTouchable();
260 }
261
NoNeedSyncScenePanelGlobalPosition(const RefPtr<FrameNode> & node)262 bool WindowSceneLayoutManager::NoNeedSyncScenePanelGlobalPosition(const RefPtr<FrameNode>& node) // false: need sync
263 {
264 CHECK_NULL_RETURN(node, false);
265 if (!WindowSceneHelper::IsPanelScene(node->GetWindowPatternType())) {
266 return false;
267 }
268 auto windowPattern = node->GetPattern<PanelScene>();
269 if (windowPattern == nullptr) {
270 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent SystemWindowScene is null. node:%{public}s",
271 GetWindowName(node).c_str());
272 return false;
273 }
274 auto session = windowPattern->GetSession();
275 if (session == nullptr) {
276 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent session is null. node:%{public}s",
277 GetWindowName(node).c_str());
278 return false;
279 }
280 return !session->IsNeedSyncScenePanelGlobalPosition();
281 }
282
IsFrameNodeAbnormal(const RefPtr<FrameNode> & node)283 void WindowSceneLayoutManager::IsFrameNodeAbnormal(const RefPtr<FrameNode>& node)
284 {
285 CHECK_NULL_VOID(node);
286 if (node->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
287 return;
288 }
289 auto windowScene = node->GetPattern<WindowScene>();
290 CHECK_NULL_VOID(windowScene);
291 auto session = windowScene->GetSession();
292 CHECK_NULL_VOID(session);
293 auto surfaceNode = session->GetSurfaceNode();
294 CHECK_NULL_VOID(surfaceNode);
295 if (!surfaceNode->GetParent()) {
296 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "node:%{public}d name:%{public}s is on ui tree but not rs tree, "
297 "screenId:%{public}" PRIu64, node->GetId(), GetWindowName(node).c_str(), GetScreenId(node));
298 }
299 }
300
TraverseTree(const RefPtr<FrameNode> & rootNode,TraverseResult & res,bool isAncestorRecent,bool isAncestorDirty,bool notSyncPosition)301 void WindowSceneLayoutManager::TraverseTree(const RefPtr<FrameNode>& rootNode, TraverseResult& res,
302 bool isAncestorRecent, bool isAncestorDirty, bool notSyncPosition)
303 {
304 CHECK_NULL_VOID(rootNode);
305 auto parentType = rootNode->GetWindowPatternType();
306 for (auto& weakNode : rootNode->GetFrameChildren()) {
307 auto node = weakNode.Upgrade();
308 // when current layer is invisible, no need traverse next
309 if (!node || !IsNodeVisible(node)) {
310 continue;
311 }
312 // once delete in recent, need update Zorder
313 uint32_t currentZorder = res.zOrderCnt_;
314 if (WindowSceneHelper::IsWindowPattern(node)) {
315 currentZorder = std::max(res.zOrderCnt_, static_cast<uint32_t>(GetNodeZIndex(node)));
316 }
317 // only window pattern need cal zorder
318 bool hasWindowSession = WindowSceneHelper::HasWindowSession(node);
319 if (hasWindowSession) {
320 res.zOrderCnt_ = currentZorder++; // keep last zorder as current zorder
321 }
322 notSyncPosition = (notSyncPosition || NoNeedSyncScenePanelGlobalPosition(node));
323 // process recent and child node
324 if (isAncestorRecent || IsRecentContainerState(node)) {
325 isAncestorRecent = true;
326 } else {
327 if (isAncestorDirty || IsNodeDirty(node)) {
328 isAncestorDirty = true;
329 UpdateGeometry(node, rootNode, WindowSceneHelper::IsTransformScene(parentType));
330 }
331 }
332 // only window pattern but not transform scene need sync info
333 if (hasWindowSession) {
334 FillWindowSceneInfo(node, res, isAncestorRecent, notSyncPosition);
335 DumpNodeInfo(node, rootNode, "AfterFillWindowSceneInfo");
336 }
337
338 res.zOrderCnt_ = currentZorder; // use cnt++ for next zorder cnt
339 auto type = node->GetWindowPatternType();
340 if (!WindowSceneHelper::IsSystemWindowScene(type) && WindowSceneHelper::IsSystemWindowScene(parentType)) {
341 TAG_LOGD(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s child of systemScene continue",
342 GetWindowName(node).c_str());
343 continue; // calculate last system window scene next layer
344 }
345 if (isCoreDebugEnable_) {
346 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "finish TraverseTree winId:%{public}d name:%{public}s"
347 "idName:%{public}s tag:%{public}s zorder:%{public}u isAncestorRecent:%{public}d "
348 "isAncestorDirty:%{public}d hasWindowSession:%{public}d notSyncPosition:%{public}d",
349 GetWindowId(node), GetWindowName(node).c_str(),
350 node->GetInspectorId()->c_str(), node->GetTag().c_str(), res.zOrderCnt_,
351 isAncestorRecent, isAncestorDirty, hasWindowSession, notSyncPosition);
352 }
353 TraverseTree(node, res, isAncestorRecent, isAncestorDirty, notSyncPosition);
354 }
355 }
356
357 // dump funcs
358 template<typename T>
GetWindowIdInner(const RefPtr<T> & windowPattern)359 uint32_t WindowSceneLayoutManager::GetWindowIdInner(const RefPtr<T>& windowPattern)
360 {
361 if (windowPattern == nullptr) {
362 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "windowPattern is null");
363 return 0;
364 }
365 auto session = windowPattern->GetSession();
366 if (session == nullptr) {
367 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "window session is null");
368 return 0;
369 }
370 return session->GetWindowId();
371 }
372
GetWindowId(const RefPtr<FrameNode> & node)373 uint32_t WindowSceneLayoutManager::GetWindowId(const RefPtr<FrameNode>& node)
374 {
375 CHECK_NULL_RETURN(node, 0);
376
377 auto type = static_cast<WindowPatternType>(node->GetWindowPatternType());
378 switch (type) {
379 case WindowPatternType::DEFAULT:
380 case WindowPatternType::TRANSFORM_SCENE:
381 return 0; // invalid window Id
382 case WindowPatternType::PANEL_SCENE:
383 return GetWindowIdInner(node->GetPattern<PanelScene>());
384 case WindowPatternType::INPUT_SCENE:
385 return GetWindowIdInner(node->GetPattern<InputScene>());
386 case WindowPatternType::SYSTEM_WINDOW_SCENE: {
387 auto windowPattern = node->GetPattern<SystemWindowScene>();
388 if (windowPattern == nullptr || windowPattern->GetSession() == nullptr) {
389 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "SystemWindowScene or session is null. type:%{public}u", type);
390 return 0;
391 }
392 return GetWindowIdInner(node->GetPattern<SystemWindowScene>());
393 }
394 case WindowPatternType::WINDOW_SCENE: {
395 return GetWindowIdInner(node->GetPattern<WindowScene>());
396 }
397 default:
398 break;
399 }
400 return 0;
401 }
402
403 template<typename T>
GetWindowNameInner(const RefPtr<T> & windowPattern)404 std::string WindowSceneLayoutManager::GetWindowNameInner(const RefPtr<T>& windowPattern)
405 {
406 if (windowPattern == nullptr) {
407 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "windowPattern is null");
408 return {};
409 }
410 auto session = windowPattern->GetSession();
411 if (session == nullptr) {
412 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "window session is null");
413 return {};
414 }
415 return session->GetWindowName();
416 }
417
GetWindowName(const RefPtr<FrameNode> & node)418 std::string WindowSceneLayoutManager::GetWindowName(const RefPtr<FrameNode>& node)
419 {
420 CHECK_NULL_RETURN(node, "");
421 std::string name;
422 auto type = static_cast<WindowPatternType>(node->GetWindowPatternType());
423 switch (type) {
424 case WindowPatternType::DEFAULT:
425 case WindowPatternType::TRANSFORM_SCENE:
426 break;
427 case WindowPatternType::PANEL_SCENE: {
428 name = GetWindowNameInner(node->GetPattern<PanelScene>());
429 break;
430 }
431 case WindowPatternType::INPUT_SCENE: {
432 name = GetWindowNameInner(node->GetPattern<InputScene>());
433 break;
434 }
435 case WindowPatternType::SYSTEM_WINDOW_SCENE: {
436 name = GetWindowNameInner(node->GetPattern<SystemWindowScene>());
437 break;
438 }
439 case WindowPatternType::WINDOW_SCENE: {
440 name = GetWindowNameInner(node->GetPattern<WindowScene>());
441 break;
442 }
443 default:
444 break;
445 }
446 return name + "_" + node->GetInspectorIdValue("") + "_" + node->GetTag();
447 }
448
449
DumpFlushInfo(uint64_t screenId,TraverseResult & res)450 void WindowSceneLayoutManager::DumpFlushInfo(uint64_t screenId, TraverseResult& res)
451 {
452 if (!isCoreDebugEnable_) {
453 return;
454 }
455 for (auto& [winId, uiParam] : res.uiParams_) {
456 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "DumpFlushInfo screenId:%{public}" PRIu64 " windowId:%{public}d"
457 "name:%{public}s rect:%{public}s, scaleX:%{public}f, scaleY:%{public}f, transX:%{public}f"
458 "transY:%{public}f pivotX:%{public}f, pivotY:%{public}f zOrder:%{public}u, interactive:%{public}d",
459 screenId, winId, uiParam.sessionName_.c_str(), uiParam.rect_.ToString().c_str(), uiParam.scaleX_,
460 uiParam.scaleY_, uiParam.transX_, uiParam.transY_,
461 uiParam.pivotX_, uiParam.pivotY_, uiParam.zOrder_, uiParam.interactive_);
462 }
463 }
464
GetRSNodeId(const RefPtr<FrameNode> & node)465 uint64_t WindowSceneLayoutManager::GetRSNodeId(const RefPtr<FrameNode>& node)
466 {
467 auto rsNode = GetRSNode(node);
468 CHECK_NULL_RETURN(rsNode, 0);
469 return rsNode->GetId();
470 }
471
DumpNodeInfo(const RefPtr<FrameNode> & node,const RefPtr<FrameNode> & parentNode,const std::string & reason)472 void WindowSceneLayoutManager::DumpNodeInfo(const RefPtr<FrameNode>& node,
473 const RefPtr<FrameNode>& parentNode, const std::string& reason)
474 {
475 if (!isCoreDebugEnable_) {
476 return;
477 }
478 CHECK_NULL_VOID(node);
479 int32_t parentId = parentNode ? parentNode->GetId() : 0;
480 auto rsNode = GetRSNode(node);
481 CHECK_NULL_VOID(rsNode);
482 auto nodeGeometry = rsNode->GetGlobalGeometry();
483 if (!nodeGeometry) {
484 TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE,
485 "reason:%{public}s globalGeometry name:%{public}s lrsId:%{public}" PRIu64 " %{public}d"
486 "parentRSId:%{public}" PRIu64 " frameNodeId:%{public}d global geoMetry is null",
487 reason.c_str(), GetWindowName(node).c_str(), GetRSNodeId(node), node->GetId(),
488 GetRSNodeId(parentNode), parentId);
489 return;
490 }
491 auto nodeLocalGeometry = rsNode->GetLocalGeometry();
492 if (!nodeLocalGeometry) {
493 TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE,
494 "reason:%{public}s localGeometry name:%{public}s lrsId:%{public}" PRIu64 " parentRSId:%{public}" PRIu64 ""
495 " localGeo is null", reason.c_str(), GetWindowName(node).c_str(),
496 GetRSNodeId(node), GetRSNodeId(parentNode));
497 return;
498 }
499
500 Rosen::WSRect tempGlobal = { nodeGeometry->GetX(), nodeGeometry->GetY(),
501 nodeGeometry->GetWidth(), nodeGeometry->GetHeight() };
502 Rosen::WSRect tempLocal = { nodeLocalGeometry->GetX(), nodeLocalGeometry->GetY(),
503 nodeLocalGeometry->GetWidth(), nodeLocalGeometry->GetHeight() };
504 auto localMatrix = nodeLocalGeometry->GetAbsMatrix();
505 auto globalMatrix = nodeGeometry->GetAbsMatrix();
506 float localTransX = localMatrix.Get(Rosen::Drawing::Matrix::TRANS_X);
507 float localTransY = localMatrix.Get(Rosen::Drawing::Matrix::TRANS_Y);
508 float globalTransX = globalMatrix.Get(Rosen::Drawing::Matrix::TRANS_X);
509 float globalTransY = globalMatrix.Get(Rosen::Drawing::Matrix::TRANS_Y);
510 auto absGlobalRect = nodeGeometry->GetAbsRect();
511 auto absLocalRect = nodeLocalGeometry->GetAbsRect();
512 auto localScaleX = localMatrix.Get(Rosen::Drawing::Matrix::SCALE_X);
513 auto localScaleY = localMatrix.Get(Rosen::Drawing::Matrix::SCALE_Y);
514 auto gScaleX = globalMatrix.Get(Rosen::Drawing::Matrix::SCALE_X);
515 auto gScaleY = globalMatrix.Get(Rosen::Drawing::Matrix::SCALE_Y);
516 float globalPosX = rsNode->GetGlobalPositionX();
517 float globalPosY = rsNode->GetGlobalPositionY();
518 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE,
519 "DumpNodeInfo reason:%{public}s name:%{public}s lrsId:%{public}" PRIu64 " parentRSId:%{public}" PRIu64 " "
520 "frameNodeId:%{public}d [Rect:%{public}s lTransX:%{public}f lTransY:%{public}f absLocalRect:%{public}s, "
521 "gRect:%{public}s gTransX:%{public}f gTransY:%{public}f globalPosX:%{public}f, globalPosY:%{public}f, "
522 "absGlobalRect:%{public}s lScaleX:%{public}f lScaleY:%{public}f gScaleX:%{public}f gScaleY:%{public}f]",
523 GetWindowName(node).c_str(), reason.c_str(), GetRSNodeId(node), GetRSNodeId(parentNode), parentId,
524 tempLocal.ToString().c_str(), localTransX, localTransY,
525 absLocalRect.ToString().c_str(), tempGlobal.ToString().c_str(), globalTransX, globalTransY, globalPosX,
526 globalPosY, absGlobalRect.ToString().c_str(), localScaleX, localScaleY, gScaleX, gScaleY);
527 }
528
RegisterScreenNode(uint64_t screenId,const RefPtr<FrameNode> & node)529 void WindowSceneLayoutManager::RegisterScreenNode(uint64_t screenId, const RefPtr<FrameNode>& node)
530 {
531 screenNodeMap_[screenId] = WeakPtr<FrameNode>(node);
532 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "screenNode:%{public}" PRIu64 " register, size:%{public}d",
533 screenId, static_cast<uint32_t>(screenNodeMap_.size()));
534 }
535
UnregisterScreenNode(uint64_t screenId)536 void WindowSceneLayoutManager::UnregisterScreenNode(uint64_t screenId)
537 {
538 screenNodeMap_.erase(screenId);
539 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "screenNode:%{public}" PRIu64 " unregister, size:%{public}d",
540 screenId, static_cast<uint32_t>(screenNodeMap_.size()));
541 }
542
GetUINodeInfo(const RefPtr<FrameNode> & node,int32_t parentId,std::ostringstream & oss)543 void WindowSceneLayoutManager::GetUINodeInfo(const RefPtr<FrameNode>& node,
544 int32_t parentId, std::ostringstream& oss)
545 {
546 CHECK_NULL_VOID(node);
547 auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
548 CHECK_NULL_VOID(context);
549 auto rsNode = context->GetRSNode();
550 CHECK_NULL_VOID(rsNode);
551 oss << " name: " << GetWindowName(node);
552 oss << " isVisible: " << node->IsVisible();
553 oss << " opacity: " << context->GetOpacityValue(1.0f);
554 oss << " patternType: " << node->GetWindowPatternType();
555 auto globalGeometry = GetGlobalGeometry(node);
556 auto localGeometry = GetLocalGeometry(node);
557 if (globalGeometry && localGeometry) {
558 auto absRect = globalGeometry->GetAbsRect();
559 oss << " resRect: [" << absRect.GetLeft() << ", " << absRect.GetTop() << ", "
560 << localGeometry->GetWidth() << ", " << localGeometry->GetHeight() << "]";
561 auto matrix = globalGeometry->GetAbsMatrix();
562 oss << " globalScale: [ " << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
563 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "],";
564 oss << " globalPos: [" << rsNode->GetGlobalPositionX() << ", " << rsNode->GetGlobalPositionY() << "],";
565 oss << " pivot: [" << globalGeometry->GetPivotX() << ", " << globalGeometry->GetPivotY() << "],";
566 } else {
567 oss << " globalGeometry: [null],";
568 }
569 if (localGeometry) {
570 auto absRect = localGeometry->GetAbsRect();
571 oss << " localRect: [" << absRect.GetLeft() << ", " << absRect.GetTop() << ", "
572 << localGeometry->GetWidth() << ", " << localGeometry->GetHeight() << "]";
573 auto matrix = localGeometry->GetAbsMatrix();
574 oss << " localScale: [" << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
575 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "],";
576 oss << " localTrans: [" << matrix.Get(Rosen::Drawing::Matrix::TRANS_X) << ", "
577 << matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) << "],";
578 oss << " localPos: [" << localGeometry->GetX() << ", "
579 << localGeometry->GetY() << "],";
580 } else {
581 oss << " localGeometry: [null],";
582 }
583 oss << " requestZIndex: " << context->GetZIndexValue(ZINDEX_DEFAULT_VALUE);
584 oss << " rsId: " << GetRSNodeId(node);
585 oss << " frameNodeId: " << node->GetId();
586 oss << " parentFrameNodeId: " << parentId << std::endl;
587 }
588
GetTotalUITreeInfo(std::string & info)589 void WindowSceneLayoutManager::GetTotalUITreeInfo(std::string& info)
590 {
591 if (!mainHandler_) {
592 auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
593 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
594 }
595 auto task = [this, &info] {
596 for (auto it = screenNodeMap_.begin(); it != screenNodeMap_.end(); ++it) {
597 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "begin task GetTotalUITreeInfo:%{public}" PRIu64, it->first);
598 std::ostringstream oss;
599 auto screenNode = it->second.Upgrade();
600 GetUITreeInfo(screenNode, 0, 0, oss);
601 oss << "--------------------------------PatternTree" << " screenId: " <<
602 it->first << "-----------------------------------" << std::endl;
603 GetRSNodeTreeInfo(GetRSNode(screenNode), 0, oss);
604 info.append(oss.str());
605 }
606 };
607 mainHandler_->PostSyncTask(std::move(task), "GetTotalUITreeInfo", AppExecFwk::EventQueue::Priority::IMMEDIATE);
608 }
609
GetUITreeInfo(const RefPtr<FrameNode> & node,int32_t depth,int32_t parentId,std::ostringstream & oss)610 void WindowSceneLayoutManager::GetUITreeInfo(const RefPtr<FrameNode>& node, int32_t depth,
611 int32_t parentId, std::ostringstream& oss)
612 {
613 if (!node) {
614 return;
615 }
616 for (int32_t i = 0; i < depth; ++i) {
617 oss << " ";
618 }
619 oss << "| ";
620 GetUINodeInfo(node, parentId, oss);
621 for (auto& weakNode : node->GetFrameChildren()) {
622 auto child = weakNode.Upgrade();
623 if (!child) {
624 continue;
625 }
626 GetUITreeInfo(child, depth + 1, node->GetId(), oss);
627 }
628 }
629
DumpRSNodeType(Rosen::RSUINodeType nodeType,std::ostringstream & oss)630 void WindowSceneLayoutManager::DumpRSNodeType(Rosen::RSUINodeType nodeType, std::ostringstream& oss)
631 {
632 switch (nodeType) {
633 case Rosen::RSUINodeType::DISPLAY_NODE: {
634 oss << "DISPLAY_NODE";
635 break;
636 }
637 case Rosen::RSUINodeType::RS_NODE: {
638 oss << "RS_NODE";
639 break;
640 }
641 case Rosen::RSUINodeType::SURFACE_NODE: {
642 oss << "SURFACE_NODE";
643 break;
644 }
645 case Rosen::RSUINodeType::CANVAS_NODE: {
646 oss << "CANVAS_NODE";
647 break;
648 }
649 case Rosen::RSUINodeType::ROOT_NODE: {
650 oss << "ROOT_NODE";
651 break;
652 }
653 case Rosen::RSUINodeType::PROXY_NODE: {
654 oss << "PROXY_NODE";
655 break;
656 }
657 case Rosen::RSUINodeType::CANVAS_DRAWING_NODE: {
658 oss << "CANVAS_DRAWING_NODE";
659 break;
660 }
661 case Rosen::RSUINodeType::EFFECT_NODE: {
662 oss << "EFFECT_NODE";
663 break;
664 }
665 default: {
666 oss << "UNKNOWN_NODE";
667 break;
668 }
669 }
670 }
671
GetRSNodeTreeInfo(const std::shared_ptr<RSNode> & rsNode,int32_t depth,std::ostringstream & oss)672 void WindowSceneLayoutManager::GetRSNodeTreeInfo(const std::shared_ptr<RSNode>& rsNode, int32_t depth,
673 std::ostringstream& oss)
674 {
675 CHECK_NULL_VOID(rsNode);
676 for (int32_t i = 0; i < depth; ++i) {
677 oss << " ";
678 }
679 oss << "| ";
680 GetRSNodeInfo(rsNode, oss);
681 auto children = rsNode->GetChildren();
682 for (auto child : children) {
683 if (auto childPtr = Rosen::RSNodeMap::Instance().GetNode(child)) {
684 GetRSNodeTreeInfo(childPtr, depth + 1, oss);
685 }
686 }
687 }
688
GetRSNodeInfo(const std::shared_ptr<RSNode> & rsNode,std::ostringstream & oss)689 void WindowSceneLayoutManager::GetRSNodeInfo(const std::shared_ptr<RSNode>& rsNode,
690 std::ostringstream& oss)
691 {
692 CHECK_NULL_VOID(rsNode);
693 DumpRSNodeType(rsNode->GetType(), oss);
694 oss << "[" + std::to_string(rsNode->GetId()) << "], ";
695 if (rsNode->GetType() == Rosen::RSUINodeType::SURFACE_NODE) {
696 auto surfaceNode = Rosen::RSNode::ReinterpretCast<Rosen::RSSurfaceNode>(rsNode);
697 std::string name = surfaceNode ? surfaceNode->GetName() : "";
698 oss << "Name [" << name << "]";
699 }
700 oss << ", StagingProperties" << rsNode->GetStagingProperties().Dump();
701 auto scale = rsNode->GetStagingProperties().GetScale();
702 oss << ", Scale: [" << scale[0] << ", " << scale[1] << "]";
703 auto translate = rsNode->GetStagingProperties().GetTranslate();
704 oss << ", Translate: [" << translate[0] << ", " << translate[1] << ", "
705 << rsNode->GetStagingProperties().GetTranslateZ() << "]";
706 oss << ", Rotation: " << rsNode->GetStagingProperties().GetRotation();
707 oss << ", Alpha: " << rsNode->GetStagingProperties().GetAlpha();
708 oss << ", ClipToBounds: " << rsNode->GetStagingProperties().GetClipBounds();
709 auto globalGeometry = rsNode->GetGlobalGeometry();
710 if (globalGeometry) {
711 auto absRect = globalGeometry->GetAbsRect();
712 oss << ", globalAbsRect: " << absRect.ToString().c_str();
713 auto matrix = globalGeometry->GetAbsMatrix();
714 oss << ", globalScale: [ " << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
715 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "]";
716 oss << ", globalPos: [" << rsNode->GetGlobalPositionX() << ", " << rsNode->GetGlobalPositionY() << "]";
717 oss << ", pivot: [" << globalGeometry->GetPivotX() << ", " << globalGeometry->GetPivotY() << "]";
718 } else {
719 oss << "globalGeometry: [null],";
720 }
721 auto localGeometry = rsNode->GetLocalGeometry();
722 if (localGeometry) {
723 auto absRect = localGeometry->GetAbsRect();
724 oss << ", localAbsRect: " << absRect.ToString().c_str();
725 auto matrix = localGeometry->GetAbsMatrix();
726 oss << ", localScale: [" << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
727 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "]";
728 oss << ", localTrans: [" << matrix.Get(Rosen::Drawing::Matrix::TRANS_X) << ", "
729 << matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) << "]";
730 oss << ", localPos: [" << localGeometry->GetX() << ", " << localGeometry->GetY() << "]";
731 } else {
732 oss << "localGeometry: [null],";
733 }
734 oss << std::endl;
735 }
736 } // namespace OHOS::Ace::NG