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 "ui/rs_display_node.h"
17 
18 #include "rs_trace.h"
19 
20 #include "command/rs_display_node_command.h"
21 #include "pipeline/rs_node_map.h"
22 #include "platform/common/rs_log.h"
23 #include "transaction/rs_render_service_client.h"
24 #include "transaction/rs_transaction_proxy.h"
25 namespace OHOS {
26 namespace Rosen {
27 
Create(const RSDisplayNodeConfig & displayNodeConfig)28 RSDisplayNode::SharedPtr RSDisplayNode::Create(const RSDisplayNodeConfig& displayNodeConfig)
29 {
30     SharedPtr node(new RSDisplayNode(displayNodeConfig));
31     RSNodeMap::MutableInstance().RegisterNode(node);
32 
33     if (LIKELY(!displayNodeConfig.isSync)) {
34         std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeCreate>(node->GetId(), displayNodeConfig);
35         auto transactionProxy = RSTransactionProxy::GetInstance();
36         if (transactionProxy != nullptr) {
37             transactionProxy->AddCommand(command, true);
38         }
39     } else {
40         if (!node->CreateNode(displayNodeConfig, node->GetId())) {
41             ROSEN_LOGE("RSDisplayNode::Create: CreateNode Failed.");
42             return nullptr;
43         }
44     }
45     ROSEN_LOGI("RSDisplayNode::Create, id:%{public}" PRIu64, node->GetId());
46     return node;
47 }
48 
CreateNode(const RSDisplayNodeConfig & displayNodeConfig,NodeId nodeId)49 bool RSDisplayNode::CreateNode(const RSDisplayNodeConfig& displayNodeConfig, NodeId nodeId)
50 {
51     return std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient())->
52         CreateNode(displayNodeConfig, nodeId);
53 }
54 
AddDisplayNodeToTree()55 void RSDisplayNode::AddDisplayNodeToTree()
56 {
57     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeAddToTree>(GetId());
58     auto transactionProxy = RSTransactionProxy::GetInstance();
59     if (transactionProxy != nullptr) {
60         transactionProxy->AddCommand(command, true);
61     }
62     ROSEN_LOGI("RSDisplayNode::AddDisplayNodeToTree, id:%{public}" PRIu64, GetId());
63 }
64 
RemoveDisplayNodeFromTree()65 void RSDisplayNode::RemoveDisplayNodeFromTree()
66 {
67     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeRemoveFromTree>(GetId());
68     auto transactionProxy = RSTransactionProxy::GetInstance();
69     if (transactionProxy != nullptr) {
70         transactionProxy->AddCommand(command, true);
71     }
72     ROSEN_LOGI("RSDisplayNode::RemoveDisplayNodeFromTree, id:%{public}" PRIu64, GetId());
73 }
74 
Marshalling(Parcel & parcel) const75 bool RSDisplayNode::Marshalling(Parcel& parcel) const
76 {
77     return parcel.WriteUint64(GetId()) && parcel.WriteUint64(screenId_) && parcel.WriteBool(isMirroredDisplay_);
78 }
79 
Unmarshalling(Parcel & parcel)80 RSDisplayNode::SharedPtr RSDisplayNode::Unmarshalling(Parcel& parcel)
81 {
82     uint64_t id = UINT64_MAX;
83     uint64_t screenId = UINT64_MAX;
84     bool isMirrored = false;
85     if (!(parcel.ReadUint64(id) && parcel.ReadUint64(screenId) && parcel.ReadBool(isMirrored))) {
86         ROSEN_LOGE("RSDisplayNode::Unmarshalling, read param failed");
87         return nullptr;
88     }
89 
90     if (auto prevNode = RSNodeMap::Instance().GetNode(id)) {
91         // if the node id is already in the map, we should not create a new node
92         return prevNode->ReinterpretCastTo<RSDisplayNode>();
93     }
94 
95     RSDisplayNodeConfig config { .screenId = screenId, .isMirrored = isMirrored };
96 
97     SharedPtr displayNode(new RSDisplayNode(config, id));
98     RSNodeMap::MutableInstance().RegisterNode(displayNode);
99 
100     // for nodes constructed by unmarshalling, we should not destroy the corresponding render node on destruction
101     displayNode->skipDestroyCommandInDestructor_ = true;
102 
103     return displayNode;
104 }
105 
ClearChildren()106 void RSDisplayNode::ClearChildren()
107 {
108     auto children = GetChildren();
109     for (auto child : children) {
110         if (auto childPtr = RSNodeMap::Instance().GetNode(child)) {
111             RemoveChild(childPtr);
112         }
113     }
114 }
115 
SetScreenId(uint64_t screenId)116 void RSDisplayNode::SetScreenId(uint64_t screenId)
117 {
118     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetScreenId>(GetId(), screenId);
119     auto transactionProxy = RSTransactionProxy::GetInstance();
120     if (transactionProxy != nullptr) {
121         transactionProxy->AddCommand(command, true);
122     }
123     ROSEN_LOGI(
124         "RSDisplayNode::SetScreenId, DisplayNode: %{public}" PRIu64 ", ScreenId: %{public}" PRIu64, GetId(), screenId);
125     RS_TRACE_NAME_FMT("RSDisplayNode::SetScreenId, DisplayNode: %" PRIu64 ", ScreenId: %" PRIu64, GetId(), screenId);
126 }
127 
OnBoundsSizeChanged() const128 void RSDisplayNode::OnBoundsSizeChanged() const
129 {
130     auto bounds = GetStagingProperties().GetBounds();
131     ROSEN_LOGD("RSDisplayNode::OnBoundsSizeChanged, w: %{public}d, h: %{public}d.",
132         (uint32_t)bounds.z_, (uint32_t)bounds.w_);
133     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetRogSize>(GetId(), bounds.z_, bounds.w_);
134     auto transactionProxy = RSTransactionProxy::GetInstance();
135     if (transactionProxy != nullptr) {
136         transactionProxy->AddCommand(command, true);
137     }
138 }
139 
SetDisplayOffset(int32_t offsetX,int32_t offsetY)140 void RSDisplayNode::SetDisplayOffset(int32_t offsetX, int32_t offsetY)
141 {
142     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetDisplayOffset>(GetId(), offsetX, offsetY);
143     auto transactionProxy = RSTransactionProxy::GetInstance();
144     if (transactionProxy != nullptr) {
145         transactionProxy->AddCommand(command, true);
146     }
147     ROSEN_LOGD("RSDisplayNode::SetDisplayOffset, offsetX:%{public}d, offsetY:%{public}d", offsetX, offsetY);
148 }
149 
SetSecurityDisplay(bool isSecurityDisplay)150 void RSDisplayNode::SetSecurityDisplay(bool isSecurityDisplay)
151 {
152     isSecurityDisplay_ = isSecurityDisplay;
153     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetSecurityDisplay>(GetId(), isSecurityDisplay);
154     auto transactionProxy = RSTransactionProxy::GetInstance();
155     if (transactionProxy != nullptr) {
156         transactionProxy->AddCommand(command, true);
157     }
158     ROSEN_LOGD("RSDisplayNode::SetSecurityDisplay, displayNodeId:[%{public}" PRIu64 "]"
159         " isSecurityDisplay:[%{public}s]", GetId(), isSecurityDisplay ? "true" : "false");
160 }
161 
GetSecurityDisplay() const162 bool RSDisplayNode::GetSecurityDisplay() const
163 {
164     return isSecurityDisplay_;
165 }
166 
SetDisplayNodeMirrorConfig(const RSDisplayNodeConfig & displayNodeConfig)167 void RSDisplayNode::SetDisplayNodeMirrorConfig(const RSDisplayNodeConfig& displayNodeConfig)
168 {
169     isMirroredDisplay_ = displayNodeConfig.isMirrored;
170     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetDisplayMode>(GetId(), displayNodeConfig);
171     auto transactionProxy = RSTransactionProxy::GetInstance();
172     if (transactionProxy != nullptr) {
173         transactionProxy->AddCommand(command, true);
174     }
175     ROSEN_LOGD("RSDisplayNode::SetDisplayNodeMirrorConfig, displayNodeId:[%{public}" PRIu64 "]"
176         " isMirrored:[%{public}s]", GetId(), displayNodeConfig.isMirrored ? "true" : "false");
177 }
178 
SetScreenRotation(const uint32_t & rotation)179 void RSDisplayNode::SetScreenRotation(const uint32_t& rotation)
180 {
181     ScreenRotation screenRotation = ScreenRotation::ROTATION_0;
182     switch (rotation) {
183         case 0: // Rotation::ROTATION_0
184             screenRotation = ScreenRotation::ROTATION_0;
185             break;
186         case 1: // Rotation::ROTATION_90
187             screenRotation = ScreenRotation::ROTATION_90;
188             break;
189         case 2: // Rotation::ROTATION_180
190             screenRotation = ScreenRotation::ROTATION_180;
191             break;
192         case 3: // Rotation::ROTATION_270
193             screenRotation = ScreenRotation::ROTATION_270;
194             break;
195         default:
196             screenRotation = ScreenRotation::INVALID_SCREEN_ROTATION;
197             break;
198     }
199     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetScreenRotation>(GetId(), screenRotation);
200     auto transactionProxy = RSTransactionProxy::GetInstance();
201     if (transactionProxy != nullptr) {
202         transactionProxy->AddCommand(command, true);
203     }
204     ROSEN_LOGI("RSDisplayNode::SetScreenRotation, displayNodeId:[%{public}" PRIu64 "]"
205                " screenRotation:[%{public}d]", GetId(), rotation);
206 }
207 
IsMirrorDisplay() const208 bool RSDisplayNode::IsMirrorDisplay() const
209 {
210     return isMirroredDisplay_;
211 }
212 
RSDisplayNode(const RSDisplayNodeConfig & config)213 RSDisplayNode::RSDisplayNode(const RSDisplayNodeConfig& config)
214     : RSNode(true), screenId_(config.screenId), offsetX_(0), offsetY_(0), isMirroredDisplay_(config.isMirrored)
215 {
216     (void)screenId_;
217     (void)offsetX_;
218     (void)offsetY_;
219 }
220 
RSDisplayNode(const RSDisplayNodeConfig & config,NodeId id)221 RSDisplayNode::RSDisplayNode(const RSDisplayNodeConfig& config, NodeId id)
222     : RSNode(true, id), screenId_(config.screenId), offsetX_(0), offsetY_(0), isMirroredDisplay_(config.isMirrored)
223 {}
224 
SetBootAnimation(bool isBootAnimation)225 void RSDisplayNode::SetBootAnimation(bool isBootAnimation)
226 {
227     isBootAnimation_ = isBootAnimation;
228     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetBootAnimation>(GetId(), isBootAnimation);
229     auto transactionProxy = RSTransactionProxy::GetInstance();
230     if (transactionProxy != nullptr) {
231         transactionProxy->AddCommand(command, true);
232     }
233 }
234 
GetBootAnimation() const235 bool RSDisplayNode::GetBootAnimation() const
236 {
237     return isBootAnimation_;
238 }
239 
SetScbNodePid(const std::vector<int32_t> & oldScbPids,int32_t currentScbPid)240 void RSDisplayNode::SetScbNodePid(const std::vector<int32_t>& oldScbPids, int32_t currentScbPid)
241 {
242     std::unique_ptr<RSCommand> command = std::make_unique<RSDisplayNodeSetNodePid>(GetId(), oldScbPids, currentScbPid);
243     auto transactionProxy = RSTransactionProxy::GetInstance();
244     if (transactionProxy != nullptr) {
245         transactionProxy->AddCommand(command, true);
246     }
247     std::ostringstream oldPidsStr;
248     oldPidsStr << " NodeId: " << GetId();
249     oldPidsStr << " currentScbPid: " << currentScbPid;
250     oldPidsStr << " oldScbPids:";
251     for (auto iter = oldScbPids.begin(); iter != oldScbPids.end(); ++iter) {
252         oldPidsStr << *iter << ",";
253     }
254     DoFlushModifier();
255     ROSEN_LOGI("SetScbNodePid %{public}s", oldPidsStr.str().c_str());
256 }
257 
258 RSDisplayNode::~RSDisplayNode() = default;
259 
260 } // namespace Rosen
261 } // namespace OHOS
262