1/* 2 * Copyright (c) 2021-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 "abstract_screen.h" 17 18#include <cmath> 19#include "abstract_screen_controller.h" 20#include "display_manager_service.h" 21#include "dm_common.h" 22#include "window_manager_hilog.h" 23 24namespace OHOS::Rosen { 25namespace { 26constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "AbstractScreenGroup"}; 27constexpr float MAX_ZORDER = 100000.0f; 28} 29 30AbstractScreen::AbstractScreen(sptr<AbstractScreenController> screenController, const std::string& name, ScreenId dmsId, 31 ScreenId rsId) : dmsId_(dmsId), rsId_(rsId), screenController_(screenController) 32{ 33 if (name != "") { 34 name_ = name; 35 } 36} 37 38AbstractScreen::~AbstractScreen() 39{ 40} 41 42sptr<SupportedScreenModes> AbstractScreen::GetActiveScreenMode() const 43{ 44 if (activeIdx_ < 0 || activeIdx_ >= static_cast<int32_t>(modes_.size())) { 45 WLOGE("active mode index is wrong: %{public}d", activeIdx_); 46 return nullptr; 47 } 48 return modes_[activeIdx_]; 49} 50 51std::vector<sptr<SupportedScreenModes>> AbstractScreen::GetAbstractScreenModes() const 52{ 53 return modes_; 54} 55 56sptr<AbstractScreenGroup> AbstractScreen::GetGroup() const 57{ 58 if (screenController_ == nullptr) { 59 return nullptr; 60 } 61 return screenController_->GetAbstractScreenGroup(groupDmsId_); 62} 63 64sptr<ScreenInfo> AbstractScreen::ConvertToScreenInfo() const 65{ 66 sptr<ScreenInfo> info = new(std::nothrow) ScreenInfo(); 67 if (info == nullptr) { 68 return nullptr; 69 } 70 FillScreenInfo(info); 71 return info; 72} 73 74void AbstractScreen::UpdateRSTree(std::shared_ptr<RSSurfaceNode>& surfaceNode, bool isAdd, bool needToUpdate) 75{ 76 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) { 77 WLOGFE("node is nullptr"); 78 return; 79 } 80 WLOGFD("%{public}s surface: %{public}s, %{public}" PRIu64"", (isAdd ? "add" : "remove"), 81 surfaceNode->GetName().c_str(), surfaceNode->GetId()); 82 83 if (isAdd) { 84 surfaceNode->SetVisible(true); 85 rsDisplayNode_->AddChild(surfaceNode, -1); 86 } else { 87 rsDisplayNode_->RemoveChild(surfaceNode); 88 } 89 90 if (needToUpdate) { 91 std::lock_guard<std::recursive_mutex> lock(mutex_); 92 if (isAdd) { 93 appSurfaceNodes_.push_back(surfaceNode); 94 } else { 95 auto iter = std::find_if(appSurfaceNodes_.begin(), appSurfaceNodes_.end(), 96 [surfaceNode] (std::shared_ptr<RSSurfaceNode> node) { 97 return surfaceNode->GetId() == node->GetId(); 98 }); 99 if (iter != appSurfaceNodes_.end()) { 100 appSurfaceNodes_.erase(iter); 101 } 102 } 103 } 104} 105 106DMError AbstractScreen::AddSurfaceNode(std::shared_ptr<RSSurfaceNode>& surfaceNode, bool onTop, bool needToRecord) 107{ 108 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) { 109 WLOGFE("node is nullptr"); 110 return DMError::DM_ERROR_NULLPTR; 111 } 112 surfaceNode->SetVisible(true); 113 if (onTop) { 114 rsDisplayNode_->AddChild(surfaceNode, -1); 115 surfaceNode->SetPositionZ(MAX_ZORDER); 116 } else { 117 rsDisplayNode_->AddChild(surfaceNode, -1); 118 } 119 if (needToRecord) { 120 std::lock_guard<std::recursive_mutex> lock(mutex_); 121 nativeSurfaceNodes_.push_back(surfaceNode); 122 } 123 auto transactionProxy = RSTransactionProxy::GetInstance(); 124 if (transactionProxy != nullptr) { 125 transactionProxy->FlushImplicitTransaction(); 126 } 127 return DMError::DM_OK; 128} 129 130DMError AbstractScreen::RemoveSurfaceNode(std::shared_ptr<RSSurfaceNode>& surfaceNode) 131{ 132 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) { 133 WLOGFE("Node is nullptr"); 134 return DMError::DM_ERROR_NULLPTR; 135 } 136 std::lock_guard<std::recursive_mutex> lock(mutex_); 137 auto iter = std::find_if(nativeSurfaceNodes_.begin(), nativeSurfaceNodes_.end(), [surfaceNode] 138 (std::shared_ptr<RSSurfaceNode> node) { 139 return surfaceNode->GetId() == node->GetId(); 140 }); 141 if (iter == nativeSurfaceNodes_.end()) { 142 WLOGFW("Child not found"); 143 return DMError::DM_ERROR_INVALID_PARAM; 144 } 145 rsDisplayNode_->RemoveChild(*iter); 146 nativeSurfaceNodes_.erase(iter); 147 auto transactionProxy = RSTransactionProxy::GetInstance(); 148 if (transactionProxy != nullptr) { 149 transactionProxy->FlushImplicitTransaction(); 150 } 151 return DMError::DM_OK; 152} 153 154void AbstractScreen::UpdateDisplayGroupRSTree(std::shared_ptr<RSSurfaceNode>& surfaceNode, NodeId parentNodeId, 155 bool isAdd) 156{ 157 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) { 158 WLOGFE("node is nullptr"); 159 return; 160 } 161 WLOGFI("%{public}s surface: %{public}s, %{public}" PRIu64"", (isAdd ? "add" : "remove"), 162 surfaceNode->GetName().c_str(), surfaceNode->GetId()); 163 164 if (isAdd) { 165 surfaceNode->SetVisible(true); 166 rsDisplayNode_->AddCrossParentChild(surfaceNode, -1); 167 } else { 168 rsDisplayNode_->RemoveCrossParentChild(surfaceNode, parentNodeId); 169 } 170} 171 172void AbstractScreen::SetPropertyForDisplayNode(const std::shared_ptr<RSDisplayNode>& rsDisplayNode, 173 const RSDisplayNodeConfig& config, const Point& startPoint) 174{ 175 rSDisplayNodeConfig_ = config; 176 startPoint_ = startPoint; 177 WLOGFI("SetDisplayOffset: posX:%{public}d, posY:%{public}d", startPoint.posX_, startPoint.posY_); 178 rsDisplayNode->SetDisplayOffset(startPoint.posX_, startPoint.posY_); 179 uint32_t width = 0; 180 uint32_t height = 0; 181 sptr<SupportedScreenModes> abstractScreenModes = GetActiveScreenMode(); 182 if (abstractScreenModes != nullptr) { 183 height = abstractScreenModes->height_; 184 width = abstractScreenModes->width_; 185 } 186 RSScreenType screenType; 187 auto ret = RSInterfaces::GetInstance().GetScreenType(rsId_, screenType); 188 if (ret == StatusCode::SUCCESS && screenType == RSScreenType::VIRTUAL_TYPE_SCREEN) { 189 rsDisplayNode->SetSecurityDisplay(true); 190 WLOGFI("virtualScreen SetSecurityDisplay success"); 191 } 192 // If setDisplayOffset is not valid for SetFrame/SetBounds 193 rsDisplayNode->SetFrame(0, 0, width, height); 194 rsDisplayNode->SetBounds(0, 0, width, height); 195} 196 197void AbstractScreen::InitRSDisplayNode(const RSDisplayNodeConfig& config, const Point& startPoint) 198{ 199 if (rsDisplayNode_ != nullptr) { 200 rsDisplayNode_->SetDisplayNodeMirrorConfig(config); 201 WLOGFD("RSDisplayNode is not null"); 202 } else { 203 WLOGFD("Create rsDisplayNode"); 204 std::shared_ptr<RSDisplayNode> rsDisplayNode = RSDisplayNode::Create(config); 205 if (rsDisplayNode == nullptr) { 206 WLOGE("fail to add child. create rsDisplayNode fail!"); 207 return; 208 } 209 rsDisplayNode_ = rsDisplayNode; 210 } 211 SetPropertyForDisplayNode(rsDisplayNode_, config, startPoint); 212 213 // flush transaction 214 auto transactionProxy = RSTransactionProxy::GetInstance(); 215 if (transactionProxy != nullptr) { 216 transactionProxy->FlushImplicitTransaction(); 217 } 218 WLOGFD("InitRSDisplayNode success"); 219} 220 221void AbstractScreen::InitRSDefaultDisplayNode(const RSDisplayNodeConfig& config, const Point& startPoint) 222{ 223 if (rsDisplayNode_ == nullptr) { 224 WLOGFD("RSDisplayNode is nullptr"); 225 } 226 227 WLOGFD("Create defaultRSDisplayNode"); 228 std::shared_ptr<RSDisplayNode> rsDisplayNode = RSDisplayNode::Create(config); 229 if (rsDisplayNode == nullptr) { 230 WLOGE("fail to add child. create rsDisplayNode fail!"); 231 return; 232 } 233 rsDisplayNode_ = rsDisplayNode; 234 SetPropertyForDisplayNode(rsDisplayNode_, config, startPoint); 235 236 std::lock_guard<std::recursive_mutex> lock(mutex_); 237 // update RSTree for default display 238 for (auto node: appSurfaceNodes_) { 239 UpdateRSTree(node, true, false); 240 } 241 for (auto node: nativeSurfaceNodes_) { 242 AddSurfaceNode(node, false, false); 243 } 244 245 // flush transaction 246 auto transactionProxy = RSTransactionProxy::GetInstance(); 247 if (transactionProxy != nullptr) { 248 transactionProxy->FlushImplicitTransaction(); 249 } 250 WLOGFD("InitRSDefaultDisplayNode success"); 251} 252 253void AbstractScreen::UpdateRSDisplayNode(Point startPoint) 254{ 255 WLOGD("update display offset from [%{public}d %{public}d] to [%{public}d %{public}d]", 256 startPoint_.posX_, startPoint_.posY_, startPoint.posX_, startPoint.posY_); 257 if (rsDisplayNode_ == nullptr) { 258 WLOGFD("rsDisplayNode_ is nullptr"); 259 return; 260 } 261 262 startPoint_ = startPoint; 263 rsDisplayNode_->SetDisplayOffset(startPoint.posX_, startPoint.posY_); 264} 265 266ScreenId AbstractScreen::GetScreenGroupId() const 267{ 268 return groupDmsId_; 269} 270 271DMError AbstractScreen::GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut>& colorGamuts) 272{ 273 auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorGamuts(rsId_, colorGamuts); 274 if (ret != StatusCode::SUCCESS) { 275 WLOGE("GetScreenSupportedColorGamuts fail! rsId %{public}" PRIu64"", rsId_); 276 return DMError::DM_ERROR_RENDER_SERVICE_FAILED; 277 } 278 WLOGI("GetScreenSupportedColorGamuts ok! rsId %{public}" PRIu64", size %{public}u", 279 rsId_, static_cast<uint32_t>(colorGamuts.size())); 280 281 return DMError::DM_OK; 282} 283 284DMError AbstractScreen::GetScreenColorGamut(ScreenColorGamut& colorGamut) 285{ 286 auto ret = RSInterfaces::GetInstance().GetScreenColorGamut(rsId_, colorGamut); 287 if (ret != StatusCode::SUCCESS) { 288 WLOGE("GetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_); 289 return DMError::DM_ERROR_RENDER_SERVICE_FAILED; 290 } 291 WLOGI("GetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamut %{public}u", 292 rsId_, static_cast<uint32_t>(colorGamut)); 293 294 return DMError::DM_OK; 295} 296 297DMError AbstractScreen::SetScreenColorGamut(int32_t colorGamutIdx) 298{ 299 std::vector<ScreenColorGamut> colorGamuts; 300 DMError res = GetScreenSupportedColorGamuts(colorGamuts); 301 if (res != DMError::DM_OK) { 302 WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_); 303 return res; 304 } 305 if (colorGamutIdx < 0 || colorGamutIdx >= static_cast<int32_t>(colorGamuts.size())) { 306 WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64" colorGamutIdx %{public}d invalid.", 307 rsId_, colorGamutIdx); 308 return DMError::DM_ERROR_INVALID_PARAM; 309 } 310 auto ret = RSInterfaces::GetInstance().SetScreenColorGamut(rsId_, colorGamutIdx); 311 if (ret != StatusCode::SUCCESS) { 312 WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_); 313 return DMError::DM_ERROR_RENDER_SERVICE_FAILED; 314 } 315 WLOGI("SetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamutIdx %{public}u", 316 rsId_, colorGamutIdx); 317 318 return DMError::DM_OK; 319} 320 321DMError AbstractScreen::GetScreenGamutMap(ScreenGamutMap& gamutMap) 322{ 323 auto ret = RSInterfaces::GetInstance().GetScreenGamutMap(rsId_, gamutMap); 324 if (ret != StatusCode::SUCCESS) { 325 WLOGE("GetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_); 326 return DMError::DM_ERROR_RENDER_SERVICE_FAILED; 327 } 328 WLOGI("GetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u", 329 rsId_, static_cast<uint32_t>(gamutMap)); 330 331 return DMError::DM_OK; 332} 333 334DMError AbstractScreen::SetScreenGamutMap(ScreenGamutMap gamutMap) 335{ 336 if (gamutMap > GAMUT_MAP_HDR_EXTENSION) { 337 return DMError::DM_ERROR_INVALID_PARAM; 338 } 339 auto ret = RSInterfaces::GetInstance().SetScreenGamutMap(rsId_, gamutMap); 340 if (ret != StatusCode::SUCCESS) { 341 WLOGE("SetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_); 342 return DMError::DM_ERROR_RENDER_SERVICE_FAILED; 343 } 344 WLOGI("SetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u", 345 rsId_, static_cast<uint32_t>(gamutMap)); 346 347 return DMError::DM_OK; 348} 349 350DMError AbstractScreen::SetScreenColorTransform() 351{ 352 WLOGI("SetScreenColorTransform ok! rsId %{public}" PRIu64"", rsId_); 353 354 return DMError::DM_OK; 355} 356 357void AbstractScreen::FillScreenInfo(sptr<ScreenInfo> info) const 358{ 359 if (info == nullptr) { 360 WLOGE("FillScreenInfo failed! info is nullptr"); 361 return; 362 } 363 info->id_ = dmsId_; 364 info->name_ = name_; 365 uint32_t width = 0; 366 uint32_t height = 0; 367 sptr<SupportedScreenModes> abstractScreenModes = GetActiveScreenMode(); 368 if (abstractScreenModes != nullptr) { 369 height = abstractScreenModes->height_; 370 width = abstractScreenModes->width_; 371 } 372 float virtualPixelRatio = virtualPixelRatio_; 373 // "< 1e-6" means virtualPixelRatio is 0. 374 if (fabsf(virtualPixelRatio) < 1e-6) { 375 virtualPixelRatio = 1.0f; 376 } 377 ScreenSourceMode sourceMode = GetSourceMode(); 378 info->virtualPixelRatio_ = virtualPixelRatio; 379 info->virtualHeight_ = height / virtualPixelRatio; 380 info->virtualWidth_ = width / virtualPixelRatio; 381 info->lastParent_ = lastGroupDmsId_; 382 info->parent_ = groupDmsId_; 383 info->isScreenGroup_ = isScreenGroup_; 384 info->rotation_ = rotation_; 385 info->orientation_ = orientation_; 386 info->sourceMode_ = sourceMode; 387 info->type_ = type_; 388 info->modeId_ = activeIdx_; 389 info->modes_ = modes_; 390} 391 392bool AbstractScreen::SetOrientation(Orientation orientation) 393{ 394 orientation_ = orientation; 395 return true; 396} 397 398bool AbstractScreen::SetVirtualPixelRatio(float virtualPixelRatio) 399{ 400 virtualPixelRatio_ = virtualPixelRatio; 401 return true; 402} 403 404float AbstractScreen::GetVirtualPixelRatio() const 405{ 406 return virtualPixelRatio_; 407} 408 409ScreenSourceMode AbstractScreen::GetSourceMode() const 410{ 411 sptr<AbstractScreenGroup> abstractScreenGroup = GetGroup(); 412 if (abstractScreenGroup == nullptr || screenController_ == nullptr) { 413 return ScreenSourceMode::SCREEN_ALONE; 414 } 415 ScreenId defaultId = screenController_->GetDefaultAbstractScreenId(); 416 if (dmsId_ == defaultId) { 417 return ScreenSourceMode::SCREEN_MAIN; 418 } 419 ScreenCombination combination = abstractScreenGroup->GetScreenCombination(); 420 switch (combination) { 421 case ScreenCombination::SCREEN_MIRROR: { 422 return ScreenSourceMode::SCREEN_MIRROR; 423 } 424 case ScreenCombination::SCREEN_EXPAND: { 425 return ScreenSourceMode::SCREEN_EXTEND; 426 } 427 case ScreenCombination::SCREEN_ALONE: { 428 return ScreenSourceMode::SCREEN_ALONE; 429 } 430 default: { 431 return ScreenSourceMode::SCREEN_ALONE; 432 } 433 } 434} 435 436Rotation AbstractScreen::CalcRotation(Orientation orientation) const 437{ 438 sptr<SupportedScreenModes> info = GetActiveScreenMode(); 439 if (info == nullptr) { 440 return Rotation::ROTATION_0; 441 } 442 // vertical: phone(Plugin screen); horizontal: pad & external screen 443 bool isVerticalScreen = info->width_ < info->height_; 444 switch (orientation) { 445 case Orientation::UNSPECIFIED: { 446 return Rotation::ROTATION_0; 447 } 448 case Orientation::VERTICAL: { 449 return isVerticalScreen ? Rotation::ROTATION_0 : Rotation::ROTATION_90; 450 } 451 case Orientation::HORIZONTAL: { 452 return isVerticalScreen ? Rotation::ROTATION_90 : Rotation::ROTATION_0; 453 } 454 case Orientation::REVERSE_VERTICAL: { 455 return isVerticalScreen ? Rotation::ROTATION_180 : Rotation::ROTATION_270; 456 } 457 case Orientation::REVERSE_HORIZONTAL: { 458 return isVerticalScreen ? Rotation::ROTATION_270 : Rotation::ROTATION_180; 459 } 460 default: { 461 WLOGE("unknown orientation %{public}u", orientation); 462 return Rotation::ROTATION_0; 463 } 464 } 465} 466 467const std::string& AbstractScreen::GetScreenName() const 468{ 469 return name_; 470} 471 472void AbstractScreen::SetPhyWidth(uint32_t phyWidth) 473{ 474 phyWidth_ = phyWidth; 475} 476 477void AbstractScreen::SetPhyHeight(uint32_t phyHeight) 478{ 479 phyHeight_ = phyHeight; 480} 481 482uint32_t AbstractScreen::GetPhyWidth() const 483{ 484 return phyWidth_; 485} 486 487uint32_t AbstractScreen::GetPhyHeight() const 488{ 489 return phyHeight_; 490} 491 492AbstractScreenGroup::AbstractScreenGroup(sptr<AbstractScreenController> screenController, ScreenId dmsId, ScreenId rsId, 493 std::string name, ScreenCombination combination) : AbstractScreen(screenController, name, dmsId, rsId), 494 combination_(combination) 495{ 496 type_ = ScreenType::UNDEFINED; 497 isScreenGroup_ = true; 498} 499 500AbstractScreenGroup::~AbstractScreenGroup() 501{ 502 rsDisplayNode_ = nullptr; 503} 504 505sptr<ScreenGroupInfo> AbstractScreenGroup::ConvertToScreenGroupInfo() const 506{ 507 sptr<ScreenGroupInfo> screenGroupInfo = new(std::nothrow) ScreenGroupInfo(); 508 if (screenGroupInfo == nullptr) { 509 return nullptr; 510 } 511 FillScreenInfo(screenGroupInfo); 512 screenGroupInfo->combination_ = combination_; 513 for (auto iter = screenMap_.begin(); iter != screenMap_.end(); iter++) { 514 screenGroupInfo->children_.push_back(iter->first); 515 screenGroupInfo->position_.push_back(iter->second->startPoint_); 516 } 517 return screenGroupInfo; 518} 519 520bool AbstractScreenGroup::GetRSDisplayNodeConfig(sptr<AbstractScreen>& dmsScreen, struct RSDisplayNodeConfig& config) 521{ 522 if (dmsScreen == nullptr) { 523 WLOGE("dmsScreen is nullptr."); 524 return false; 525 } 526 config = { dmsScreen->rsId_ }; 527 switch (combination_) { 528 case ScreenCombination::SCREEN_ALONE: 529 [[fallthrough]]; 530 case ScreenCombination::SCREEN_EXPAND: 531 break; 532 case ScreenCombination::SCREEN_MIRROR: { 533 if (GetChildCount() == 0 || mirrorScreenId_ == dmsScreen->dmsId_) { 534 WLOGI("AddChild, SCREEN_MIRROR, config is not mirror"); 535 break; 536 } 537 if (screenController_ == nullptr) { 538 return false; 539 } 540 if (mirrorScreenId_ == SCREEN_ID_INVALID || !HasChild(mirrorScreenId_)) { 541 WLOGI("AddChild, mirrorScreenId_ is invalid, use default screen"); 542 mirrorScreenId_ = screenController_->GetDefaultAbstractScreenId(); 543 } 544 // Todo displayNode is nullptr 545 std::shared_ptr<RSDisplayNode> displayNode = screenController_->GetRSDisplayNodeByScreenId(mirrorScreenId_); 546 if (displayNode == nullptr) { 547 WLOGFE("AddChild fail, displayNode is nullptr, cannot get DisplayNode"); 548 break; 549 } 550 NodeId nodeId = displayNode->GetId(); 551 WLOGI("AddChild, mirrorScreenId_:%{public}" PRIu64", rsId_:%{public}" PRIu64", nodeId:%{public}" PRIu64"", 552 mirrorScreenId_, dmsScreen->rsId_, nodeId); 553 config = {dmsScreen->rsId_, true, nodeId}; 554 break; 555 } 556 default: 557 WLOGE("fail to add child. invalid group combination:%{public}u", combination_); 558 return false; 559 } 560 return true; 561} 562 563bool AbstractScreenGroup::AddChild(sptr<AbstractScreen>& dmsScreen, Point& startPoint) 564{ 565 if (dmsScreen == nullptr) { 566 WLOGE("AddChild, dmsScreen is nullptr."); 567 return false; 568 } 569 ScreenId screenId = dmsScreen->dmsId_; 570 WLOGFD("AbstractScreenGroup AddChild dmsScreenId: %{public}" PRIu64"", screenId); 571 auto iter = screenMap_.find(screenId); 572 if (iter != screenMap_.end()) { 573 if (dmsScreen->rsDisplayNode_ != nullptr && dmsScreen->type_ == ScreenType::REAL && 574 defaultScreenId_ == screenId) { 575 WLOGFD("Add default screen, id: %{public}" PRIu64"", screenId); 576 } else { 577 WLOGE("AddChild, screenMap_ has dmsScreen:%{public}" PRIu64"", screenId); 578 return false; 579 } 580 } 581 struct RSDisplayNodeConfig config; 582 if (!GetRSDisplayNodeConfig(dmsScreen, config)) { 583 return false; 584 } 585 if (dmsScreen->rsDisplayNode_ != nullptr && dmsScreen->type_ == ScreenType::REAL && 586 defaultScreenId_ == screenId) { 587 WLOGFD("Reconnect default screen, screenId: %{public}" PRIu64"", screenId); 588 dmsScreen->InitRSDefaultDisplayNode(config, startPoint); 589 } else { 590 dmsScreen->InitRSDisplayNode(config, startPoint); 591 dmsScreen->lastGroupDmsId_ = dmsScreen->groupDmsId_; 592 dmsScreen->groupDmsId_ = dmsId_; 593 screenMap_.insert(std::make_pair(screenId, dmsScreen)); 594 } 595 return true; 596} 597 598bool AbstractScreenGroup::AddChildren(std::vector<sptr<AbstractScreen>>& dmsScreens, std::vector<Point>& startPoints) 599{ 600 size_t size = dmsScreens.size(); 601 if (size != startPoints.size()) { 602 WLOGE("AddChildren, unequal size."); 603 return false; 604 } 605 bool res = true; 606 for (size_t i = 0; i < size; i++) { 607 res = AddChild(dmsScreens[i], startPoints[i]) && res; 608 } 609 return res; 610} 611 612bool AbstractScreenGroup::RemoveChild(sptr<AbstractScreen>& dmsScreen) 613{ 614 if (dmsScreen == nullptr) { 615 WLOGE("RemoveChild, dmsScreen is nullptr."); 616 return false; 617 } 618 ScreenId screenId = dmsScreen->dmsId_; 619 dmsScreen->lastGroupDmsId_ = dmsScreen->groupDmsId_; 620 dmsScreen->groupDmsId_ = SCREEN_ID_INVALID; 621 dmsScreen->startPoint_ = Point(); 622 if (dmsScreen->rsDisplayNode_ != nullptr) { 623 dmsScreen->rsDisplayNode_->SetDisplayOffset(0, 0); 624 dmsScreen->rsDisplayNode_->RemoveFromTree(); 625 auto transactionProxy = RSTransactionProxy::GetInstance(); 626 if (transactionProxy != nullptr) { 627 transactionProxy->FlushImplicitTransaction(); 628 } 629 dmsScreen->rsDisplayNode_ = nullptr; 630 } 631 WLOGFD("groupDmsId:%{public}" PRIu64", screenId:%{public}" PRIu64"", 632 dmsScreen->groupDmsId_, screenId); 633 return screenMap_.erase(screenId); 634} 635 636bool AbstractScreenGroup::RemoveDefaultScreen(const sptr<AbstractScreen>& dmsScreen) 637{ 638 if (dmsScreen == nullptr) { 639 WLOGE("RemoveChild, dmsScreen is nullptr."); 640 return false; 641 } 642 ScreenId screenId = dmsScreen->dmsId_; 643 dmsScreen->lastGroupDmsId_ = dmsScreen->groupDmsId_; 644 if (dmsScreen->rsDisplayNode_ != nullptr) { 645 dmsScreen->rsDisplayNode_->SetDisplayOffset(0, 0); 646 dmsScreen->rsDisplayNode_->RemoveFromTree(); 647 auto transactionProxy = RSTransactionProxy::GetInstance(); 648 if (transactionProxy != nullptr) { 649 transactionProxy->FlushImplicitTransaction(); 650 } 651 } 652 defaultScreenId_ = screenId; 653 WLOGFD("groupDmsId:%{public}" PRIu64", screenId:%{public}" PRIu64"", 654 dmsScreen->groupDmsId_, screenId); 655 return true; 656} 657 658bool AbstractScreenGroup::HasChild(ScreenId childScreen) const 659{ 660 return screenMap_.find(childScreen) != screenMap_.end(); 661} 662 663std::vector<sptr<AbstractScreen>> AbstractScreenGroup::GetChildren() const 664{ 665 std::vector<sptr<AbstractScreen>> res; 666 for (auto iter = screenMap_.begin(); iter != screenMap_.end(); iter++) { 667 res.push_back(iter->second); 668 } 669 return res; 670} 671 672std::vector<Point> AbstractScreenGroup::GetChildrenPosition() const 673{ 674 std::vector<Point> res; 675 for (auto iter = screenMap_.begin(); iter != screenMap_.end(); iter++) { 676 res.push_back(iter->second->startPoint_); 677 } 678 return res; 679} 680 681Point AbstractScreenGroup::GetChildPosition(ScreenId screenId) const 682{ 683 Point point; 684 auto iter = screenMap_.find(screenId); 685 if (iter != screenMap_.end()) { 686 point = iter->second->startPoint_; 687 } 688 return point; 689} 690 691size_t AbstractScreenGroup::GetChildCount() const 692{ 693 return screenMap_.size(); 694} 695 696ScreenCombination AbstractScreenGroup::GetScreenCombination() const 697{ 698 return combination_; 699} 700} // namespace OHOS::Rosen 701