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 isParentRecent,bool isParentDirty,bool isParentNotSyncPosition)301 void WindowSceneLayoutManager::TraverseTree(const RefPtr<FrameNode>& rootNode, TraverseResult& res,
302 bool isParentRecent, bool isParentDirty, bool isParentNotSyncPosition)
303 {
304 CHECK_NULL_VOID(rootNode);
305 auto parentType = rootNode->GetWindowPatternType();
306 for (auto& weakNode : rootNode->GetFrameChildren()) {
307 bool isAncestorRecent = isParentRecent;
308 bool isAncestorDirty = isParentDirty;
309 bool notSyncPosition = isParentNotSyncPosition;
310 auto node = weakNode.Upgrade();
311 // when current layer is invisible, no need traverse next
312 if (!node || !IsNodeVisible(node)) {
313 continue;
314 }
315 // once delete in recent, need update zorder
316 uint32_t currentZorder = res.zOrderCnt_;
317 if (WindowSceneHelper::IsWindowPattern(node)) {
318 currentZorder = std::max(res.zOrderCnt_, static_cast<uint32_t>(GetNodeZIndex(node)));
319 }
320 // only window pattern need cal zorder
321 bool hasWindowSession = WindowSceneHelper::HasWindowSession(node);
322 if (hasWindowSession) {
323 res.zOrderCnt_ = currentZorder++; // keep last zorder as current zorder
324 }
325 notSyncPosition = (notSyncPosition || NoNeedSyncScenePanelGlobalPosition(node));
326 // process recent and child node
327 if (!isAncestorRecent) {
328 if (isAncestorDirty || IsNodeDirty(node)) {
329 isAncestorDirty = true;
330 UpdateGeometry(node, rootNode, WindowSceneHelper::IsTransformScene(parentType));
331 }
332 }
333 // only scenepanel can change recent state
334 if (IsRecentContainerState(node)) {
335 isAncestorRecent = true;
336 }
337 // only window pattern but not transform scene need sync info
338 if (hasWindowSession) {
339 FillWindowSceneInfo(node, res, isAncestorRecent, notSyncPosition);
340 DumpNodeInfo(node, rootNode, "AfterFillWindowSceneInfo");
341 }
342
343 res.zOrderCnt_ = currentZorder; // use cnt++ for next zorder cnt
344 auto type = node->GetWindowPatternType();
345 if (!WindowSceneHelper::IsSystemWindowScene(type) && WindowSceneHelper::IsSystemWindowScene(parentType)) {
346 TAG_LOGD(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s child of systemScene continue",
347 GetWindowName(node).c_str());
348 continue; // calculate last system window scene next layer
349 }
350 if (isCoreDebugEnable_) {
351 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "finish TraverseTree winId:%{public}d name:%{public}s"
352 "idName:%{public}s tag:%{public}s zorder:%{public}u isAncestorRecent:%{public}d "
353 "isAncestorDirty:%{public}d hasWindowSession:%{public}d notSyncPosition:%{public}d",
354 GetWindowId(node), GetWindowName(node).c_str(),
355 node->GetInspectorId()->c_str(), node->GetTag().c_str(), res.zOrderCnt_,
356 isAncestorRecent, isAncestorDirty, hasWindowSession, notSyncPosition);
357 }
358 TraverseTree(node, res, isAncestorRecent, isAncestorDirty, notSyncPosition);
359 }
360 }
361
362 // dump funcs
363 template<typename T>
GetWindowIdInner(const RefPtr<T> & windowPattern)364 uint32_t WindowSceneLayoutManager::GetWindowIdInner(const RefPtr<T>& windowPattern)
365 {
366 if (windowPattern == nullptr) {
367 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "windowPattern is null");
368 return 0;
369 }
370 auto session = windowPattern->GetSession();
371 if (session == nullptr) {
372 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "window session is null");
373 return 0;
374 }
375 return session->GetWindowId();
376 }
377
GetWindowId(const RefPtr<FrameNode> & node)378 uint32_t WindowSceneLayoutManager::GetWindowId(const RefPtr<FrameNode>& node)
379 {
380 CHECK_NULL_RETURN(node, 0);
381
382 auto type = static_cast<WindowPatternType>(node->GetWindowPatternType());
383 switch (type) {
384 case WindowPatternType::DEFAULT:
385 case WindowPatternType::TRANSFORM_SCENE:
386 return 0; // invalid window Id
387 case WindowPatternType::PANEL_SCENE:
388 return GetWindowIdInner(node->GetPattern<PanelScene>());
389 case WindowPatternType::INPUT_SCENE:
390 return GetWindowIdInner(node->GetPattern<InputScene>());
391 case WindowPatternType::SYSTEM_WINDOW_SCENE: {
392 auto windowPattern = node->GetPattern<SystemWindowScene>();
393 if (windowPattern == nullptr || windowPattern->GetSession() == nullptr) {
394 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "SystemWindowScene or session is null. type:%{public}u", type);
395 return 0;
396 }
397 return GetWindowIdInner(node->GetPattern<SystemWindowScene>());
398 }
399 case WindowPatternType::WINDOW_SCENE: {
400 return GetWindowIdInner(node->GetPattern<WindowScene>());
401 }
402 default:
403 break;
404 }
405 return 0;
406 }
407
408 template<typename T>
GetWindowNameInner(const RefPtr<T> & windowPattern)409 std::string WindowSceneLayoutManager::GetWindowNameInner(const RefPtr<T>& windowPattern)
410 {
411 if (windowPattern == nullptr) {
412 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "windowPattern is null");
413 return {};
414 }
415 auto session = windowPattern->GetSession();
416 if (session == nullptr) {
417 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "window session is null");
418 return {};
419 }
420 return session->GetWindowName();
421 }
422
GetWindowName(const RefPtr<FrameNode> & node)423 std::string WindowSceneLayoutManager::GetWindowName(const RefPtr<FrameNode>& node)
424 {
425 CHECK_NULL_RETURN(node, "");
426 std::string name;
427 auto type = static_cast<WindowPatternType>(node->GetWindowPatternType());
428 switch (type) {
429 case WindowPatternType::DEFAULT:
430 case WindowPatternType::TRANSFORM_SCENE:
431 break;
432 case WindowPatternType::PANEL_SCENE: {
433 name = GetWindowNameInner(node->GetPattern<PanelScene>());
434 break;
435 }
436 case WindowPatternType::INPUT_SCENE: {
437 name = GetWindowNameInner(node->GetPattern<InputScene>());
438 break;
439 }
440 case WindowPatternType::SYSTEM_WINDOW_SCENE: {
441 name = GetWindowNameInner(node->GetPattern<SystemWindowScene>());
442 break;
443 }
444 case WindowPatternType::WINDOW_SCENE: {
445 name = GetWindowNameInner(node->GetPattern<WindowScene>());
446 break;
447 }
448 default:
449 break;
450 }
451 return name + "_" + node->GetInspectorIdValue("") + "_" + node->GetTag();
452 }
453
454
DumpFlushInfo(uint64_t screenId,TraverseResult & res)455 void WindowSceneLayoutManager::DumpFlushInfo(uint64_t screenId, TraverseResult& res)
456 {
457 if (!isCoreDebugEnable_) {
458 return;
459 }
460 for (auto& [winId, uiParam] : res.uiParams_) {
461 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "DumpFlushInfo screenId:%{public}" PRIu64 " windowId:%{public}d "
462 "name:%{public}s rect:%{public}s, scaleX:%{public}f, scaleY:%{public}f, transX:%{public}f "
463 "transY:%{public}f pivotX:%{public}f, pivotY:%{public}f zOrder:%{public}u, interactive:%{public}d",
464 screenId, winId, uiParam.sessionName_.c_str(), uiParam.rect_.ToString().c_str(), uiParam.scaleX_,
465 uiParam.scaleY_, uiParam.transX_, uiParam.transY_,
466 uiParam.pivotX_, uiParam.pivotY_, uiParam.zOrder_, uiParam.interactive_);
467 }
468 }
469
GetRSNodeId(const RefPtr<FrameNode> & node)470 uint64_t WindowSceneLayoutManager::GetRSNodeId(const RefPtr<FrameNode>& node)
471 {
472 auto rsNode = GetRSNode(node);
473 CHECK_NULL_RETURN(rsNode, 0);
474 return rsNode->GetId();
475 }
476
DumpNodeInfo(const RefPtr<FrameNode> & node,const RefPtr<FrameNode> & parentNode,const std::string & reason)477 void WindowSceneLayoutManager::DumpNodeInfo(const RefPtr<FrameNode>& node,
478 const RefPtr<FrameNode>& parentNode, const std::string& reason)
479 {
480 if (!isCoreDebugEnable_) {
481 return;
482 }
483 CHECK_NULL_VOID(node);
484 int32_t parentId = parentNode ? parentNode->GetId() : 0;
485 auto rsNode = GetRSNode(node);
486 CHECK_NULL_VOID(rsNode);
487 auto nodeGeometry = rsNode->GetGlobalGeometry();
488 if (!nodeGeometry) {
489 TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE,
490 "reason:%{public}s globalGeometry name:%{public}s lrsId:%{public}" PRIu64 " %{public}d"
491 "parentRSId:%{public}" PRIu64 " frameNodeId:%{public}d global geoMetry is null",
492 reason.c_str(), GetWindowName(node).c_str(), GetRSNodeId(node), node->GetId(),
493 GetRSNodeId(parentNode), parentId);
494 return;
495 }
496 auto nodeLocalGeometry = rsNode->GetLocalGeometry();
497 if (!nodeLocalGeometry) {
498 TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE,
499 "reason:%{public}s localGeometry name:%{public}s lrsId:%{public}" PRIu64 " parentRSId:%{public}" PRIu64 ""
500 " localGeo is null", reason.c_str(), GetWindowName(node).c_str(),
501 GetRSNodeId(node), GetRSNodeId(parentNode));
502 return;
503 }
504
505 Rosen::WSRect tempGlobal = { nodeGeometry->GetX(), nodeGeometry->GetY(),
506 nodeGeometry->GetWidth(), nodeGeometry->GetHeight() };
507 Rosen::WSRect tempLocal = { nodeLocalGeometry->GetX(), nodeLocalGeometry->GetY(),
508 nodeLocalGeometry->GetWidth(), nodeLocalGeometry->GetHeight() };
509 auto localMatrix = nodeLocalGeometry->GetAbsMatrix();
510 auto globalMatrix = nodeGeometry->GetAbsMatrix();
511 float localTransX = localMatrix.Get(Rosen::Drawing::Matrix::TRANS_X);
512 float localTransY = localMatrix.Get(Rosen::Drawing::Matrix::TRANS_Y);
513 float globalTransX = globalMatrix.Get(Rosen::Drawing::Matrix::TRANS_X);
514 float globalTransY = globalMatrix.Get(Rosen::Drawing::Matrix::TRANS_Y);
515 auto absGlobalRect = nodeGeometry->GetAbsRect();
516 auto absLocalRect = nodeLocalGeometry->GetAbsRect();
517 auto localScaleX = localMatrix.Get(Rosen::Drawing::Matrix::SCALE_X);
518 auto localScaleY = localMatrix.Get(Rosen::Drawing::Matrix::SCALE_Y);
519 auto gScaleX = globalMatrix.Get(Rosen::Drawing::Matrix::SCALE_X);
520 auto gScaleY = globalMatrix.Get(Rosen::Drawing::Matrix::SCALE_Y);
521 float globalPosX = rsNode->GetGlobalPositionX();
522 float globalPosY = rsNode->GetGlobalPositionY();
523 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE,
524 "DumpNodeInfo reason:%{public}s name:%{public}s lrsId:%{public}" PRIu64 " parentRSId:%{public}" PRIu64 " "
525 "frameNodeId:%{public}d [Rect:%{public}s lTransX:%{public}f lTransY:%{public}f absLocalRect:%{public}s, "
526 "gRect:%{public}s gTransX:%{public}f gTransY:%{public}f globalPosX:%{public}f, globalPosY:%{public}f, "
527 "absGlobalRect:%{public}s lScaleX:%{public}f lScaleY:%{public}f gScaleX:%{public}f gScaleY:%{public}f]",
528 GetWindowName(node).c_str(), reason.c_str(), GetRSNodeId(node), GetRSNodeId(parentNode), parentId,
529 tempLocal.ToString().c_str(), localTransX, localTransY,
530 absLocalRect.ToString().c_str(), tempGlobal.ToString().c_str(), globalTransX, globalTransY, globalPosX,
531 globalPosY, absGlobalRect.ToString().c_str(), localScaleX, localScaleY, gScaleX, gScaleY);
532 }
533
RegisterScreenNode(uint64_t screenId,const RefPtr<FrameNode> & node)534 void WindowSceneLayoutManager::RegisterScreenNode(uint64_t screenId, const RefPtr<FrameNode>& node)
535 {
536 screenNodeMap_[screenId] = WeakPtr<FrameNode>(node);
537 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "screenNode:%{public}" PRIu64 " register, size:%{public}d",
538 screenId, static_cast<uint32_t>(screenNodeMap_.size()));
539 }
540
UnregisterScreenNode(uint64_t screenId)541 void WindowSceneLayoutManager::UnregisterScreenNode(uint64_t screenId)
542 {
543 screenNodeMap_.erase(screenId);
544 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "screenNode:%{public}" PRIu64 " unregister, size:%{public}d",
545 screenId, static_cast<uint32_t>(screenNodeMap_.size()));
546 }
547
GetUINodeInfo(const RefPtr<FrameNode> & node,int32_t parentId,std::ostringstream & oss)548 void WindowSceneLayoutManager::GetUINodeInfo(const RefPtr<FrameNode>& node,
549 int32_t parentId, std::ostringstream& oss)
550 {
551 if (node == nullptr) {
552 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "node null. parentId:%{public}d", parentId);
553 return;
554 }
555 auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
556 if (context == nullptr) {
557 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "context null. screenId:%{public}" PRIu64 " tag:%{public}s"
558 "Id:%{public}d parentId:%{public}d", GetScreenId(node), node->GetTag().c_str(), node->GetId(), parentId);
559 return;
560 }
561 auto rsNode = context->GetRSNode();
562 if (rsNode == nullptr) {
563 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "rsNode null. screenId:%{public}" PRIu64 " tag:%{public}s"
564 "Id:%{public}d parentId:%{public}d", GetScreenId(node), node->GetTag().c_str(), node->GetId(), parentId);
565 return;
566 }
567 oss << " name: " << GetWindowName(node);
568 oss << " isVisible: " << node->IsVisible();
569 oss << " opacity: " << context->GetOpacityValue(1.0f);
570 oss << " patternType: " << node->GetWindowPatternType();
571 auto globalGeometry = GetGlobalGeometry(node);
572 auto localGeometry = GetLocalGeometry(node);
573 if (globalGeometry && localGeometry) {
574 auto absRect = globalGeometry->GetAbsRect();
575 oss << " resRect: [" << absRect.GetLeft() << ", " << absRect.GetTop() << ", "
576 << localGeometry->GetWidth() << ", " << localGeometry->GetHeight() << "]";
577 auto matrix = globalGeometry->GetAbsMatrix();
578 oss << " globalScale: [ " << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
579 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "],";
580 oss << " globalPos: [" << rsNode->GetGlobalPositionX() << ", " << rsNode->GetGlobalPositionY() << "],";
581 oss << " pivot: [" << globalGeometry->GetPivotX() << ", " << globalGeometry->GetPivotY() << "],";
582 } else {
583 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "globalGeometry null. screenId:%{public}" PRIu64 " tag:%{public}s"
584 "Id:%{public}d parentId:%{public}d", GetScreenId(node), node->GetTag().c_str(), node->GetId(), parentId);
585 oss << " globalGeometry: [null],";
586 }
587 if (localGeometry) {
588 auto absRect = localGeometry->GetAbsRect();
589 oss << " localRect: [" << absRect.GetLeft() << ", " << absRect.GetTop() << ", "
590 << localGeometry->GetWidth() << ", " << localGeometry->GetHeight() << "]";
591 auto matrix = localGeometry->GetAbsMatrix();
592 oss << " localScale: [" << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
593 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "],";
594 oss << " localTrans: [" << matrix.Get(Rosen::Drawing::Matrix::TRANS_X) << ", "
595 << matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) << "],";
596 oss << " localPos: [" << localGeometry->GetX() << ", "
597 << localGeometry->GetY() << "],";
598 } else {
599 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "localGeometry null. screenId:%{public}" PRIu64 " tag:%{public}s"
600 "Id:%{public}d parentId:%{public}d", GetScreenId(node), node->GetTag().c_str(), node->GetId(), parentId);
601 oss << " localGeometry: [null],";
602 }
603 oss << " requestZIndex: " << context->GetZIndexValue(ZINDEX_DEFAULT_VALUE);
604 oss << " rsId: " << GetRSNodeId(node);
605 oss << " frameNodeId: " << node->GetId();
606 oss << " parentFrameNodeId: " << parentId << std::endl;
607 }
608
GetTotalUITreeInfo(std::string & info)609 void WindowSceneLayoutManager::GetTotalUITreeInfo(std::string& info)
610 {
611 if (!mainHandler_) {
612 auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
613 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
614 }
615 auto task = [this, &info] {
616 for (auto it = screenNodeMap_.begin(); it != screenNodeMap_.end(); ++it) {
617 TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "begin task GetTotalUITreeInfo:%{public}" PRIu64, it->first);
618 std::ostringstream oss;
619 auto screenNode = it->second.Upgrade();
620 GetUITreeInfo(screenNode, 0, 0, oss);
621 oss << "--------------------------------PatternTree" << " screenId: " <<
622 it->first << "-----------------------------------" << std::endl;
623 GetRSNodeTreeInfo(GetRSNode(screenNode), 0, oss);
624 info.append(oss.str());
625 }
626 };
627 mainHandler_->PostSyncTask(std::move(task), "GetTotalUITreeInfo", AppExecFwk::EventQueue::Priority::IMMEDIATE);
628 }
629
GetUITreeInfo(const RefPtr<FrameNode> & node,int32_t depth,int32_t parentId,std::ostringstream & oss)630 void WindowSceneLayoutManager::GetUITreeInfo(const RefPtr<FrameNode>& node, int32_t depth,
631 int32_t parentId, std::ostringstream& oss)
632 {
633 if (!node) {
634 return;
635 }
636 for (int32_t i = 0; i < depth; ++i) {
637 oss << " ";
638 }
639 oss << "| ";
640 GetUINodeInfo(node, parentId, oss);
641 for (auto& weakNode : node->GetFrameChildren()) {
642 auto child = weakNode.Upgrade();
643 if (!child) {
644 continue;
645 }
646 GetUITreeInfo(child, depth + 1, node->GetId(), oss);
647 }
648 }
649
DumpRSNodeType(Rosen::RSUINodeType nodeType,std::ostringstream & oss)650 void WindowSceneLayoutManager::DumpRSNodeType(Rosen::RSUINodeType nodeType, std::ostringstream& oss)
651 {
652 switch (nodeType) {
653 case Rosen::RSUINodeType::DISPLAY_NODE: {
654 oss << "DISPLAY_NODE";
655 break;
656 }
657 case Rosen::RSUINodeType::RS_NODE: {
658 oss << "RS_NODE";
659 break;
660 }
661 case Rosen::RSUINodeType::SURFACE_NODE: {
662 oss << "SURFACE_NODE";
663 break;
664 }
665 case Rosen::RSUINodeType::CANVAS_NODE: {
666 oss << "CANVAS_NODE";
667 break;
668 }
669 case Rosen::RSUINodeType::ROOT_NODE: {
670 oss << "ROOT_NODE";
671 break;
672 }
673 case Rosen::RSUINodeType::PROXY_NODE: {
674 oss << "PROXY_NODE";
675 break;
676 }
677 case Rosen::RSUINodeType::CANVAS_DRAWING_NODE: {
678 oss << "CANVAS_DRAWING_NODE";
679 break;
680 }
681 case Rosen::RSUINodeType::EFFECT_NODE: {
682 oss << "EFFECT_NODE";
683 break;
684 }
685 default: {
686 oss << "UNKNOWN_NODE";
687 break;
688 }
689 }
690 }
691
GetRSNodeTreeInfo(const std::shared_ptr<RSNode> & rsNode,int32_t depth,std::ostringstream & oss)692 void WindowSceneLayoutManager::GetRSNodeTreeInfo(const std::shared_ptr<RSNode>& rsNode, int32_t depth,
693 std::ostringstream& oss)
694 {
695 CHECK_NULL_VOID(rsNode);
696 for (int32_t i = 0; i < depth; ++i) {
697 oss << " ";
698 }
699 oss << "| ";
700 GetRSNodeInfo(rsNode, oss);
701 auto children = rsNode->GetChildren();
702 for (auto child : children) {
703 if (auto childPtr = Rosen::RSNodeMap::Instance().GetNode(child)) {
704 GetRSNodeTreeInfo(childPtr, depth + 1, oss);
705 }
706 }
707 }
708
GetRSNodeInfo(const std::shared_ptr<RSNode> & rsNode,std::ostringstream & oss)709 void WindowSceneLayoutManager::GetRSNodeInfo(const std::shared_ptr<RSNode>& rsNode,
710 std::ostringstream& oss)
711 {
712 CHECK_NULL_VOID(rsNode);
713 DumpRSNodeType(rsNode->GetType(), oss);
714 oss << "[" + std::to_string(rsNode->GetId()) << "], ";
715 if (rsNode->GetType() == Rosen::RSUINodeType::SURFACE_NODE) {
716 auto surfaceNode = Rosen::RSNode::ReinterpretCast<Rosen::RSSurfaceNode>(rsNode);
717 std::string name = surfaceNode ? surfaceNode->GetName() : "";
718 oss << "Name [" << name << "]";
719 }
720 oss << ", StagingProperties" << rsNode->GetStagingProperties().Dump();
721 auto scale = rsNode->GetStagingProperties().GetScale();
722 oss << ", Scale: [" << scale[0] << ", " << scale[1] << "]";
723 auto translate = rsNode->GetStagingProperties().GetTranslate();
724 oss << ", Translate: [" << translate[0] << ", " << translate[1] << ", "
725 << rsNode->GetStagingProperties().GetTranslateZ() << "]";
726 oss << ", Rotation: " << rsNode->GetStagingProperties().GetRotation();
727 oss << ", Alpha: " << rsNode->GetStagingProperties().GetAlpha();
728 oss << ", ClipToBounds: " << rsNode->GetStagingProperties().GetClipBounds();
729 auto globalGeometry = rsNode->GetGlobalGeometry();
730 if (globalGeometry) {
731 auto absRect = globalGeometry->GetAbsRect();
732 oss << ", globalAbsRect: " << absRect.ToString().c_str();
733 auto matrix = globalGeometry->GetAbsMatrix();
734 oss << ", globalScale: [ " << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
735 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "]";
736 oss << ", globalPos: [" << rsNode->GetGlobalPositionX() << ", " << rsNode->GetGlobalPositionY() << "]";
737 oss << ", pivot: [" << globalGeometry->GetPivotX() << ", " << globalGeometry->GetPivotY() << "]";
738 } else {
739 oss << "globalGeometry: [null],";
740 }
741 auto localGeometry = rsNode->GetLocalGeometry();
742 if (localGeometry) {
743 auto absRect = localGeometry->GetAbsRect();
744 oss << ", localAbsRect: " << absRect.ToString().c_str();
745 auto matrix = localGeometry->GetAbsMatrix();
746 oss << ", localScale: [" << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
747 << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "]";
748 oss << ", localTrans: [" << matrix.Get(Rosen::Drawing::Matrix::TRANS_X) << ", "
749 << matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) << "]";
750 oss << ", localPos: [" << localGeometry->GetX() << ", " << localGeometry->GetY() << "]";
751 } else {
752 oss << "localGeometry: [null],";
753 }
754 oss << std::endl;
755 }
756 } // namespace OHOS::Ace::NG