• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "pipeline/rs_render_thread.h"
17 
18 #include <cstdint>
19 
20 #include "rs_trace.h"
21 #include "sandbox_utils.h"
22 
23 #include "animation/rs_animation_fraction.h"
24 #include "command/rs_surface_node_command.h"
25 #include "common/rs_background_thread.h"
26 #include "delegate/rs_functional_delegate.h"
27 #include "pipeline/rs_draw_cmd_list.h"
28 #include "pipeline/rs_node_map.h"
29 #include "pipeline/rs_render_node_map.h"
30 #include "pipeline/rs_render_node_gc.h"
31 #include "pipeline/rs_root_render_node.h"
32 #include "pipeline/rs_surface_buffer_callback_manager.h"
33 #include "pipeline/rs_surface_render_node.h"
34 #include "platform/common/rs_log.h"
35 #include "platform/common/rs_system_properties.h"
36 #include "property/rs_property_trace.h"
37 #include "render/rs_image_cache.h"
38 #include "render/rs_typeface_cache.h"
39 #include "render_context/shader_cache.h"
40 #include "rs_frame_report.h"
41 #include "transaction/rs_render_service_client.h"
42 #include "ui/rs_surface_extractor.h"
43 #include "ui/rs_surface_node.h"
44 #include "ui/rs_ui_director.h"
45 #ifdef RS_ENABLE_VK
46 #include "platform/ohos/backend/rs_vulkan_context.h"
47 #endif
48 #ifdef OHOS_RSS_CLIENT
49 #include "res_sched_client.h"
50 #include "res_type.h"
51 #endif
52 
53 #ifdef RES_CLINET_SCHED_ENABLE
54 #include "qos.h"
55 #endif
56 
57 #ifdef ROSEN_PREVIEW
58 #include "glfw_render_context.h"
59 #endif
60 
61 #ifdef ROSEN_OHOS
62 #include <unistd.h>
63 #include "frame_collector.h"
64 #include "render_frame_trace.h"
65 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
66 #ifdef ACCESSIBILITY_ENABLE
67 #include "accessibility_config.h"
68 #include "platform/common/rs_accessibility.h"
69 #endif
70 
71 static const std::string RT_INTERVAL_NAME = "renderthread";
72 #endif
73 #if !defined(ROSEN_PREVIEW) && !defined(ROSEN_IOS)
74 #include <sys/prctl.h>
75 #endif
SystemCallSetThreadName(const std::string & name)76 static void SystemCallSetThreadName(const std::string& name)
77 {
78 #if !defined(ROSEN_PREVIEW) && !defined(ROSEN_IOS)
79 
80     if (prctl(PR_SET_NAME, name.c_str()) < 0) {
81         return;
82     }
83 #endif
84 }
85 
86 namespace OHOS {
87 namespace Rosen {
88 namespace {
89     static constexpr uint64_t REFRESH_PERIOD = 16666667;
90 }
91 
SendFrameEvent(bool start)92 void SendFrameEvent(bool start)
93 {
94 #ifdef ROSEN_OHOS
95     FrameCollector::GetInstance().MarkFrameEvent(start ? FrameEventType::WaitVsyncStart : FrameEventType::WaitVsyncEnd);
96 #endif
97 }
98 
Instance()99 RSRenderThread& RSRenderThread::Instance()
100 {
101     static RSRenderThread renderThread;
102     RSAnimationFraction::Init();
103     return renderThread;
104 }
105 
RSRenderThread()106 RSRenderThread::RSRenderThread()
107 {
108     static std::function<std::shared_ptr<Drawing::Typeface> (uint64_t)> customTypefaceQueryfunc =
109     [] (uint64_t globalUniqueId) -> std::shared_ptr<Drawing::Typeface> {
110         return RSTypefaceCache::Instance().GetDrawingTypefaceCache(globalUniqueId);
111     };
112     Drawing::DrawOpItem::SetTypefaceQueryCallBack(customTypefaceQueryfunc);
113     mainFunc_ = [&]() {
114         uint64_t renderStartTimeStamp = jankDetector_->GetSysTimeNs();
115         RS_TRACE_BEGIN("RSRenderThread DrawFrame: " + std::to_string(timestamp_));
116 #ifdef ROSEN_OHOS
117         FRAME_TRACE::RenderFrameTrace::GetInstance().RenderStartFrameTrace(RT_INTERVAL_NAME);
118 #endif
119         prevTimestamp_ = timestamp_;
120         ProcessCommands();
121 #ifdef RS_ENABLE_GPU
122         ROSEN_LOGD("RSRenderThread DrawFrame(%{public}" PRIu64 ") in %{public}s",
123             prevTimestamp_, renderContext_ ? "GPU" : "CPU");
124 #endif
125         Animate(prevTimestamp_);
126         Render();
127         SendCommands();
128         {
129             std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
130             context_->activeNodesInRoot_.clear();
131         }
132         RSRenderNodeGC::Instance().ReleaseNodeMemory();
133         ReleasePixelMapInBackgroundThread();
134         context_->pendingSyncNodes_.clear();
135 #ifdef ROSEN_OHOS
136         FRAME_TRACE::RenderFrameTrace::GetInstance().RenderEndFrameTrace(RT_INTERVAL_NAME);
137 #endif
138         jankDetector_->CalculateSkippedFrame(renderStartTimeStamp, jankDetector_->GetSysTimeNs());
139         RSTypefaceCache::Instance().HandleDelayDestroyQueue();
140         RS_TRACE_END();
141     };
142     context_ = std::make_shared<RSContext>();
143     context_->Initialize();
144     jankDetector_ = std::make_shared<RSJankDetector>();
145 #ifdef ACCESSIBILITY_ENABLE
146     RSAccessibility::GetInstance().ListenHighContrastChange([](bool newHighContrast) {
147         std::thread thread(
148             [](bool newHighContrast) {
149                 auto& renderThread = RSRenderThread::Instance();
150                 renderThread.SetHighContrast(newHighContrast);
151             },
152             newHighContrast);
153         thread.detach();
154     });
155 #endif
156 #ifdef ROSEN_OHOS
157     Drawing::DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback({
158         .OnFinish = RSSurfaceBufferCallbackManager::Instance().GetOnFinishCb(),
159         .OnAfterAcquireBuffer = RSSurfaceBufferCallbackManager::Instance().GetOnAfterAcquireBufferCb(),
160     });
161     Drawing::DrawSurfaceBufferOpItem::SetIsUniRender(false);
162     Drawing::DrawSurfaceBufferOpItem::RegisterGetRootNodeIdFuncForRT(
163         [this]() {
164             if (visitor_) {
165                 return visitor_->GetActiveSubtreeRootId();
166             }
167             return INVALID_NODEID;
168         }
169     );
170 #endif
171     RSSurfaceBufferCallbackManager::Instance().SetIsUniRender(false);
172     RSSurfaceBufferCallbackManager::Instance().SetVSyncFuncs({
173         .requestNextVsync = []() {
174             RSRenderThread::Instance().RequestNextVSync();
175         },
176         .isRequestedNextVSync = [this]() {
177 #ifdef __OHOS__
178             if (receiver_ != nullptr) {
179                 return receiver_->IsRequestedNextVSync();
180             }
181 #endif
182             return false;
183         },
184     });
185 }
186 
~RSRenderThread()187 RSRenderThread::~RSRenderThread()
188 {
189     Stop();
190 #ifdef RS_ENABLE_GPU
191     if (renderContext_ != nullptr) {
192         ROSEN_LOGD("Destroy renderContext!!");
193         delete renderContext_;
194         renderContext_ = nullptr;
195     }
196 #endif
197 }
198 
Start()199 void RSRenderThread::Start()
200 {
201     ROSEN_LOGD("RSRenderThread start.");
202     running_.store(true);
203     std::unique_lock<std::mutex> cmdLock(rtMutex_);
204     if (thread_ == nullptr) {
205         thread_ = std::make_unique<std::thread>([this] { this->RSRenderThread::RenderLoop(); });
206     }
207 }
208 
ReleasePixelMapInBackgroundThread()209 void RSRenderThread::ReleasePixelMapInBackgroundThread()
210 {
211     if (!RSImageCache::Instance().CheckUniqueIdIsEmpty()) {
212         static std::function<void()> task = []() -> void { RSImageCache::Instance().ReleaseUniqueIdList(); };
213         RSBackgroundThread::Instance().PostTask(task);
214     }
215 }
216 
Stop()217 void RSRenderThread::Stop()
218 {
219     running_.store(false);
220 
221     if (handler_) {
222         handler_->RemoveAllEvents();
223         handler_ = nullptr;
224     }
225     receiver_ = nullptr;
226     if (runner_) {
227         runner_->Stop();
228     }
229 
230     if (thread_ != nullptr && thread_->joinable()) {
231         thread_->join();
232     }
233 
234     thread_ = nullptr;
235     ROSEN_LOGD("RSRenderThread stopped.");
236 }
237 
RecvTransactionData(std::unique_ptr<RSTransactionData> & transactionData)238 void RSRenderThread::RecvTransactionData(std::unique_ptr<RSTransactionData>& transactionData)
239 {
240     {
241         std::unique_lock<std::mutex> cmdLock(cmdMutex_);
242         std::string str = "RecvCommands ptr:" + std::to_string(reinterpret_cast<uintptr_t>(transactionData.get()));
243         commandTimestamp_ = transactionData->GetTimestamp();
244         ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, str.c_str());
245         cmds_.emplace_back(std::move(transactionData));
246         ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
247     }
248     // [PLANNING]: process in next vsync (temporarily)
249     RSRenderThread::Instance().RequestNextVSync();
250 }
251 
RequestNextVSync()252 void RSRenderThread::RequestNextVSync()
253 {
254     if (handler_) {
255         RS_TRACE_FUNC();
256         SendFrameEvent(true);
257         VSyncReceiver::FrameCallback fcb = {
258             .userData_ = this,
259             .callbackWithId_ = [this](uint64_t timestamp, int64_t frameCount,
260                                    void* arg) { this->OnVsync(timestamp, frameCount); },
261         };
262         if (receiver_ != nullptr) {
263             receiver_->RequestNextVSync(fcb);
264         } else {
265             hasSkipVsync_ = true;
266         }
267     } else {
268         hasSkipVsync_ = true;
269     }
270 }
271 
GetTid()272 int32_t RSRenderThread::GetTid()
273 {
274     return tid_;
275 }
276 
CreateAndInitRenderContextIfNeed()277 void RSRenderThread::CreateAndInitRenderContextIfNeed()
278 {
279 #if (defined(RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && !defined(ROSEN_PREVIEW)
280     if (renderContext_ == nullptr) {
281         renderContext_ = new RenderContext();
282         ROSEN_LOGD("Create RenderContext");
283 #ifdef ROSEN_OHOS
284 #ifdef RS_ENABLE_GL
285         if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
286             RS_TRACE_NAME("InitializeEglContext");
287             renderContext_->InitializeEglContext(); // init egl context on RT
288             if (!cacheDir_.empty()) {
289                 renderContext_->SetCacheDir(cacheDir_);
290             }
291         }
292 #endif
293 #ifdef RS_ENABLE_VK
294     if (!cacheDir_.empty()) {
295         renderContex_->SetCacheDir(cacheDir_);
296     }
297     if (RSSystemProperties::IsUseVulkan()) {
298         renderContext_->SetUpGpuContext(nullptr);
299     }
300 #endif
301 #endif
302     }
303 #endif
304 }
305 
RenderLoop()306 void RSRenderThread::RenderLoop()
307 {
308     SystemCallSetThreadName("RSRenderThread");
309 
310 #ifdef OHOS_RSS_CLIENT
311     std::unordered_map<std::string, std::string> payload;
312     payload["uid"] = std::to_string(getuid());
313     payload["pid"] = std::to_string(GetRealPid());
314     ResourceSchedule::ResSchedClient::GetInstance().ReportData(
315         ResourceSchedule::ResType::RES_TYPE_REPORT_RENDER_THREAD, getproctid(), payload);
316 #endif
317 #ifdef ROSEN_OHOS
318     tid_ = gettid();
319 #endif
320     CreateAndInitRenderContextIfNeed();
321     std::string name = "RSRenderThread_" + std::to_string(GetRealPid());
322     runner_ = AppExecFwk::EventRunner::Create(false);
323     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
324     auto rsClient = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
325     receiver_ = rsClient->CreateVSyncReceiver(name, handler_);
326     if (receiver_ == nullptr) {
327         ROSEN_LOGE("RSRenderThread CreateVSyncReceiver Error");
328         return;
329     }
330     receiver_->Init();
331     if (hasSkipVsync_) {
332         hasSkipVsync_ = false;
333         RSRenderThread::Instance().RequestNextVSync();
334     }
335 #ifdef ROSEN_PREVIEW
336     static auto onSizeChange = [&](int width, int height) {
337         if (isRunning_) {
338             RSRenderThread::Instance().RequestNextVSync();
339         }
340     };
341     GlfwRenderContext::GetGlobal()->OnSizeChanged(onSizeChange);
342 #endif
343 
344 #ifdef ROSEN_OHOS
345     FrameCollector::GetInstance().SetRepaintCallback([this]() { this->RequestNextVSync(); });
346     auto delegate = RSFunctionalDelegate::Create();
347     delegate->SetRepaintCallback([this]() {
348         bool isOverDrawEnabled = RSOverdrawController::GetInstance().IsEnabled();
349         PostTask([this, isOverDrawEnabled]() {
350             isOverDrawEnabledOfCurFrame_ = isOverDrawEnabled;
351             RequestNextVSync();
352         });
353     });
354     RSOverdrawController::GetInstance().SetDelegate(delegate);
355 #endif
356 
357 #ifdef RES_CLINET_SCHED_ENABLE
358     auto ret = OHOS::QOS::SetThreadQos(OHOS::QOS::QosLevel::QOS_USER_INTERACTIVE);
359     RS_LOGI("RSRenderThread: SetThreadQos retcode = %{public}d", ret);
360 #endif
361 
362     if (runner_) {
363         runner_->Run();
364     }
365 }
366 
OnVsync(uint64_t timestamp,int64_t frameCount)367 void RSRenderThread::OnVsync(uint64_t timestamp, int64_t frameCount)
368 {
369     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSRenderThread::OnVsync");
370 #ifdef ROSEN_PREVIEW
371     isRunning_ = true;
372 #endif
373     SendFrameEvent(false);
374     mValue = (mValue + 1) % 2; // 1 and 2 is Calculated parameters
375     RS_TRACE_INT("Vsync-client", mValue);
376     timestamp_ = timestamp;
377     if (activeWindowCnt_.load() > 0) {
378         mainFunc_(); // start render-loop now
379     }
380 #ifdef ROSEN_PREVIEW
381     isRunning_ = false;
382 #endif
383     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
384 }
385 
UpdateWindowStatus(bool active)386 void RSRenderThread::UpdateWindowStatus(bool active)
387 {
388     if (active) {
389         activeWindowCnt_++;
390     } else {
391         activeWindowCnt_--;
392     }
393     ROSEN_LOGD("RSRenderThread UpdateWindowStatus %{public}d, cur activeWindowCnt_ %{public}d",
394         active, activeWindowCnt_.load());
395 }
396 
ProcessCommands()397 void RSRenderThread::ProcessCommands()
398 {
399     // Attention: there are two situations
400     // 1. when commandTimestamp_ != 0, it means that UIDirector has called
401     // "RSRenderThread::Instance().RequestNextVSync()", which equals there are some commands form UIThread need to be
402     // executed. To make commands from UIThread sync with buffer flushed by RenderThread, we choose commandTimestamp_ as
403     // uiTimestamp_ which would be used in RenderThreadVisitor when we call flushFrame.
404     // 2. when cmds_.empty() is true or commandTimestamp_ = 0,
405     // it means that some thread except UIThread like RSRenderThread::Animate
406     // has called "RSRenderThread::Instance().RequestNextVSync()", which equals that some commands form RenderThread
407     // need to be executed. To make commands from RenderThread sync with buffer flushed by RenderThread, we choose
408     // (prevTimestamp_ - 1) as uiTimestamp_ which would be used in RenderThreadVisitor when we call flushFrame.
409 
410     // The reason why prevTimestamp_ need to be minus 1 is that timestamp used in UIThread is always less than (for now)
411     // timestamp used in RenderThread. If we do not do this, when RenderThread::Animate execute flushFrame and use
412     // prevTimestamp_ as buffer timestamp which equals T0, UIDirector send messages in the same vsync period, and the
413     // commandTimestamp_ would also be T0, RenderService would execute commands from UIDirector and composite buffer
414     // which rendering is executed by RSRenderThread::Animate for they have the same timestamp. To avoid this situation,
415     // we should always use "prevTimestamp_ - 1".
416 
417     std::unique_lock<std::mutex> cmdLock(cmdMutex_);
418     if (cmds_.empty()) {
419         uiTimestamp_ = prevTimestamp_ - 1;
420         return;
421     }
422     if (RsFrameReport::GetInstance().GetEnable()) {
423         RsFrameReport::GetInstance().ProcessCommandsStart();
424     }
425 
426     if (commandTimestamp_ != 0) {
427         uiTimestamp_ = commandTimestamp_;
428         commandTimestamp_ = 0;
429     } else {
430         uiTimestamp_ = prevTimestamp_ - 1;
431     }
432 
433     ROSEN_LOGD("RSRenderThread ProcessCommands size: %{public}lu\n", (unsigned long)cmds_.size());
434     std::vector<std::unique_ptr<RSTransactionData>> cmds;
435 #ifdef CROSS_PLATFORM
436     PrepareCommandForCrossPlatform(cmds);
437 #else
438     std::swap(cmds, cmds_);
439 #endif
440     cmdLock.unlock();
441 
442     // To improve overall responsiveness, we make animations start on LAST frame instead of THIS frame.
443     // If last frame is too far away (earlier than 2 vsync from now), we use currentTimestamp_ - REFRESH_PERIOD as
444     // 'virtual' last frame timestamp.
445     if (timestamp_ - lastAnimateTimestamp_ > 2 * REFRESH_PERIOD) { // 2: if last frame is earlier than 2 vsync from now
446         context_->currentTimestamp_ = timestamp_ - REFRESH_PERIOD;
447     } else {
448         context_->currentTimestamp_ = lastAnimateTimestamp_;
449     }
450     uint64_t uiEndTimeStamp = jankDetector_->GetSysTimeNs();
451     for (auto& cmdData : cmds) {
452         std::string str = "ProcessCommands ptr:" + std::to_string(reinterpret_cast<uintptr_t>(cmdData.get()));
453         ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, str.c_str());
454         // only set transactionTimestamp_ in UniRender mode
455         context_->transactionTimestamp_ = RSSystemProperties::GetUniRenderEnabled() ? cmdData->GetTimestamp() : 0;
456         cmdData->Process(*context_);
457         jankDetector_->UpdateUiDrawFrameMsg(cmdData->GetTimestamp(), uiEndTimeStamp, cmdData->GetAbilityName());
458         ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
459     }
460 }
461 
462 #ifdef CROSS_PLATFORM
PrepareCommandForCrossPlatform(std::vector<std::unique_ptr<RSTransactionData>> & cmds)463 void RSRenderThread::PrepareCommandForCrossPlatform(std::vector<std::unique_ptr<RSTransactionData>>& cmds)
464 {
465     if (cmds_.empty()) {
466         return;
467     }
468     int index = 0;
469     uint64_t firstCmdTimestamp = cmds_[0]->GetTimestamp();
470     uint64_t lastCmdTimestamp = cmds_.back()->GetTimestamp();
471     while (index < cmds_.size()) {
472         if (cmds_[index]->GetTimestamp() <
473             std::max({timestamp_, firstCmdTimestamp + 1, lastCmdTimestamp})) {
474             index++;
475         } else {
476             break;
477         }
478     }
479     for (int i = 0; i < index; i++) {
480         cmds.emplace_back(std::move(cmds_[i]));
481     }
482 
483     cmds_.erase(cmds_.begin(), cmds_.begin() + index);
484     if (!cmds_.empty()) {
485         RequestNextVSync();
486     }
487 }
488 #endif
489 
Animate(uint64_t timestamp)490 void RSRenderThread::Animate(uint64_t timestamp)
491 {
492     RS_TRACE_FUNC();
493 
494     if (RsFrameReport::GetInstance().GetEnable()) {
495         RsFrameReport::GetInstance().AnimateStart();
496     }
497 
498     lastAnimateTimestamp_ = timestamp;
499 
500     if (context_->animatingNodeList_.empty()) {
501         return;
502     }
503 
504     bool needRequestNextVsync = false;
505     // isCalculateAnimationValue is embedded modify for stat animate frame drop
506     bool isCalculateAnimationValue = false;
507     // iterate and animate all animating nodes, remove if animation finished
508     EraseIf(context_->animatingNodeList_,
509         [timestamp, &needRequestNextVsync, &isCalculateAnimationValue](const auto& iter) -> bool {
510         auto node = iter.second.lock();
511         if (node == nullptr) {
512             ROSEN_LOGD("RSRenderThread::Animate removing expired animating node");
513             return true;
514         }
515         auto [hasRunningAnimation, nodeNeedRequestNextVsync, nodeCalculateAnimationValue] = node->Animate(timestamp);
516         if (!hasRunningAnimation) {
517             ROSEN_LOGD("RSRenderThread::Animate removing finished animating node %{public}" PRIu64, node->GetId());
518         }
519         needRequestNextVsync = needRequestNextVsync || nodeNeedRequestNextVsync;
520         isCalculateAnimationValue = isCalculateAnimationValue || nodeCalculateAnimationValue;
521         return !hasRunningAnimation;
522     });
523     if (!isCalculateAnimationValue && needRequestNextVsync) {
524         RS_TRACE_NAME("Animation running empty");
525     }
526 
527     if (needRequestNextVsync) {
528         RSRenderThread::Instance().RequestNextVSync();
529     }
530 }
531 
Render()532 void RSRenderThread::Render()
533 {
534     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
535         RSPropertyTrace::GetInstance().RefreshNodeTraceInfo();
536     }
537     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSRenderThread::Render");
538     if (RsFrameReport::GetInstance().GetEnable()) {
539         RsFrameReport::GetInstance().RenderStart(timestamp_);
540     }
541     std::unique_lock<std::mutex> lock(mutex_);
542     const auto& rootNode = context_->GetGlobalRootRenderNode();
543 
544     if (rootNode == nullptr) {
545         ROSEN_LOGE("RSRenderThread::Render, rootNode is nullptr");
546         return;
547     }
548     if (visitor_ == nullptr) {
549         visitor_ = std::make_shared<RSRenderThreadVisitor>();
550     }
551     // get latest partial render status from system properties and set it to RTvisitor_
552     visitor_->SetPartialRenderStatus(RSSystemProperties::GetPartialRenderEnabled(),
553         isRTRenderForced_ || (isOverDrawEnabledOfLastFrame_ != isOverDrawEnabledOfCurFrame_) ||
554         IsHighContrastChanged());
555     ResetHighContrastChanged();
556     rootNode->Prepare(visitor_);
557     rootNode->Process(visitor_);
558     RSSurfaceBufferCallbackManager::Instance().RunSurfaceBufferCallback();
559     isOverDrawEnabledOfLastFrame_ = isOverDrawEnabledOfCurFrame_;
560     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
561 }
562 
SendCommands()563 void RSRenderThread::SendCommands()
564 {
565     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSRenderThread::SendCommands");
566     if (RsFrameReport::GetInstance().GetEnable()) {
567         RsFrameReport::GetInstance().SendCommandsStart();
568     }
569 
570     RSUIDirector::RecvMessages();
571     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
572 }
573 
Detach(NodeId id)574 void RSRenderThread::Detach(NodeId id)
575 {
576     if (auto node = context_->GetNodeMap().GetRenderNode<RSRootRenderNode>(id)) {
577         std::unique_lock<std::mutex> lock(mutex_);
578         context_->GetGlobalRootRenderNode()->RemoveChild(node);
579     }
580 }
581 
PostTask(RSTaskMessage::RSTask task)582 void RSRenderThread::PostTask(RSTaskMessage::RSTask task)
583 {
584     if (handler_) {
585         handler_->PostTask(task);
586     }
587 }
588 
PostSyncTask(RSTaskMessage::RSTask task)589 void RSRenderThread::PostSyncTask(RSTaskMessage::RSTask task)
590 {
591     if (handler_) {
592         handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
593     }
594 }
595 
PostPreTask()596 void RSRenderThread::PostPreTask()
597 {
598     if (handler_ && preTask_) {
599         handler_->PostTask(preTask_);
600     }
601 }
602 } // namespace Rosen
603 } // namespace OHOS
604