• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_handler.h"
17 
18 #include <cstdlib>
19 
20 #ifdef ROSEN_OHOS
21 #include "mem_mgr_client.h"
22 #endif
23 #include "rs_trace.h"
24 
25 #include "platform/common/rs_log.h"
26 #include "sandbox_utils.h"
27 #include "transaction/rs_transaction_proxy.h"
28 
29 #ifdef _WIN32
30 #include <windows.h>
31 #define gettid GetCurrentThreadId
32 #endif
33 
34 #ifdef __APPLE__
35 #define gettid getpid
36 #endif
37 
38 #ifdef __gnu_linux__
39 #include <sys/syscall.h>
40 #include <sys/types.h>
41 #define gettid []()->int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); }
42 #endif
43 
44 namespace OHOS {
45 namespace Rosen {
46 CommitTransactionCallback RSTransactionHandler::commitTransactionCallback_ = nullptr;
SetRenderThreadClient(std::unique_ptr<RSIRenderClient> & renderThreadClient)47 void RSTransactionHandler::SetRenderThreadClient(std::unique_ptr<RSIRenderClient>& renderThreadClient)
48 {
49     if (renderThreadClient != nullptr) {
50         renderThreadClient_ = std::move(renderThreadClient);
51     }
52 }
53 
SetRenderServiceClient(const std::shared_ptr<RSIRenderClient> & renderServiceClient)54 void RSTransactionHandler::SetRenderServiceClient(const std::shared_ptr<RSIRenderClient>& renderServiceClient)
55 {
56     if (renderServiceClient != nullptr) {
57         renderServiceClient_ = renderServiceClient;
58     }
59 }
60 
AddCommand(std::unique_ptr<RSCommand> & command,bool isRenderServiceCommand,FollowType followType,NodeId nodeId)61 void RSTransactionHandler::AddCommand(
62     std::unique_ptr<RSCommand>& command, bool isRenderServiceCommand, FollowType followType, NodeId nodeId)
63 {
64 #ifndef SCREENLESS_DEVICE
65     if ((renderServiceClient_ == nullptr && renderThreadClient_ == nullptr) || command == nullptr) {
66         RS_LOGE("RSTransactionHandler::add command fail, (renderServiceClient_ and renderThreadClient_ is nullptr)"
67                 " or command is nullptr");
68         return;
69     }
70 
71     std::unique_lock<std::mutex> cmdLock(mutex_);
72 
73     RS_LOGI_IF(DEBUG_NODE,
74         "RSTransactionHandler::add command nodeId:%{public}" PRIu64 " isRenderServiceCommand:%{public}d"
75         " followType:%{public}hu",
76         nodeId, isRenderServiceCommand, followType);
77     if (renderServiceClient_ != nullptr && isRenderServiceCommand) {
78         AddRemoteCommand(command, nodeId, followType);
79         return;
80     }
81 
82     if (!isRenderServiceCommand) {
83         AddCommonCommand(command);
84         return;
85     }
86     ROSEN_LOGE("RSTransactionHandler::AddCommand failed, isRenderServiceCommand:%{public}d %{public}s",
87         isRenderServiceCommand, command->PrintType().c_str());
88 #endif
89 }
90 
AddCommandFromRT(std::unique_ptr<RSCommand> & command,NodeId nodeId,FollowType followType)91 void RSTransactionHandler::AddCommandFromRT(std::unique_ptr<RSCommand>& command, NodeId nodeId, FollowType followType)
92 {
93     if (renderServiceClient_ == nullptr || command == nullptr) {
94         return;
95     }
96 
97     {
98         std::unique_lock<std::mutex> cmdLock(mutexForRT_);
99         implicitTransactionDataFromRT_->AddCommand(command, nodeId, followType);
100     }
101 }
102 
MoveCommandByNodeId(std::shared_ptr<RSTransactionHandler> transactionHandler,NodeId nodeId)103 void RSTransactionHandler::MoveCommandByNodeId(std::shared_ptr<RSTransactionHandler> transactionHandler, NodeId nodeId)
104 {
105     if (renderServiceClient_ == nullptr && renderThreadClient_ == nullptr) {
106         RS_LOGE("RSTransactionHandler::MoveCommandByNodeId GetCommand fail, (renderServiceClient_ and "
107                 "renderThreadClient_ is nullptr)");
108         return;
109     }
110 
111     std::unique_lock<std::mutex> cmdLock(mutex_);
112     if (renderServiceClient_ != nullptr) {
113         MoveRemoteCommandByNodeId(transactionHandler, nodeId);
114     }
115     if (renderThreadClient_ != nullptr) {
116         MoveCommonCommandByNodeId(transactionHandler, nodeId);
117     }
118 }
119 
ExecuteSynchronousTask(const std::shared_ptr<RSSyncTask> & task,bool isRenderServiceTask)120 void RSTransactionHandler::ExecuteSynchronousTask(const std::shared_ptr<RSSyncTask>& task, bool isRenderServiceTask)
121 {
122     if (!task) {
123         ROSEN_LOGE("RSTransactionHandler::ExecuteSynchronousTask failed, the task is not exist.");
124         return;
125     }
126 
127     if (renderServiceClient_ && isRenderServiceTask) {
128         renderServiceClient_->ExecuteSynchronousTask(task);
129         return;
130     }
131 
132     if (renderThreadClient_ && (!isRenderServiceTask)) {
133         renderThreadClient_->ExecuteSynchronousTask(task);
134         return;
135     }
136 
137     ROSEN_LOGE(
138         "RSTransactionHandler::ExecuteSynchronousTask failed, isRenderServiceTask is %{public}d.", isRenderServiceTask);
139 }
140 
SetCommitTransactionCallback(CommitTransactionCallback commitTransactionCallback)141 void RSTransactionHandler::SetCommitTransactionCallback(CommitTransactionCallback commitTransactionCallback)
142 {
143     RSTransactionHandler::commitTransactionCallback_ = commitTransactionCallback;
144 }
145 
FlushImplicitTransaction(uint64_t timestamp,const std::string & abilityName,bool dvsyncTimeUpdate,uint64_t dvsyncTime)146 void RSTransactionHandler::FlushImplicitTransaction(uint64_t timestamp, const std::string& abilityName,
147     bool dvsyncTimeUpdate, uint64_t dvsyncTime)
148 {
149     std::unique_lock<std::mutex> cmdLock(mutex_);
150     if (!implicitRemoteTransactionDataStack_.empty() && needSync_) {
151         RS_LOGE_LIMIT(__func__, __line__, "FlushImplicitTransaction failed, DataStack not empty");
152         return;
153     }
154     timestamp_ = std::max(timestamp, timestamp_);
155     thread_local pid_t tid = gettid();
156     if (renderThreadClient_ != nullptr && !implicitCommonTransactionData_->IsEmpty()) {
157         implicitCommonTransactionData_->timestamp_ = timestamp_;
158         implicitCommonTransactionData_->token_ = token_;
159         implicitCommonTransactionData_->tid_ = tid;
160         implicitCommonTransactionData_->abilityName_ = abilityName;
161         renderThreadClient_->CommitTransaction(implicitCommonTransactionData_);
162         implicitCommonTransactionData_ = std::make_unique<RSTransactionData>();
163     } else {
164         if (flushEmptyCallback_) {
165             flushEmptyCallback_(timestamp_);
166         }
167     }
168 
169     if (renderServiceClient_ == nullptr || implicitRemoteTransactionData_->IsEmpty()) {
170         return;
171     }
172 
173     auto transactionData = std::make_unique<RSTransactionData>();
174     std::swap(implicitRemoteTransactionData_, transactionData);
175     transactionData->timestamp_ = timestamp_;
176     transactionData->token_ = token_;
177     transactionData->tid_ = tid;
178     if (RSSystemProperties::GetHybridRenderEnabled() && RSTransactionHandler::commitTransactionCallback_ != nullptr) {
179         RS_TRACE_NAME_FMT("HybridRender transactionFlag:[%d,%" PRIu64 "]", GetRealPid(), transactionDataIndex_ + 1);
180         RSTransactionHandler::commitTransactionCallback_(renderServiceClient_,
181             std::move(transactionData), transactionDataIndex_, shared_from_this());
182         return;
183     }
184     renderServiceClient_->CommitTransaction(transactionData);
185     transactionDataIndex_ = transactionData->GetIndex();
186 }
187 
GetTransactionDataIndex() const188 uint32_t RSTransactionHandler::GetTransactionDataIndex() const
189 {
190     return transactionDataIndex_;
191 }
192 
PostTask(const std::function<void ()> & task)193 void RSTransactionHandler::PostTask(const std::function<void()>& task)
194 {
195     PostDelayTask(task, 0);
196 }
197 
PostDelayTask(const std::function<void ()> & task,uint32_t delay)198 void RSTransactionHandler::PostDelayTask(const std::function<void()>& task, uint32_t delay)
199 {
200     if (taskRunner_ == nullptr) {
201         return;
202     }
203     taskRunner_(task, delay);
204 }
205 
SetUITaskRunner(const TaskRunner & uiTaskRunner)206 void RSTransactionHandler::SetUITaskRunner(const TaskRunner& uiTaskRunner)
207 {
208     taskRunner_ = uiTaskRunner;
209 }
210 
IsEmpty() const211 bool RSTransactionHandler::IsEmpty() const
212 {
213     bool isEmpty = true;
214     std::unique_lock<std::mutex> cmdLock(mutex_);
215     if (implicitCommonTransactionData_) {
216         isEmpty &= implicitCommonTransactionData_->IsEmpty();
217     }
218     if (implicitRemoteTransactionData_) {
219         isEmpty &= implicitRemoteTransactionData_->IsEmpty();
220     }
221     isEmpty &= implicitCommonTransactionDataStack_.empty();
222     isEmpty &= implicitRemoteTransactionDataStack_.empty();
223     return isEmpty;
224 }
225 
FlushImplicitTransactionFromRT(uint64_t timestamp)226 void RSTransactionHandler::FlushImplicitTransactionFromRT(uint64_t timestamp)
227 {
228     std::unique_lock<std::mutex> cmdLock(mutexForRT_);
229     if (renderServiceClient_ != nullptr && !implicitTransactionDataFromRT_->IsEmpty()) {
230         implicitTransactionDataFromRT_->timestamp_ = timestamp;
231         thread_local pid_t tid = gettid();
232         implicitTransactionDataFromRT_->tid_= tid;
233         renderServiceClient_->CommitTransaction(implicitTransactionDataFromRT_);
234         implicitTransactionDataFromRT_ = std::make_unique<RSTransactionData>();
235     }
236 }
237 
StartSyncTransaction()238 void RSTransactionHandler::StartSyncTransaction()
239 {
240     needSync_ = true;
241 }
242 
CloseSyncTransaction()243 void RSTransactionHandler::CloseSyncTransaction()
244 {
245     needSync_ = false;
246 }
247 
StartCloseSyncTransactionFallbackTask(std::shared_ptr<AppExecFwk::EventHandler> handler,bool isOpen)248 void RSTransactionHandler::StartCloseSyncTransactionFallbackTask(
249     std::shared_ptr<AppExecFwk::EventHandler> handler, bool isOpen)
250 {
251     std::unique_lock<std::mutex> cmdLock(mutex_);
252     static uint32_t num = 0;
253     const std::string name = "CloseSyncTransactionFallbackTask";
254     const int timeOutDelay = 5000;
255     if (!handler) {
256         ROSEN_LOGD("StartCloseSyncTransactionFallbackTask handler is null");
257         return;
258     }
259     if (isOpen) {
260         num++;
261         auto taskName = name + std::to_string(num);
262         taskNames_.push(taskName);
263         auto task = [this]() {
264             RS_TRACE_NAME("CloseSyncTransaction timeout");
265             ROSEN_LOGE("CloseSyncTransaction timeout");
266             auto transactionProxy = RSTransactionProxy::GetInstance(); // planning
267             if (transactionProxy != nullptr) {
268                 transactionProxy->CommitSyncTransaction();
269                 transactionProxy->CloseSyncTransaction();
270             }
271             if (!taskNames_.empty()) {
272                 taskNames_.pop();
273             }
274         };
275         handler->PostTask(task, taskName, timeOutDelay);
276     } else {
277         if (!taskNames_.empty()) {
278             handler->RemoveTask(taskNames_.front());
279             taskNames_.pop();
280         }
281     }
282 }
283 
Begin()284 void RSTransactionHandler::Begin()
285 {
286     std::unique_lock<std::mutex> cmdLock(mutex_);
287     implicitCommonTransactionDataStack_.emplace(std::make_unique<RSTransactionData>());
288     implicitRemoteTransactionDataStack_.emplace(std::make_unique<RSTransactionData>());
289     if (needSync_) {
290         implicitCommonTransactionDataStack_.top()->MarkNeedSync();
291         implicitRemoteTransactionDataStack_.top()->MarkNeedSync();
292     }
293 }
294 
Commit(uint64_t timestamp)295 void RSTransactionHandler::Commit(uint64_t timestamp)
296 {
297     std::unique_lock<std::mutex> cmdLock(mutex_);
298     if (!implicitCommonTransactionDataStack_.empty()) {
299         implicitCommonTransactionDataStack_.pop();
300     }
301 
302     if (!implicitRemoteTransactionDataStack_.empty()) {
303         if (renderServiceClient_ != nullptr && !implicitRemoteTransactionDataStack_.top()->IsEmpty()) {
304             implicitRemoteTransactionDataStack_.top()->timestamp_ = timestamp;
305             thread_local pid_t tid = gettid();
306             implicitRemoteTransactionDataStack_.top()->tid_= tid;
307             renderServiceClient_->CommitTransaction(implicitRemoteTransactionDataStack_.top());
308         }
309         implicitRemoteTransactionDataStack_.pop();
310     }
311 }
312 
CommitSyncTransaction(uint64_t timestamp,const std::string & abilityName)313 void RSTransactionHandler::CommitSyncTransaction(uint64_t timestamp, const std::string& abilityName)
314 {
315     std::unique_lock<std::mutex> cmdLock(mutex_);
316     timestamp_ = std::max(timestamp, timestamp_);
317     thread_local pid_t tid = gettid();
318     if (!implicitCommonTransactionDataStack_.empty()) {
319         if (renderThreadClient_ != nullptr && (!implicitCommonTransactionDataStack_.top()->IsEmpty() ||
320                                                   implicitCommonTransactionDataStack_.top()->IsNeedSync())) {
321             implicitCommonTransactionDataStack_.top()->timestamp_ = timestamp;
322             implicitCommonTransactionDataStack_.top()->tid_ = tid;
323             implicitCommonTransactionDataStack_.top()->abilityName_ = abilityName;
324             implicitCommonTransactionDataStack_.top()->SetSyncId(syncId_);
325             renderThreadClient_->CommitTransaction(implicitCommonTransactionDataStack_.top());
326         }
327         implicitCommonTransactionDataStack_.pop();
328     }
329 
330     if (!implicitRemoteTransactionDataStack_.empty()) {
331         if (renderServiceClient_ != nullptr && (!implicitRemoteTransactionDataStack_.top()->IsEmpty() ||
332                                                    implicitRemoteTransactionDataStack_.top()->IsNeedSync())) {
333             implicitRemoteTransactionDataStack_.top()->timestamp_ = timestamp;
334             implicitRemoteTransactionDataStack_.top()->tid_ = tid;
335             implicitRemoteTransactionDataStack_.top()->SetSyncId(syncId_);
336             renderServiceClient_->CommitTransaction(implicitRemoteTransactionDataStack_.top());
337         }
338         implicitRemoteTransactionDataStack_.pop();
339     }
340 }
341 
MarkTransactionNeedSync()342 void RSTransactionHandler::MarkTransactionNeedSync()
343 {
344     std::unique_lock<std::mutex> cmdLock(mutex_);
345     if (!implicitCommonTransactionDataStack_.empty()) {
346         implicitCommonTransactionDataStack_.top()->MarkNeedSync();
347     }
348 
349     if (!implicitRemoteTransactionDataStack_.empty()) {
350         implicitRemoteTransactionDataStack_.top()->MarkNeedSync();
351     }
352 }
353 
MarkTransactionNeedCloseSync(const int32_t transactionCount)354 void RSTransactionHandler::MarkTransactionNeedCloseSync(const int32_t transactionCount)
355 {
356     std::unique_lock<std::mutex> cmdLock(mutex_);
357     if (!implicitCommonTransactionDataStack_.empty()) {
358         implicitCommonTransactionDataStack_.top()->MarkNeedSync();
359         implicitCommonTransactionDataStack_.top()->MarkNeedCloseSync();
360         implicitCommonTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
361     }
362 
363     if (!implicitRemoteTransactionDataStack_.empty()) {
364         implicitRemoteTransactionDataStack_.top()->MarkNeedSync();
365         implicitRemoteTransactionDataStack_.top()->MarkNeedCloseSync();
366         implicitRemoteTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
367     }
368 }
369 
SetSyncTransactionNum(const int32_t transactionCount)370 void RSTransactionHandler::SetSyncTransactionNum(const int32_t transactionCount)
371 {
372     std::unique_lock<std::mutex> cmdLock(mutex_);
373     if (!implicitCommonTransactionDataStack_.empty()) {
374         implicitCommonTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
375     }
376 
377     if (!implicitRemoteTransactionDataStack_.empty()) {
378         implicitRemoteTransactionDataStack_.top()->SetSyncTransactionNum(transactionCount);
379     }
380 }
381 
SetParentPid(const int32_t parentPid)382 void RSTransactionHandler::SetParentPid(const int32_t parentPid)
383 {
384     std::unique_lock<std::mutex> cmdLock(mutex_);
385     if (!implicitCommonTransactionDataStack_.empty()) {
386         implicitCommonTransactionDataStack_.top()->SetParentPid(parentPid);
387     }
388 
389     if (!implicitRemoteTransactionDataStack_.empty()) {
390         implicitRemoteTransactionDataStack_.top()->SetParentPid(parentPid);
391     }
392 }
393 
AddCommonCommand(std::unique_ptr<RSCommand> & command)394 void RSTransactionHandler::AddCommonCommand(std::unique_ptr<RSCommand>& command)
395 {
396     if (!implicitCommonTransactionDataStack_.empty()) {
397         implicitCommonTransactionDataStack_.top()->AddCommand(command, 0, FollowType::NONE);
398         return;
399     }
400     implicitCommonTransactionData_->AddCommand(command, 0, FollowType::NONE);
401 }
402 
MoveCommonCommandByNodeId(std::shared_ptr<RSTransactionHandler> transactionHandler,NodeId nodeId)403 void RSTransactionHandler::MoveCommonCommandByNodeId(
404     std::shared_ptr<RSTransactionHandler> transactionHandler, NodeId nodeId)
405 {
406     if (!implicitCommonTransactionDataStack_.empty() &&
407         !transactionHandler->implicitCommonTransactionDataStack_.empty()) {
408         implicitCommonTransactionDataStack_.top()->MoveCommandByNodeId(
409             transactionHandler->implicitCommonTransactionDataStack_.top(), nodeId);
410     }
411     implicitCommonTransactionData_->MoveCommandByNodeId(transactionHandler->implicitCommonTransactionData_, nodeId);
412 }
413 
AddRemoteCommand(std::unique_ptr<RSCommand> & command,NodeId nodeId,FollowType followType)414 void RSTransactionHandler::AddRemoteCommand(std::unique_ptr<RSCommand>& command, NodeId nodeId, FollowType followType)
415 {
416     if (!implicitRemoteTransactionDataStack_.empty()) {
417         implicitRemoteTransactionDataStack_.top()->AddCommand(command, nodeId, followType);
418         return;
419     }
420     implicitRemoteTransactionData_->AddCommand(command, nodeId, followType);
421 }
422 
MoveRemoteCommandByNodeId(std::shared_ptr<RSTransactionHandler> transactionHandler,NodeId nodeId)423 void RSTransactionHandler::MoveRemoteCommandByNodeId(
424     std::shared_ptr<RSTransactionHandler> transactionHandler, NodeId nodeId)
425 {
426     if (!implicitRemoteTransactionDataStack_.empty() &&
427         !transactionHandler->implicitRemoteTransactionDataStack_.empty()) {
428         implicitRemoteTransactionDataStack_.top()->MoveCommandByNodeId(
429             transactionHandler->implicitRemoteTransactionDataStack_.top(), nodeId);
430     }
431     implicitRemoteTransactionData_->MoveCommandByNodeId(transactionHandler->implicitRemoteTransactionData_, nodeId);
432 }
433 } // namespace Rosen
434 } // namespace OHOS
435