From aa4e5183f20c11f0f9a693fc349f0d8fd2a0d39a Mon Sep 17 00:00:00 2001 From: xiaojianfeng Date: Sun, 13 Feb 2022 09:20:33 +0800 Subject: [PATCH] modify make mirror Signed-off-by: xiaojianfeng Change-Id: I2b7342bbb4197b488117bb2e48ffeeb1356d2d47 --- dmserver/include/abstract_screen.h | 4 +- dmserver/include/abstract_screen_controller.h | 6 +- dmserver/src/abstract_display_controller.cpp | 38 +-- dmserver/src/abstract_screen.cpp | 36 ++- dmserver/src/abstract_screen_controller.cpp | 225 +++++++++++++++++- dmserver/src/display_manager_proxy.cpp | 2 +- dmserver/src/display_manager_service.cpp | 31 ++- dmserver/src/display_manager_stub.cpp | 4 +- interfaces/innerkits/dm/screen.h | 1 + utils/src/screen_info.cpp | 32 +-- wmserver/include/window_node_container.h | 2 +- wmserver/src/window_node_container.cpp | 4 +- 12 files changed, 324 insertions(+), 61 deletions(-) diff --git a/dmserver/include/abstract_screen.h b/dmserver/include/abstract_screen.h index 09af2f36..51e6f437 100644 --- a/dmserver/include/abstract_screen.h +++ b/dmserver/include/abstract_screen.h @@ -53,7 +53,8 @@ public: ScreenId dmsId_; ScreenId rsId_; std::shared_ptr rsDisplayNode_; - ScreenId groupDmsId_; + RSDisplayNodeConfig rSDisplayNodeConfig_; + ScreenId groupDmsId_ {INVALID_SCREEN_ID}; ScreenType type_ { ScreenType::REAL }; int32_t activeIdx_; float virtualPixelRatio = { 1.0 }; @@ -78,6 +79,7 @@ public: const sptr ConvertToScreenGroupInfo() const; ScreenCombination combination_ { ScreenCombination::SCREEN_ALONE }; + ScreenId mirrorScreenId_ {INVALID_SCREEN_ID}; private: std::map, Point>> abstractScreenMap_; }; diff --git a/dmserver/include/abstract_screen_controller.h b/dmserver/include/abstract_screen_controller.h index 733edffb..8e00c796 100644 --- a/dmserver/include/abstract_screen_controller.h +++ b/dmserver/include/abstract_screen_controller.h @@ -43,6 +43,8 @@ public: void Init(); std::vector GetAllScreenIds(); sptr GetAbstractScreen(ScreenId dmsScreenId) const; + std::vector GetShotScreenIds(std::vector) const; + std::vector GetAllMirrorScreenIds(std::vector) const; sptr GetAbstractScreenGroup(ScreenId dmsScreenId); ScreenId GetDefaultAbstractScreenId(); ScreenId ConvertToRsScreenId(ScreenId dmsScreenId); @@ -54,7 +56,9 @@ public: bool SetScreenActiveMode(ScreenId screenId, uint32_t modeId); std::shared_ptr GetRSDisplayNodeByScreenId(ScreenId dmsScreenId) const; void UpdateRSTree(ScreenId dmsScreenId, std::shared_ptr& surfaceNode, bool isAdd); - + bool MakeMirror(ScreenId, std::vector screens); + void DumpScreenInfo() const; + void DumpScreenGroupInfo() const; private: void OnRsScreenChange(ScreenId rsScreenId, ScreenEvent screenEvent); void ProcessScreenDisconnected(ScreenId rsScreenId); diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp index 81192c5c..291dbd10 100644 --- a/dmserver/src/abstract_display_controller.cpp +++ b/dmserver/src/abstract_display_controller.cpp @@ -84,7 +84,7 @@ sptr AbstractDisplayController::GetAbstractDisplay(DisplayId di std::lock_guard lock(mutex_); auto iter = abstractDisplayMap_.find(displayId); if (iter == abstractDisplayMap_.end()) { - WLOGFE("Failed to get AbstractDisplay, return nullptr!"); + WLOGFE("Failed to get AbstractDisplay %{public}" PRIu64", return nullptr!", displayId); return nullptr; } return iter->second; @@ -117,19 +117,23 @@ void AbstractDisplayController::OnAbstractScreenConnected(sptr a { WLOGI("connect new screen. id:%{public}" PRIu64"", absScreen->dmsId_); std::lock_guard lock(mutex_); - if (absScreen->type_ == ScreenType::REAL) { - sptr group = absScreen->GetGroup(); - if (group == nullptr) { - WLOGE("the group information of the screen is wrong"); - return; - } - if (group->combination_ == ScreenCombination::SCREEN_ALONE) { + sptr group = absScreen->GetGroup(); + if (group == nullptr) { + WLOGE("the group information of the screen is wrong"); + return; + } + if (group->combination_ == ScreenCombination::SCREEN_ALONE) { + BindAloneScreenLocked(absScreen); + } else if (group->combination_ == ScreenCombination::SCREEN_MIRROR) { + if (group->GetChildCount() == 1) { + WLOGI("OnAbstractScreenConnected, ScreenCombination::SCREEN_MIRROR, BindAloneScreenLocked"); BindAloneScreenLocked(absScreen); - } else if (group->combination_ == ScreenCombination::SCREEN_MIRROR) { - AddScreenToMirrorLocked(group, absScreen); } else { - WLOGE("support in future. combination:%{public}ud", group->combination_); + WLOGI("OnAbstractScreenConnected, ScreenCombination::SCREEN_MIRROR, AddScreenToMirrorLocked"); + AddScreenToMirrorLocked(group, absScreen); } + } else { + WLOGE("support in future. combination:%{public}u", group->combination_); } } @@ -146,15 +150,11 @@ void AbstractDisplayController::OnAbstractScreenDisconnected(sptrtype_ == ScreenType::REAL) { - if (screenGroup->combination_ == ScreenCombination::SCREEN_ALONE - || screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR) { - ProcessScreenDisconnected(absScreen, screenGroup); - } else { - WLOGE("support in future. combination:%{public}u", screenGroup->combination_); - } + if (screenGroup->combination_ == ScreenCombination::SCREEN_ALONE + || screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR) { + ProcessScreenDisconnected(absScreen, screenGroup); } else { - WLOGE("support in future. type_:%{public}u", absScreen->type_); + WLOGE("support in future. combination:%{public}u", screenGroup->combination_); } } diff --git a/dmserver/src/abstract_screen.cpp b/dmserver/src/abstract_screen.cpp index cc8465ff..77c9bf1e 100644 --- a/dmserver/src/abstract_screen.cpp +++ b/dmserver/src/abstract_screen.cpp @@ -81,6 +81,9 @@ void AbstractScreen::InitRSDisplayNode(RSDisplayNodeConfig& config) return; } rsDisplayNode_ = rsDisplayNode; + rSDisplayNodeConfig_ = config; + auto transactionProxy = RSTransactionProxy::GetInstance(); + transactionProxy->FlushImplicitTransaction(); } void AbstractScreen::FillScreenInfo(sptr info) const @@ -146,14 +149,35 @@ bool AbstractScreenGroup::AddChild(sptr& dmsScreen, Point& start case ScreenCombination::SCREEN_EXPAND: config = { dmsScreen->rsId_ }; break; - case ScreenCombination::SCREEN_MIRROR: - WLOGE("The feature will be supported in the future"); - return false; + case ScreenCombination::SCREEN_MIRROR: { + if (GetChildCount() == 0 || mirrorScreenId_ == dmsScreen->dmsId_) { + WLOGI("AddChild, SCREEN_MIRROR, config is not mirror"); + config = { dmsScreen->rsId_ }; + break; + } + if (mirrorScreenId_ == INVALID_SCREEN_ID || !HasChild(mirrorScreenId_)) { + WLOGI("AddChild, mirrorScreenId_ is invalid, use default screen"); + mirrorScreenId_ = + DisplayManagerService::GetInstance().GetAbstractScreenController()->GetDefaultAbstractScreenId(); + } + std::shared_ptr displayNode = SingletonContainer::Get(). + GetAbstractScreenController()->GetRSDisplayNodeByScreenId(mirrorScreenId_); + if (displayNode == nullptr) { + WLOGFE("AddChild fail, displayNode is nullptr, cannot get DisplayNode"); + return false; + } + NodeId nodeId = displayNode->GetId(); + WLOGI("AddChild, mirrorScreenId_:%{public}" PRIu64", rsId_:%{public}" PRIu64", nodeId:%{public}" PRIu64"", + mirrorScreenId_, dmsScreen->rsId_, nodeId); + config = {dmsScreen->rsId_, true, nodeId}; + break; + } default: WLOGE("fail to add child. invalid group combination:%{public}u", combination_); return false; } dmsScreen->InitRSDisplayNode(config); + dmsScreen->groupDmsId_ = dmsId_; abstractScreenMap_.insert(std::make_pair(screenId, std::make_pair(dmsScreen, startPoint))); return true; } @@ -180,11 +204,7 @@ bool AbstractScreenGroup::RemoveChild(sptr& dmsScreen) } ScreenId screenId = dmsScreen->dmsId_; dmsScreen->groupDmsId_ = SCREEN_ID_INVALID; - bool res = abstractScreenMap_.erase(screenId); - if (abstractScreenMap_.size() == 1) { - combination_ = ScreenCombination::SCREEN_ALONE; - } - return res; + return abstractScreenMap_.erase(screenId); } bool AbstractScreenGroup::HasChild(ScreenId childScreen) const diff --git a/dmserver/src/abstract_screen_controller.cpp b/dmserver/src/abstract_screen_controller.cpp index fdb11361..572d0851 100644 --- a/dmserver/src/abstract_screen_controller.cpp +++ b/dmserver/src/abstract_screen_controller.cpp @@ -60,12 +60,59 @@ std::vector AbstractScreenController::GetAllScreenIds() return res; } +std::vector AbstractScreenController::GetShotScreenIds(std::vector mirrorScreenIds) const +{ + WLOGI("GetShotScreenIds"); + std::vector result; + for (ScreenId screenId : mirrorScreenIds) { + auto dmsScreenIdIter = dms2RsScreenIdMap_.find(screenId); + auto dmsScreenIter = dmsScreenMap_.find(screenId); + if (dmsScreenIdIter != dms2RsScreenIdMap_.end() && dmsScreenIter == dmsScreenMap_.end()) { + result.emplace_back(screenId); + } + } + for (ScreenId screenId : result) { + WLOGI("GetShotScreenIds: screenId: %{public}" PRIu64"", screenId); + } + return result; +} + +std::vector AbstractScreenController::GetAllMirrorScreenIds(std::vector mirrorScreenIds) const +{ + std::vector result; + for (ScreenId screenId : mirrorScreenIds) { + auto iter = dmsScreenMap_.find(screenId); + if (iter != dmsScreenMap_.end()) { + result.emplace_back(screenId); + } + } + if (result.empty()) { + WLOGI("GetAllMirrorScreenIds, result is empty"); + return result; + } + for (auto iter = dmsScreenMap_.begin(); iter != dmsScreenMap_.end(); iter++) { + if (iter->second->type_ != ScreenType::REAL) { + continue; + } + auto screenIdIter = std::find(result.begin(), result.end(), iter->first); + if (screenIdIter == result.end()) { + result.emplace_back(iter->first); + } + } + for (ScreenId screenId : result) { + WLOGI("GetAllMirrorScreenIds: screenId: %{public}" PRIu64"", screenId); + } + return result; +} + std::shared_ptr AbstractScreenController::GetRSDisplayNodeByScreenId(ScreenId dmsScreenId) const { sptr screen = GetAbstractScreen(dmsScreenId); if (screen == nullptr) { return nullptr; } + WLOGI("GetAbstractScreen: screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ", + screen->dmsId_, screen->rsDisplayNode_->GetId()); return screen->rsDisplayNode_; } @@ -115,6 +162,7 @@ ScreenId AbstractScreenController::GetDefaultAbstractScreenId() } auto iter = rs2DmsScreenIdMap_.find(rsDefaultId); if (iter != rs2DmsScreenIdMap_.end()) { + WLOGI("GetDefaultAbstractScreenId, screen:%{public}" PRIu64"", iter->second); return iter->second; } WLOGFI("GetDefaultAbstractScreenId, default screen is null, try to get."); @@ -205,6 +253,11 @@ void AbstractScreenController::ProcessScreenDisconnected(ScreenId rsScreenId) abstractScreenCallback_->onDisconnected_(dmsScreenMapIter->second); } RemoveFromGroupLocked(dmsScreenMapIter->second); + dmsScreenMapIter->second->rsDisplayNode_->RemoveFromTree(); + auto transactionProxy = RSTransactionProxy::GetInstance(); + if (transactionProxy != nullptr) { + transactionProxy->FlushImplicitTransaction(); + } dmsScreenMap_.erase(dmsScreenMapIter); } rs2DmsScreenIdMap_.erase(iter); @@ -274,6 +327,10 @@ sptr AbstractScreenController::RemoveFromGroupLocked(sptrdmsId_, groupDmsId); return nullptr; } + if (screen->dmsId_ == screenGroup->mirrorScreenId_) { + // Todo: if mirror screen removed and it is SCREEN_MIRROR type, then should make mirror in this group. + screenGroup->mirrorScreenId_ = GetDefaultAbstractScreenId(); + } if (screenGroup->GetChildCount() == 0) { // Group removed, need to do something. dmsScreenGroupMap_.erase(screenGroup->dmsId_); @@ -301,14 +358,13 @@ sptr AbstractScreenController::AddAsFirstScreenLocked(sptr< { ScreenId dmsGroupScreenId = dmsScreenCount_.load(); sptr screenGroup = - new AbstractScreenGroup(dmsGroupScreenId, SCREEN_ID_INVALID, ScreenCombination::SCREEN_ALONE); + new AbstractScreenGroup(dmsGroupScreenId, SCREEN_ID_INVALID, ScreenCombination::SCREEN_MIRROR); Point point; if (!screenGroup->AddChild(newScreen, point)) { WLOGE("fail to add screen to group. screen=%{public}" PRIu64"", newScreen->dmsId_); return nullptr; } dmsScreenCount_++; - newScreen->groupDmsId_ = dmsGroupScreenId; auto iter = dmsScreenGroupMap_.find(dmsGroupScreenId); if (iter != dmsScreenGroupMap_.end()) { WLOGE("group screen existed. id=%{public}" PRIu64"", dmsGroupScreenId); @@ -316,6 +372,7 @@ sptr AbstractScreenController::AddAsFirstScreenLocked(sptr< } dmsScreenGroupMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup)); dmsScreenMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup)); + screenGroup->mirrorScreenId_ = newScreen->dmsId_; WLOGI("connect new group screen. id=%{public}" PRIu64"/%{public}" PRIu64", combination:%{public}u", newScreen->dmsId_, dmsGroupScreenId, newScreen->type_); return screenGroup; @@ -323,12 +380,6 @@ sptr AbstractScreenController::AddAsFirstScreenLocked(sptr< sptr AbstractScreenController::AddAsSuccedentScreenLocked(sptr newScreen) { - auto screenIter = dmsScreenMap_.find(newScreen->dmsId_); - if (screenIter != dmsScreenMap_.end()) { - WLOGE("AddAsSuccedentScreenLocked. screen:%{public}" PRIu64" is already in dmsScreenMap_.", - newScreen->dmsId_); - return nullptr; - } ScreenId defaultScreenId = GetDefaultAbstractScreenId(); auto iter = dmsScreenMap_.find(defaultScreenId); if (iter == dmsScreenMap_.end()) { @@ -346,7 +397,6 @@ sptr AbstractScreenController::AddAsSuccedentScreenLocked(s auto screenGroup = screenGroupIter->second; Point point; screenGroup->AddChild(newScreen, point); - newScreen->groupDmsId_ = screenGroup->dmsId_; return screenGroup; } @@ -355,10 +405,33 @@ ScreenId AbstractScreenController::CreateVirtualScreen(VirtualScreenOption optio if (rsInterface_ == nullptr) { return SCREEN_ID_INVALID; } + std::lock_guard lock(mutex_); ScreenId result = rsInterface_->CreateVirtualScreen(option.name_, option.width_, option.height_, option.surface_, INVALID_SCREEN_ID, option.flags_); WLOGFI("AbstractScreenController::CreateVirtualScreen id: %{public}" PRIu64"", result); - return result; + ScreenId dmsScreenId = SCREEN_ID_INVALID; + auto iter = rs2DmsScreenIdMap_.find(result); + if (iter == rs2DmsScreenIdMap_.end()) { + if (!option.isForShot) { + WLOGI("CreateVirtualScreen is not shot"); + dmsScreenId = dmsScreenCount_; + sptr absScreen = new AbstractScreen(dmsScreenId, result); + absScreen->type_ = ScreenType::VIRTUAL; + dmsScreenCount_++; + rs2DmsScreenIdMap_.insert(std::make_pair(result, dmsScreenId)); + dms2RsScreenIdMap_.insert(std::make_pair(dmsScreenId, result)); + dmsScreenMap_.insert(std::make_pair(dmsScreenId, absScreen)); + DisplayManagerAgentController::GetInstance().OnScreenConnect(absScreen->ConvertToScreenInfo()); + } else { + WLOGI("CreateVirtualScreen is shot"); + dmsScreenId = dmsScreenCount_++; + rs2DmsScreenIdMap_.insert(std::make_pair(result, dmsScreenId)); + dms2RsScreenIdMap_.insert(std::make_pair(dmsScreenId, result)); + } + } else { + return iter->second; + } + return dmsScreenId; } DMError AbstractScreenController::DestroyVirtualScreen(ScreenId screenId) @@ -366,8 +439,25 @@ DMError AbstractScreenController::DestroyVirtualScreen(ScreenId screenId) if (rsInterface_ == nullptr) { return DMError::DM_ERROR_NULLPTR; } + WLOGFI("DumpScreenInfo before Destroy VirtualScreen"); + DumpScreenInfo(); WLOGFI("AbstractScreenController::DestroyVirtualScreen"); - rsInterface_->RemoveVirtualScreen(screenId); + std::lock_guard lock(mutex_); + ScreenId rsScreenId = SCREEN_ID_INVALID; + auto iter = dms2RsScreenIdMap_.find(screenId); + if (iter != dms2RsScreenIdMap_.end()) { + rsScreenId = iter->second; + } + if (rsScreenId != SCREEN_ID_INVALID && GetAbstractScreen(screenId) != nullptr) { + OnRsScreenChange(rsScreenId, ScreenEvent::DISCONNECTED); + } + dms2RsScreenIdMap_.erase(screenId); + rs2DmsScreenIdMap_.erase(rsScreenId); + if (rsScreenId != SCREEN_ID_INVALID) { + rsInterface_->RemoveVirtualScreen(rsScreenId); + } + WLOGFI("DumpScreenInfo after Destroy VirtualScreen"); + DumpScreenInfo(); return DMError::DM_OK; } @@ -393,4 +483,117 @@ bool AbstractScreenController::SetScreenActiveMode(ScreenId screenId, uint32_t m screen->activeIdx_ = modeId; return true; } + +bool AbstractScreenController::MakeMirror(ScreenId screenId, std::vector screens) +{ + WLOGI("AbstractScreenController::MakeMirror, screenId:%{public}" PRIu64"", screenId); + sptr screen = GetAbstractScreen(screenId); + if (screen == nullptr) { + WLOGFE("screen is nullptr"); + return false; + } + WLOGFI("GetAbstractScreenGroup start"); + GetRSDisplayNodeByScreenId(screenId); + auto group = GetAbstractScreenGroup(screen->groupDmsId_); + if (group == nullptr) { + WLOGFE("group is nullptr, try to get"); + ScreenId defaultScreenId = GetDefaultAbstractScreenId(); + auto defaultScreen = GetAbstractScreen(defaultScreenId); + if (defaultScreen == nullptr) { + WLOGFE("defaultScreen is nullptr"); + return false; + } + group = GetAbstractScreenGroup(defaultScreen->groupDmsId_); + if (group == nullptr) { + WLOGFE("group is nullptr"); + return false; + } + } + WLOGFI("GetAbstractScreenGroup end"); + GetRSDisplayNodeByScreenId(screenId); + group->combination_ = ScreenCombination::SCREEN_MIRROR; + group->mirrorScreenId_ = screen->dmsId_; + Point point; + for (ScreenId mirrorScreenId : screens) { + WLOGI("GetAbstractScreen: mirrorScreenId: %{public}" PRIu64"", mirrorScreenId); + auto mirrorScreen = GetAbstractScreen(mirrorScreenId); + if (mirrorScreen == nullptr) { + WLOGFE("mirrorScreen:%{public}" PRIu64" is nullptr", mirrorScreenId); + continue; + } + WLOGI("GetAbstractScreen: mirrorScreen->groupDmsId_: %{public}" PRIu64"", mirrorScreen->groupDmsId_); + auto originGroup = GetAbstractScreenGroup(mirrorScreen->groupDmsId_); + if (originGroup != nullptr) { + originGroup->RemoveChild(mirrorScreen); + } + group->AddChild(mirrorScreen, point); + } + WLOGFI("MakeMirror success"); + return true; +} + +void AbstractScreenController::DumpScreenInfo() const +{ + WLOGI("-------- dump screen info begin---------"); + WLOGI("-------- the Screen Id Map Info---------"); + WLOGI(" DmsScreenId RsScreenId"); + for (auto iter = dms2RsScreenIdMap_.begin(); iter != dms2RsScreenIdMap_.end(); iter++) { + WLOGI("%{public}20" PRIu64" %{public}20" PRIu64"", iter->first, iter->second); + } + WLOGI("-------- the Screen Info ---------"); + WLOGI(" dmsId rsId groupDmsId " + "isGroup type NodeId isMirrored mirrorNodeId"); + for (auto iter = dmsScreenMap_.begin(); iter != dmsScreenMap_.end(); iter++) { + auto screen = iter->second; + std::string screenType; + if (screen->type_ == ScreenType::UNDEFINE) { + screenType = "UNDEFINE"; + } else if (screen->type_ == ScreenType::REAL) { + screenType = "REAL"; + } else { + screenType = "VIRTUAL"; + } + std::string isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false"; + std::string isGroup = (dmsScreenGroupMap_.find(screen->dmsId_) != dmsScreenGroupMap_.end()) ? "true" : "false"; + NodeId nodeId = (screen->rsDisplayNode_ == nullptr) ? INVALID_SCREEN_ID : screen->rsDisplayNode_->GetId(); + WLOGI("%{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}10s %{public}20" + PRIu64" %{public}10s %{public}20" PRIu64" ", screen->dmsId_,screen->rsId_, screen->groupDmsId_, + isGroup.c_str(), screenType.c_str(), nodeId, isMirrored.c_str(), screen->rSDisplayNodeConfig_.mirrorNodeId); + } +} + +void AbstractScreenController::DumpScreenGroupInfo() const +{ + WLOGI("-------- the ScreenGroup Info ---------"); + WLOGI(" isGroup dmsId rsId groupDmsId type " + "NodeId isMirrored mirrorNodeId"); + for (auto iter = dmsScreenGroupMap_.begin(); iter != dmsScreenGroupMap_.end(); iter++) { + auto screenGroup = iter->second; + std::string isMirrored = "false"; + std::string isGroup = "true"; + std::string screenType = "UNDEFINE"; + NodeId nodeId = (screenGroup->rsDisplayNode_ == nullptr) ? 0 : screenGroup->rsDisplayNode_->GetId(); + WLOGI("%{public}10s %{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}20" + PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screenGroup->dmsId_,screenGroup->rsId_, + screenGroup->groupDmsId_, screenType.c_str(), nodeId, + isMirrored.c_str(), screenGroup->rSDisplayNodeConfig_.mirrorNodeId); + auto childrenScreen = screenGroup->GetChildren(); + for (auto screen : childrenScreen) { + std::string isGroup = (dmsScreenGroupMap_.find(screen->dmsId_) != dmsScreenGroupMap_.end()) ? "true" : "false"; + if (screen->type_ == ScreenType::UNDEFINE) { + screenType = "UNDEFINE"; + } else if (screen->type_ == ScreenType::REAL) { + screenType = "REAL"; + } else { + screenType = "VIRTUAL"; + } + isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false"; + nodeId = (screen->rsDisplayNode_ == nullptr) ? 0 : screen->rsDisplayNode_->GetId(); + WLOGI("%{public}10s %{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}20" + PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screen->dmsId_,screen->rsId_, + screen->groupDmsId_, screenType.c_str(), nodeId, + isMirrored.c_str(), screen->rSDisplayNodeConfig_.mirrorNodeId); + } + } +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dmserver/src/display_manager_proxy.cpp b/dmserver/src/display_manager_proxy.cpp index e2b8c690..a21ce726 100644 --- a/dmserver/src/display_manager_proxy.cpp +++ b/dmserver/src/display_manager_proxy.cpp @@ -102,7 +102,7 @@ ScreenId DisplayManagerProxy::CreateVirtualScreen(VirtualScreenOption virtualOpt bool res = data.WriteString(virtualOption.name_) && data.WriteUint32(virtualOption.width_) && data.WriteUint32(virtualOption.height_) && data.WriteFloat(virtualOption.density_) && data.WriteRemoteObject(virtualOption.surface_->GetProducer()->AsObject()) && - data.WriteInt32(virtualOption.flags_); + data.WriteInt32(virtualOption.flags_) && data.WriteBool(virtualOption.isForShot); if (!res) { WLOGFE("DisplayManagerProxy::Write data failed"); return SCREEN_ID_INVALID; diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index 8014019d..4c9e6bc9 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -104,11 +104,15 @@ DisplayInfo DisplayManagerService::GetDisplayInfoById(DisplayId displayId) ScreenId DisplayManagerService::CreateVirtualScreen(VirtualScreenOption option) { WM_SCOPED_TRACE("dms:CreateVirtualScreen(%s)", option.name_.c_str()); + WLOGFI("DumpScreenInfo before Create VirtualScreen"); + abstractScreenController_->DumpScreenInfo(); ScreenId screenId = abstractScreenController_->CreateVirtualScreen(option); if (screenId == SCREEN_ID_INVALID) { WLOGFE("DisplayManagerService::CreateVirtualScreen: Get virtualScreenId failed"); return SCREEN_ID_INVALID; } + WLOGFI("DumpScreenInfo after Create VirtualScreen"); + abstractScreenController_->DumpScreenInfo(); return screenId; } @@ -341,7 +345,19 @@ std::shared_ptr DisplayManagerService::GetRSDisplayNodeByDisplayI DMError DisplayManagerService::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenIds) { - if (mainScreenId == SCREEN_ID_INVALID || mirrorScreenIds.empty()) { + WLOGFI("MakeMirror. mainScreenId :%{public}" PRIu64"", mainScreenId); + abstractScreenController_->DumpScreenInfo(); + auto shotScreenIds = abstractScreenController_->GetShotScreenIds(mirrorScreenIds); + auto iter = std::find(shotScreenIds.begin(), shotScreenIds.end(), mainScreenId); + if (iter != shotScreenIds.end()) { + shotScreenIds.erase(iter); + } + auto allMirrorScreenIds = abstractScreenController_->GetAllMirrorScreenIds(mirrorScreenIds); + iter = std::find(allMirrorScreenIds.begin(), allMirrorScreenIds.end(), mainScreenId); + if (iter != allMirrorScreenIds.end()) { + allMirrorScreenIds.erase(iter); + } + if (mainScreenId == SCREEN_ID_INVALID || (shotScreenIds.empty() && allMirrorScreenIds.empty())) { WLOGFI("create mirror fail, screen is invalid. Screen :%{public}" PRIu64"", mainScreenId); return DMError::DM_ERROR_INVALID_PARAM; } @@ -353,13 +369,24 @@ DMError DisplayManagerService::MakeMirror(ScreenId mainScreenId, std::vectorGetId(); - for (ScreenId mirrorScreenId : mirrorScreenIds) { + WLOGI("MakeMirror, nodeId:%{public}" PRIu64"", nodeId); + for (ScreenId mirrorScreenId : shotScreenIds) { + mirrorScreenId = abstractScreenController_->ConvertToRsScreenId(mirrorScreenId); + if (mirrorScreenId == INVALID_SCREEN_ID) { + continue; + } struct RSDisplayNodeConfig config = {mirrorScreenId, true, nodeId}; displayNodeMap_[mirrorScreenId] = RSDisplayNode::Create(config); } auto transactionProxy = RSTransactionProxy::GetInstance(); transactionProxy->FlushImplicitTransaction(); + + if (!allMirrorScreenIds.empty() && !abstractScreenController_->MakeMirror(mainScreenId, allMirrorScreenIds)) { + WLOGFE("make mirror failed."); + return DMError::DM_ERROR_NULLPTR; + } WLOGFI("create mirror. NodeId: %{public}" PRIu64"", nodeId); + abstractScreenController_->DumpScreenInfo(); return DMError::DM_OK; } diff --git a/dmserver/src/display_manager_stub.cpp b/dmserver/src/display_manager_stub.cpp index eca1de1b..4bfb1717 100644 --- a/dmserver/src/display_manager_stub.cpp +++ b/dmserver/src/display_manager_stub.cpp @@ -57,13 +57,15 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, sptr bp = iface_cast(surfaceObject); sptr surface = Surface::CreateSurfaceAsProducer(bp); int32_t flags = data.ReadInt32(); + bool isForShot = data.ReadBool(); VirtualScreenOption option = { .name_ = name, .width_ = width, .height_ = height, .density_ = density, .surface_ = surface, - .flags_ = flags + .flags_ = flags, + .isForShot = isForShot }; ScreenId screenId = CreateVirtualScreen(option); reply.WriteUint64(static_cast(screenId)); diff --git a/interfaces/innerkits/dm/screen.h b/interfaces/innerkits/dm/screen.h index cee8f44d..9b4a0761 100644 --- a/interfaces/innerkits/dm/screen.h +++ b/interfaces/innerkits/dm/screen.h @@ -48,6 +48,7 @@ struct VirtualScreenOption { float density_; sptr surface_; int32_t flags_; + bool isForShot {true}; }; class Screen : public RefBase { diff --git a/utils/src/screen_info.cpp b/utils/src/screen_info.cpp index 0d1b7956..ecf70230 100644 --- a/utils/src/screen_info.cpp +++ b/utils/src/screen_info.cpp @@ -30,18 +30,23 @@ void ScreenInfo::Update(sptr info) bool ScreenInfo::Marshalling(Parcel &parcel) const { - bool res1 = parcel.WriteUint64(id_) && + bool res = parcel.WriteUint64(id_) && parcel.WriteUint32(virtualWidth_) && parcel.WriteUint32(virtualHeight_) && parcel.WriteFloat(virtualPixelRatio_) && parcel.WriteUint64(parent_) && parcel.WriteBool(hasChild_) && parcel.WriteUint32(modeId_) && parcel.WriteUint32(static_cast(modes_.size())); - bool res2 = true; - for (uint32_t modeIndex = 0; modeIndex < modes_.size(); modeIndex++) { - res2 = res2 && parcel.WriteUint32(modes_[modeIndex]->height_) && - parcel.WriteUint32(modes_[modeIndex]->width_) && - parcel.WriteUint32(modes_[modeIndex]->freshRate_); + if (!res) { + return false; } - return res1 && res2; + for (uint32_t modeIndex = 0; modeIndex < modes_.size(); modeIndex++) { + if (parcel.WriteUint32(modes_[modeIndex]->height_) && + parcel.WriteUint32(modes_[modeIndex]->width_) && + parcel.WriteUint32(modes_[modeIndex]->freshRate_)) { + continue; + } + return false; + } + return true; } ScreenInfo* ScreenInfo::Unmarshalling(Parcel &parcel) @@ -61,17 +66,16 @@ ScreenInfo* ScreenInfo::InnerUnmarshalling(Parcel& parcel) if (!res1) { return nullptr; } - bool res2 = true; modes_.clear(); for (uint32_t modeIndex = 0; modeIndex < size; modeIndex++) { sptr mode = new SupportedScreenModes(); - res2 = res2 && parcel.ReadUint32(mode->height_) && + if (parcel.ReadUint32(mode->height_) && parcel.ReadUint32(mode->width_) && - parcel.ReadUint32(mode->freshRate_); - modes_.push_back(mode); - } - if (!res2) { - return nullptr; + parcel.ReadUint32(mode->freshRate_)) { + modes_.push_back(mode); + } else { + return nullptr; + } } return this; } diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 213eddf3..8c643078 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -29,7 +29,7 @@ namespace OHOS { namespace Rosen { class WindowNodeContainer : public RefBase { public: - WindowNodeContainer(uint64_t displayId, uint32_t width, uint32_t height); + WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height); ~WindowNodeContainer(); WMError AddWindowNode(sptr& node, sptr& parentNode); WMError RemoveWindowNode(sptr& node); diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 140da5ac..129462d7 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -564,7 +564,7 @@ void WindowNodeContainer::OnAvoidAreaChange(const std::vector& avoidArea) void WindowNodeContainer::DumpScreenWindowTree() { - WLOGFI("-------- Screen %{public}" PRIu64" dump window info begin---------", displayId_); + WLOGFI("-------- display %{public}" PRIu64" dump window info begin---------", displayId_); WLOGFI("WindowName WinId Type Mode Flag ZOrd [ x y w h]"); std::vector> windowNodes; TraverseContainer(windowNodes); @@ -578,7 +578,7 @@ void WindowNodeContainer::DumpScreenWindowTree() node->GetWindowMode(), node->GetWindowFlags(), --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_); } - WLOGFI("-------- Screen %{public}" PRIu64" dump window info end ---------", displayId_); + WLOGFI("-------- display %{public}" PRIu64" dump window info end ---------", displayId_); } uint64_t WindowNodeContainer::GetScreenId() const