1 /*
2 * Copyright (c) 2021-2023 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 "transaction/rs_transaction_proxy.h"
17 #include <stdlib.h>
18
19 #include "platform/common/rs_log.h"
20 #include "rs_trace.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 std::once_flag RSTransactionProxy::flag_;
25 RSTransactionProxy* RSTransactionProxy::instance_ = nullptr;
26
GetInstance()27 RSTransactionProxy* RSTransactionProxy::GetInstance()
28 {
29 std::call_once(flag_, &RSTransactionProxy::Init);
30 return instance_;
31 }
32
RSTransactionProxy()33 RSTransactionProxy::RSTransactionProxy()
34 {
35 }
36
~RSTransactionProxy()37 RSTransactionProxy::~RSTransactionProxy()
38 {
39 }
40
Init()41 void RSTransactionProxy::Init()
42 {
43 instance_ = new RSTransactionProxy();
44 ::atexit(&RSTransactionProxy::Destroy);
45 }
46
Destroy()47 void RSTransactionProxy::Destroy()
48 {
49 instance_ = nullptr;
50 }
51
SetRenderThreadClient(std::unique_ptr<RSIRenderClient> & renderThreadClient)52 void RSTransactionProxy::SetRenderThreadClient(std::unique_ptr<RSIRenderClient>& renderThreadClient)
53 {
54 if (renderThreadClient != nullptr) {
55 renderThreadClient_ = std::move(renderThreadClient);
56 }
57 }
58
SetRenderServiceClient(const std::shared_ptr<RSIRenderClient> & renderServiceClient)59 void RSTransactionProxy::SetRenderServiceClient(const std::shared_ptr<RSIRenderClient>& renderServiceClient)
60 {
61 if (renderServiceClient != nullptr) {
62 renderServiceClient_ = renderServiceClient;
63 }
64 }
65
AddCommand(std::unique_ptr<RSCommand> & command,bool isRenderServiceCommand,FollowType followType,NodeId nodeId)66 void RSTransactionProxy::AddCommand(std::unique_ptr<RSCommand>& command, bool isRenderServiceCommand,
67 FollowType followType, NodeId nodeId)
68 {
69 if ((renderServiceClient_ == nullptr && renderThreadClient_ == nullptr) || command == nullptr) {
70 RS_LOGE("RSTransactionProxy::add command fail, (renderServiceClient_ and renderThreadClient_ is nullptr)"
71 " or command is nullptr");
72 return;
73 }
74
75 std::unique_lock<std::mutex> cmdLock(mutex_);
76
77 RS_LOGI_IF(DEBUG_NODE,
78 "RSTransactionProxy::add command nodeId:%{public}" PRIu64 " isRenderServiceCommand:%{public}d"
79 " followType:%{public}hu", nodeId, isRenderServiceCommand, followType);
80 if (renderServiceClient_ != nullptr && (isRenderServiceCommand || renderThreadClient_ == nullptr)) {
81 AddRemoteCommand(command, nodeId, followType);
82 return;
83 }
84
85 if (!isRenderServiceCommand) {
86 AddCommonCommand(command);
87 return;
88 }
89 ROSEN_LOGE("RSTransactionProxy::AddCommand failed, isRenderServiceCommand:%{public}d %{public}s",
90 isRenderServiceCommand, command->PrintType().c_str());
91 }
92
AddCommandFromRT(std::unique_ptr<RSCommand> & command,NodeId nodeId,FollowType followType)93 void RSTransactionProxy::AddCommandFromRT(std::unique_ptr<RSCommand>& command, NodeId nodeId, FollowType followType)
94 {
95 if (renderServiceClient_ == nullptr || command == nullptr) {
96 return;
97 }
98
99 {
100 std::unique_lock<std::mutex> cmdLock(mutexForRT_);
101 implicitTransactionDataFromRT_->AddCommand(command, nodeId, followType);
102 }
103 }
104
ExecuteSynchronousTask(const std::shared_ptr<RSSyncTask> & task,bool isRenderServiceTask)105 void RSTransactionProxy::ExecuteSynchronousTask(const std::shared_ptr<RSSyncTask>& task, bool isRenderServiceTask)
106 {
107 if (!task) {
108 ROSEN_LOGE("RSTransactionProxy::ExecuteSynchronousTask failed, the task is not exist.");
109 return;
110 }
111
112 if (renderServiceClient_ && isRenderServiceTask) {
113 renderServiceClient_->ExecuteSynchronousTask(task);
114 return;
115 }
116
117 if (renderThreadClient_ && (!isRenderServiceTask)) {
118 renderThreadClient_->ExecuteSynchronousTask(task);
119 return;
120 }
121
122 ROSEN_LOGE("RSTransactionProxy::ExecuteSynchronousTask failed, isRenderServiceTask is %{public}d.",
123 isRenderServiceTask);
124 }
125
FlushImplicitTransaction(uint64_t timestamp,const std::string & abilityName)126 void RSTransactionProxy::FlushImplicitTransaction(uint64_t timestamp, const std::string& abilityName)
127 {
128 std::unique_lock<std::mutex> cmdLock(mutex_);
129 if (!implicitRemoteTransactionDataStack_.empty() && needSync_) {
130 RS_LOGE_LIMIT(__func__, __line__, "FlushImplicitTransaction failed, DataStack not empty");
131 return;
132 }
133 timestamp_ = std::max(timestamp, timestamp_);
134 if (renderThreadClient_ != nullptr && !implicitCommonTransactionData_->IsEmpty()) {
135 implicitCommonTransactionData_->timestamp_ = timestamp_;
136 implicitCommonTransactionData_->abilityName_ = abilityName;
137 renderThreadClient_->CommitTransaction(implicitCommonTransactionData_);
138 implicitCommonTransactionData_ = std::make_unique<RSTransactionData>();
139 } else {
140 if (flushEmptyCallback_) {
141 flushEmptyCallback_(timestamp_);
142 }
143 }
144
145 if (renderServiceClient_ != nullptr && !implicitRemoteTransactionData_->IsEmpty()) {
146 implicitRemoteTransactionData_->timestamp_ = timestamp_;
147 renderServiceClient_->CommitTransaction(implicitRemoteTransactionData_);
148 transactionDataIndex_ = implicitRemoteTransactionData_->GetIndex();
149 implicitRemoteTransactionData_ = std::make_unique<RSTransactionData>();
150 } else {
151 RS_LOGE_LIMIT(__func__, __line__, "FlushImplicitTransaction return, [renderServiceClient_:%{public}d,]" \
152 " transactionData empty:%{public}d",
153 renderServiceClient_ != nullptr, implicitRemoteTransactionData_->IsEmpty());
154 }
155 }
156
GetTransactionDataIndex() const157 uint32_t RSTransactionProxy::GetTransactionDataIndex() const
158 {
159 return transactionDataIndex_;
160 }
161
IsEmpty() const162 bool RSTransactionProxy::IsEmpty() const
163 {
164 bool isEmpty = true;
165 std::unique_lock<std::mutex> cmdLock(mutex_);
166 if (implicitCommonTransactionData_) {
167 isEmpty &= implicitCommonTransactionData_->IsEmpty();
168 }
169 if (implicitRemoteTransactionData_) {
170 isEmpty &= implicitRemoteTransactionData_->IsEmpty();
171 }
172 isEmpty &= implicitCommonTransactionDataStack_.empty();
173 isEmpty &= implicitRemoteTransactionDataStack_.empty();
174 return isEmpty;
175 }
176
FlushImplicitTransactionFromRT(uint64_t timestamp)177 void RSTransactionProxy::FlushImplicitTransactionFromRT(uint64_t timestamp)
178 {
179 std::unique_lock<std::mutex> cmdLock(mutexForRT_);
180 if (renderServiceClient_ != nullptr && !implicitTransactionDataFromRT_->IsEmpty()) {
181 implicitTransactionDataFromRT_->timestamp_ = timestamp;
182 renderServiceClient_->CommitTransaction(implicitTransactionDataFromRT_);
183 implicitTransactionDataFromRT_ = std::make_unique<RSTransactionData>();
184 }
185 }
186
StartSyncTransaction()187 void RSTransactionProxy::StartSyncTransaction()
188 {
189 needSync_ = true;
190 }
191
CloseSyncTransaction()192 void RSTransactionProxy::CloseSyncTransaction()
193 {
194 needSync_ = false;
195 }
196
StartCloseSyncTransactionFallbackTask(std::shared_ptr<AppExecFwk::EventHandler> handler,bool isOpen)197 void RSTransactionProxy::StartCloseSyncTransactionFallbackTask(
198 std::shared_ptr<AppExecFwk::EventHandler> handler, bool isOpen)
199 {
200 std::unique_lock<std::mutex> cmdLock(mutex_);
201 static uint32_t num = 0;
202 const std::string name = "CloseSyncTransactionFallbackTask";
203 const int timeOutDelay = 5000;
204 if (!handler) {
205 ROSEN_LOGD("StartCloseSyncTransactionFallbackTask handler is null");
206 return;
207 }
208 if (isOpen) {
209 num++;
210 auto taskName = name + std::to_string(num);
211 taskNames_.push(taskName);
212 auto task = [this]() {
213 RS_TRACE_NAME("CloseSyncTransaction timeout");
214 ROSEN_LOGE("CloseSyncTransaction timeout");
215 auto transactionProxy = RSTransactionProxy::GetInstance();
216 if (transactionProxy != nullptr) {
217 transactionProxy->CommitSyncTransaction();
218 transactionProxy->CloseSyncTransaction();
219 }
220 if (!taskNames_.empty()) {
221 taskNames_.pop();
222 }
223 };
224 handler->PostTask(task, taskName, timeOutDelay);
225 } else {
226 if (!taskNames_.empty()) {
227 handler->RemoveTask(taskNames_.front());
228 taskNames_.pop();
229 }
230 }
231 }
232
Begin()233 void RSTransactionProxy::Begin()
234 {
235 std::unique_lock<std::mutex> cmdLock(mutex_);
236 implicitCommonTransactionDataStack_.emplace(std::make_unique<RSTransactionData>());
237 implicitRemoteTransactionDataStack_.emplace(std::make_unique<RSTransactionData>());
238 if (needSync_) {
239 implicitCommonTransactionDataStack_.top()->MarkNeedSync();
240 implicitRemoteTransactionDataStack_.top()->MarkNeedSync();
241 }
242 }
243
Commit(uint64_t timestamp)244 void RSTransactionProxy::Commit(uint64_t timestamp)
245 {
246 std::unique_lock<std::mutex> cmdLock(mutex_);
247 if (!implicitCommonTransactionDataStack_.empty()) {
248 implicitCommonTransactionDataStack_.pop();
249 }
250
251 if (!implicitRemoteTransactionDataStack_.empty()) {
252 if (renderServiceClient_ != nullptr && !implicitRemoteTransactionDataStack_.top()->IsEmpty()) {
253 implicitRemoteTransactionDataStack_.top()->timestamp_ = timestamp;
254 renderServiceClient_->CommitTransaction(implicitRemoteTransactionDataStack_.top());
255 }
256 implicitRemoteTransactionDataStack_.pop();
257 }
258 }
259
CommitSyncTransaction(uint64_t timestamp,const std::string & abilityName)260 void RSTransactionProxy::CommitSyncTransaction(uint64_t timestamp, const std::string& abilityName)
261 {
262 std::unique_lock<std::mutex> cmdLock(mutex_);
263 timestamp_ = std::max(timestamp, timestamp_);
264 if (!implicitCommonTransactionDataStack_.empty()) {
265 if (renderThreadClient_ != nullptr && (!implicitCommonTransactionDataStack_.top()->IsEmpty() ||
266 implicitCommonTransactionDataStack_.top()->IsNeedSync())) {
267 implicitCommonTransactionDataStack_.top()->timestamp_ = timestamp;
268 implicitCommonTransactionDataStack_.top()->abilityName_ = abilityName;
269 implicitCommonTransactionDataStack_.top()->SetSyncId(syncId_);
270 renderThreadClient_->CommitTransaction(implicitCommonTransactionDataStack_.top());
271 }
272 implicitCommonTransactionDataStack_.pop();
273 }
274
275 if (!implicitRemoteTransactionDataStack_.empty()) {
276 if (renderServiceClient_ != nullptr && (!implicitRemoteTransactionDataStack_.top()->IsEmpty() ||
277 implicitRemoteTransactionDataStack_.top()->IsNeedSync())) {
278 implicitRemoteTransactionDataStack_.top()->timestamp_ = timestamp;
279 implicitRemoteTransactionDataStack_.top()->SetSyncId(syncId_);
280 renderServiceClient_->CommitTransaction(implicitRemoteTransactionDataStack_.top());
281 }
282 implicitRemoteTransactionDataStack_.pop();
283 }
284 }
285
MarkTransactionNeedSync()286 void RSTransactionProxy::MarkTransactionNeedSync()
287 {
288 std::unique_lock<std::mutex> cmdLock(mutex_);
289 if (!implicitCommonTransactionDataStack_.empty()) {
290 implicitCommonTransactionDataStack_.top()->MarkNeedSync();
291 }
292
293 if (!implicitRemoteTransactionDataStack_.empty()) {
294 implicitRemoteTransactionDataStack_.top()->MarkNeedSync();
295 }
296 }
297
MarkTransactionNeedCloseSync(const int32_t transactionCount)298 void RSTransactionProxy::MarkTransactionNeedCloseSync(const int32_t transactionCount)
299 {
300 std::unique_lock<std::mutex> cmdLock(mutex_);
301 if (!implicitCommonTransactionDataStack_.empty()) {
302 implicitCommonTransactionDataStack_.top()->MarkNeedSync();
303 implicitCommonTransactionDataStack_.top()->MarkNeedCloseSync();
304 implicitCommonTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
305 }
306
307 if (!implicitRemoteTransactionDataStack_.empty()) {
308 implicitRemoteTransactionDataStack_.top()->MarkNeedSync();
309 implicitRemoteTransactionDataStack_.top()->MarkNeedCloseSync();
310 implicitRemoteTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
311 }
312 }
313
SetSyncTransactionNum(const int32_t transactionCount)314 void RSTransactionProxy::SetSyncTransactionNum(const int32_t transactionCount)
315 {
316 std::unique_lock<std::mutex> cmdLock(mutex_);
317 if (!implicitCommonTransactionDataStack_.empty()) {
318 implicitCommonTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
319 }
320
321 if (!implicitRemoteTransactionDataStack_.empty()) {
322 implicitRemoteTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
323 }
324 }
325
SetParentPid(const int32_t parentPid)326 void RSTransactionProxy::SetParentPid(const int32_t parentPid)
327 {
328 std::unique_lock<std::mutex> cmdLock(mutex_);
329 if (!implicitCommonTransactionDataStack_.empty()) {
330 implicitCommonTransactionDataStack_.top()->SetParentPid(parentPid);
331 }
332
333 if (!implicitRemoteTransactionDataStack_.empty()) {
334 implicitRemoteTransactionDataStack_.top()->SetParentPid(parentPid);
335 }
336 }
337
AddCommonCommand(std::unique_ptr<RSCommand> & command)338 void RSTransactionProxy::AddCommonCommand(std::unique_ptr<RSCommand> &command)
339 {
340 if (!implicitCommonTransactionDataStack_.empty()) {
341 implicitCommonTransactionDataStack_.top()->AddCommand(command, 0, FollowType::NONE);
342 return;
343 }
344 implicitCommonTransactionData_->AddCommand(command, 0, FollowType::NONE);
345 }
346
AddRemoteCommand(std::unique_ptr<RSCommand> & command,NodeId nodeId,FollowType followType)347 void RSTransactionProxy::AddRemoteCommand(std::unique_ptr<RSCommand>& command, NodeId nodeId, FollowType followType)
348 {
349 if (!implicitRemoteTransactionDataStack_.empty()) {
350 implicitRemoteTransactionDataStack_.top()->AddCommand(command, nodeId, followType);
351 return;
352 }
353 implicitRemoteTransactionData_->AddCommand(command, nodeId, followType);
354 }
355
356 } // namespace Rosen
357 } // namespace OHOS
358