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