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