• 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 std::atomic_bool RSRenderThread::running_ = false;
89 namespace {
90     static constexpr uint64_t REFRESH_PERIOD = 16666667;
91 }
92 
SendFrameEvent(bool start)93 void SendFrameEvent(bool start)
94 {
95 #ifdef ROSEN_OHOS
96     FrameCollector::GetInstance().MarkFrameEvent(start ? FrameEventType::WaitVsyncStart : FrameEventType::WaitVsyncEnd);
97 #endif
98 }
99 
Instance()100 RSRenderThread& RSRenderThread::Instance()
101 {
102     static RSRenderThread renderThread;
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     RSAnimationFraction::Init();
145     jankDetector_ = std::make_shared<RSJankDetector>();
146 #ifdef ACCESSIBILITY_ENABLE
147     RSAccessibility::GetInstance().ListenHighContrastChange([](bool newHighContrast) {
148         std::thread thread(
149             [](bool newHighContrast) {
150                 auto& renderThread = RSRenderThread::Instance();
151                 renderThread.SetHighContrast(newHighContrast);
152             },
153             newHighContrast);
154         thread.detach();
155     });
156 #endif
157 #ifdef ROSEN_OHOS
158     Drawing::DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback({
159         .OnFinish = RSSurfaceBufferCallbackManager::Instance().GetOnFinishCb(),
160         .OnAfterAcquireBuffer = RSSurfaceBufferCallbackManager::Instance().GetOnAfterAcquireBufferCb(),
161     });
162     Drawing::DrawSurfaceBufferOpItem::SetIsUniRender(false);
163     Drawing::DrawSurfaceBufferOpItem::RegisterGetRootNodeIdFuncForRT(
164         [this]() {
165             if (visitor_) {
166                 return visitor_->GetActiveSubtreeRootId();
167             }
168             return INVALID_NODEID;
169         }
170     );
171 #endif
172     RSSurfaceBufferCallbackManager::Instance().SetIsUniRender(false);
173     RSSurfaceBufferCallbackManager::Instance().SetVSyncFuncs({
174         .requestNextVsync = []() {
175             RSRenderThread::Instance().RequestNextVSync();
176         },
177         .isRequestedNextVSync = [this]() {
178 #ifdef __OHOS__
179             if (receiver_ != nullptr) {
180                 return receiver_->IsRequestedNextVSync();
181             }
182 #endif
183             return false;
184         },
185     });
186 }
187 
~RSRenderThread()188 RSRenderThread::~RSRenderThread()
189 {
190     Stop();
191 #ifdef RS_ENABLE_GPU
192     if (renderContext_ != nullptr) {
193         ROSEN_LOGD("Destroy renderContext!!");
194         delete renderContext_;
195         renderContext_ = nullptr;
196     }
197 #endif
198 }
199 
Start()200 void RSRenderThread::Start()
201 {
202     ROSEN_LOGD("RSRenderThread start.");
203     RSRenderThread::running_.store(true);
204     std::unique_lock<std::mutex> cmdLock(rtMutex_);
205     if (thread_ == nullptr) {
206         thread_ = std::make_unique<std::thread>([this] { this->RSRenderThread::RenderLoop(); });
207     }
208 }
209 
ReleasePixelMapInBackgroundThread()210 void RSRenderThread::ReleasePixelMapInBackgroundThread()
211 {
212     if (!RSImageCache::Instance().CheckUniqueIdIsEmpty()) {
213         static std::function<void()> task = []() -> void { RSImageCache::Instance().ReleaseUniqueIdList(); };
214         RSBackgroundThread::Instance().PostTask(task);
215     }
216 }
217 
GetIsRunning()218 bool RSRenderThread::GetIsRunning()
219 {
220     return running_.load();
221 }
222 
Stop()223 void RSRenderThread::Stop()
224 {
225     RSRenderThread::running_.store(false);
226 
227     if (handler_) {
228         handler_->RemoveAllEvents();
229         handler_ = nullptr;
230     }
231     receiver_ = nullptr;
232     if (runner_) {
233         runner_->Stop();
234     }
235 
236     if (thread_ != nullptr && thread_->joinable()) {
237         thread_->join();
238     }
239 
240     thread_ = nullptr;
241     ROSEN_LOGD("RSRenderThread stopped.");
242 }
243 
RecvTransactionData(std::unique_ptr<RSTransactionData> & transactionData)244 void RSRenderThread::RecvTransactionData(std::unique_ptr<RSTransactionData>& transactionData)
245 {
246     {
247         std::unique_lock<std::mutex> cmdLock(cmdMutex_);
248         std::string str = "RecvCommands ptr:" + std::to_string(reinterpret_cast<uintptr_t>(transactionData.get()));
249         commandTimestamp_ = transactionData->GetTimestamp();
250         ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, str.c_str());
251         cmds_.emplace_back(std::move(transactionData));
252         ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
253     }
254     // [PLANNING]: process in next vsync (temporarily)
255     RSRenderThread::Instance().RequestNextVSync();
256 }
257 
RequestNextVSync()258 void RSRenderThread::RequestNextVSync()
259 {
260     if (handler_) {
261         RS_TRACE_FUNC();
262         SendFrameEvent(true);
263         VSyncReceiver::FrameCallback fcb = {
264             .userData_ = this,
265             .callbackWithId_ = [this](uint64_t timestamp, int64_t frameCount,
266                                    void* arg) { this->OnVsync(timestamp, frameCount); },
267         };
268         if (receiver_ != nullptr) {
269             receiver_->RequestNextVSync(fcb);
270         } else {
271             hasSkipVsync_ = true;
272         }
273     } else {
274         hasSkipVsync_ = true;
275     }
276 }
277 
GetTid()278 int32_t RSRenderThread::GetTid()
279 {
280     return tid_;
281 }
282 
CreateAndInitRenderContextIfNeed()283 void RSRenderThread::CreateAndInitRenderContextIfNeed()
284 {
285 #if (defined(RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && !defined(ROSEN_PREVIEW)
286     if (renderContext_ == nullptr) {
287         renderContext_ = new RenderContext();
288         ROSEN_LOGD("Create RenderContext");
289 #ifdef ROSEN_OHOS
290 #ifdef RS_ENABLE_GL
291         if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
292             RS_TRACE_NAME("InitializeEglContext");
293             renderContext_->InitializeEglContext(); // init egl context on RT
294             if (!cacheDir_.empty()) {
295                 renderContext_->SetCacheDir(cacheDir_);
296             }
297         }
298 #endif
299 #ifdef RS_ENABLE_VK
300     if (!cacheDir_.empty()) {
301         renderContext_->SetCacheDir(cacheDir_);
302     }
303     if (RSSystemProperties::IsUseVulkan()) {
304         renderContext_->SetUpGpuContext(nullptr);
305     }
306 #endif
307 #endif
308     }
309 #endif
310 }
311 
RenderLoop()312 void RSRenderThread::RenderLoop()
313 {
314     SystemCallSetThreadName("RSRenderThread");
315 
316 #ifdef OHOS_RSS_CLIENT
317     std::unordered_map<std::string, std::string> payload;
318     payload["uid"] = std::to_string(getuid());
319     payload["pid"] = std::to_string(GetRealPid());
320     ResourceSchedule::ResSchedClient::GetInstance().ReportData(
321         ResourceSchedule::ResType::RES_TYPE_REPORT_RENDER_THREAD, getproctid(), payload);
322 #endif
323 #ifdef ROSEN_OHOS
324     tid_ = gettid();
325 #endif
326     CreateAndInitRenderContextIfNeed();
327     std::string name = "RSRenderThread_" + std::to_string(GetRealPid());
328     runner_ = AppExecFwk::EventRunner::Create(false);
329     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
330     auto rsClient = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
331     receiver_ = rsClient->CreateVSyncReceiver(name, handler_);
332     if (receiver_ == nullptr) {
333         ROSEN_LOGE("RSRenderThread CreateVSyncReceiver Error");
334         return;
335     }
336     receiver_->Init();
337     if (hasSkipVsync_) {
338         hasSkipVsync_ = false;
339         RSRenderThread::Instance().RequestNextVSync();
340     }
341 #ifdef ROSEN_PREVIEW
342     static auto onSizeChange = [&](int width, int height) {
343         if (isRunning_) {
344             RSRenderThread::Instance().RequestNextVSync();
345         }
346     };
347     GlfwRenderContext::GetGlobal()->OnSizeChanged(onSizeChange);
348 #endif
349 
350 #ifdef ROSEN_OHOS
351     FrameCollector::GetInstance().SetRepaintCallback([this]() { this->RequestNextVSync(); });
352     auto delegate = RSFunctionalDelegate::Create();
353     delegate->SetRepaintCallback([this]() {
354         bool isOverDrawEnabled = RSOverdrawController::GetInstance().IsEnabled();
355         PostTask([this, isOverDrawEnabled]() {
356             isOverDrawEnabledOfCurFrame_ = isOverDrawEnabled;
357             RequestNextVSync();
358         });
359     });
360     RSOverdrawController::GetInstance().SetDelegate(delegate);
361 #endif
362 
363 #ifdef RES_CLINET_SCHED_ENABLE
364     auto ret = OHOS::QOS::SetThreadQos(OHOS::QOS::QosLevel::QOS_USER_INTERACTIVE);
365     RS_LOGI("RSRenderThread: SetThreadQos retcode = %{public}d", ret);
366 #endif
367 
368     if (runner_) {
369         runner_->Run();
370     }
371 }
372 
OnVsync(uint64_t timestamp,int64_t frameCount)373 void RSRenderThread::OnVsync(uint64_t timestamp, int64_t frameCount)
374 {
375     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSRenderThread::OnVsync");
376 #ifdef ROSEN_PREVIEW
377     isRunning_ = true;
378 #endif
379     SendFrameEvent(false);
380     mValue = (mValue + 1) % 2; // 1 and 2 is Calculated parameters
381     RS_TRACE_INT("Vsync-client", mValue);
382     timestamp_ = timestamp;
383     if (activeWindowCnt_.load() > 0) {
384         mainFunc_(); // start render-loop now
385     }
386 #ifdef ROSEN_PREVIEW
387     isRunning_ = false;
388 #endif
389     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
390 }
391 
UpdateWindowStatus(bool active)392 void RSRenderThread::UpdateWindowStatus(bool active)
393 {
394     if (active) {
395         activeWindowCnt_++;
396     } else {
397         activeWindowCnt_--;
398     }
399     ROSEN_LOGD("RSRenderThread UpdateWindowStatus %{public}d, cur activeWindowCnt_ %{public}d",
400         active, activeWindowCnt_.load());
401 }
402 
ProcessCommands()403 void RSRenderThread::ProcessCommands()
404 {
405     // Attention: there are two situations
406     // 1. when commandTimestamp_ != 0, it means that UIDirector has called
407     // "RSRenderThread::Instance().RequestNextVSync()", which equals there are some commands form UIThread need to be
408     // executed. To make commands from UIThread sync with buffer flushed by RenderThread, we choose commandTimestamp_ as
409     // uiTimestamp_ which would be used in RenderThreadVisitor when we call flushFrame.
410     // 2. when cmds_.empty() is true or commandTimestamp_ = 0,
411     // it means that some thread except UIThread like RSRenderThread::Animate
412     // has called "RSRenderThread::Instance().RequestNextVSync()", which equals that some commands form RenderThread
413     // need to be executed. To make commands from RenderThread sync with buffer flushed by RenderThread, we choose
414     // (prevTimestamp_ - 1) as uiTimestamp_ which would be used in RenderThreadVisitor when we call flushFrame.
415 
416     // The reason why prevTimestamp_ need to be minus 1 is that timestamp used in UIThread is always less than (for now)
417     // timestamp used in RenderThread. If we do not do this, when RenderThread::Animate execute flushFrame and use
418     // prevTimestamp_ as buffer timestamp which equals T0, UIDirector send messages in the same vsync period, and the
419     // commandTimestamp_ would also be T0, RenderService would execute commands from UIDirector and composite buffer
420     // which rendering is executed by RSRenderThread::Animate for they have the same timestamp. To avoid this situation,
421     // we should always use "prevTimestamp_ - 1".
422 
423     std::unique_lock<std::mutex> cmdLock(cmdMutex_);
424     if (cmds_.empty()) {
425         uiTimestamp_ = prevTimestamp_ - 1;
426         return;
427     }
428 
429     if (commandTimestamp_ != 0) {
430         uiTimestamp_ = commandTimestamp_;
431         commandTimestamp_ = 0;
432     } else {
433         uiTimestamp_ = prevTimestamp_ - 1;
434     }
435 
436     ROSEN_LOGD("RSRenderThread ProcessCommands size: %{public}lu\n", (unsigned long)cmds_.size());
437     std::vector<std::unique_ptr<RSTransactionData>> cmds;
438 #ifdef CROSS_PLATFORM
439     PrepareCommandForCrossPlatform(cmds);
440 #else
441     std::swap(cmds, cmds_);
442 #endif
443     cmdLock.unlock();
444 
445     // To improve overall responsiveness, we make animations start on LAST frame instead of THIS frame.
446     // If last frame is too far away (earlier than 2 vsync from now), we use currentTimestamp_ - REFRESH_PERIOD as
447     // 'virtual' last frame timestamp.
448     if (timestamp_ - lastAnimateTimestamp_ > 2 * REFRESH_PERIOD) { // 2: if last frame is earlier than 2 vsync from now
449         context_->currentTimestamp_ = timestamp_ - REFRESH_PERIOD;
450     } else {
451         context_->currentTimestamp_ = lastAnimateTimestamp_;
452     }
453     uint64_t uiEndTimeStamp = jankDetector_->GetSysTimeNs();
454     for (auto& cmdData : cmds) {
455         std::string str = "ProcessCommands ptr:" + std::to_string(reinterpret_cast<uintptr_t>(cmdData.get()));
456         ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, str.c_str());
457         // only set transactionTimestamp_ in UniRender mode
458         context_->transactionTimestamp_ = RSSystemProperties::GetUniRenderEnabled() ? cmdData->GetTimestamp() : 0;
459         cmdData->Process(*context_);
460         jankDetector_->UpdateUiDrawFrameMsg(cmdData->GetTimestamp(), uiEndTimeStamp, cmdData->GetAbilityName());
461         ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
462     }
463 }
464 
465 #ifdef CROSS_PLATFORM
PrepareCommandForCrossPlatform(std::vector<std::unique_ptr<RSTransactionData>> & cmds)466 void RSRenderThread::PrepareCommandForCrossPlatform(std::vector<std::unique_ptr<RSTransactionData>>& cmds)
467 {
468     if (cmds_.empty()) {
469         return;
470     }
471     int index = 0;
472     uint64_t firstCmdTimestamp = cmds_[0]->GetTimestamp();
473     uint64_t lastCmdTimestamp = cmds_.back()->GetTimestamp();
474     while (index < cmds_.size()) {
475         if (cmds_[index]->GetTimestamp() <
476             std::max({timestamp_, firstCmdTimestamp + 1, lastCmdTimestamp})) {
477             index++;
478         } else {
479             break;
480         }
481     }
482     for (int i = 0; i < index; i++) {
483         cmds.emplace_back(std::move(cmds_[i]));
484     }
485 
486     cmds_.erase(cmds_.begin(), cmds_.begin() + index);
487     if (!cmds_.empty()) {
488         RequestNextVSync();
489     }
490 }
491 #endif
492 
Animate(uint64_t timestamp)493 void RSRenderThread::Animate(uint64_t timestamp)
494 {
495     RS_TRACE_FUNC();
496 
497     lastAnimateTimestamp_ = timestamp;
498 
499     if (context_->animatingNodeList_.empty()) {
500         return;
501     }
502 
503     bool needRequestNextVsync = false;
504     // For now, there is no need to optimize the power consumption issue related to delayTime.
505     int64_t minLeftDelayTime = 0;
506     // isCalculateAnimationValue is embedded modify for stat animate frame drop
507     bool isCalculateAnimationValue = false;
508     // iterate and animate all animating nodes, remove if animation finished
509     EraseIf(context_->animatingNodeList_,
510         [timestamp, &needRequestNextVsync, &isCalculateAnimationValue, &minLeftDelayTime](const auto& iter) -> bool {
511         auto node = iter.second.lock();
512         if (node == nullptr) {
513             ROSEN_LOGD("RSRenderThread::Animate removing expired animating node");
514             return true;
515         }
516         auto [hasRunningAnimation, nodeNeedRequestNextVsync, nodeCalculateAnimationValue] =
517             node->Animate(timestamp, minLeftDelayTime);
518         if (!hasRunningAnimation) {
519             ROSEN_LOGD("RSRenderThread::Animate removing finished animating node %{public}" PRIu64, node->GetId());
520         }
521         needRequestNextVsync = needRequestNextVsync || nodeNeedRequestNextVsync;
522         isCalculateAnimationValue = isCalculateAnimationValue || nodeCalculateAnimationValue;
523         return !hasRunningAnimation;
524     });
525     if (!isCalculateAnimationValue && needRequestNextVsync) {
526         RS_TRACE_NAME("Animation running empty");
527     }
528 
529     if (needRequestNextVsync) {
530         RSRenderThread::Instance().RequestNextVSync();
531     }
532 }
533 
Render()534 void RSRenderThread::Render()
535 {
536     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
537         RSPropertyTrace::GetInstance().RefreshNodeTraceInfo();
538     }
539     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSRenderThread::Render");
540     RsFrameReport::GetInstance().RenderStart(timestamp_);
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     DrawableV2::RSRenderNodeDrawableAdapter::ClearResource();
559     RSSurfaceBufferCallbackManager::Instance().RunSurfaceBufferCallback();
560     isOverDrawEnabledOfLastFrame_ = isOverDrawEnabledOfCurFrame_;
561     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
562 }
563 
SendCommands()564 void RSRenderThread::SendCommands()
565 {
566     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSRenderThread::SendCommands");
567     RsFrameReport::GetInstance().SendCommandsStart();
568 
569     RSUIDirector::RecvMessages();
570     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
571 }
572 
Detach(NodeId id)573 void RSRenderThread::Detach(NodeId id)
574 {
575     if (auto node = context_->GetNodeMap().GetRenderNode<RSRootRenderNode>(id)) {
576         std::unique_lock<std::mutex> lock(mutex_);
577         context_->GetGlobalRootRenderNode()->RemoveChild(node);
578     }
579 }
580 
PostTask(RSTaskMessage::RSTask task)581 void RSRenderThread::PostTask(RSTaskMessage::RSTask task)
582 {
583     if (handler_) {
584         handler_->PostTask(task);
585     }
586 }
587 
PostSyncTask(RSTaskMessage::RSTask task)588 void RSRenderThread::PostSyncTask(RSTaskMessage::RSTask task)
589 {
590     if (handler_) {
591         handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
592     }
593 }
594 
PostPreTask()595 void RSRenderThread::PostPreTask()
596 {
597     if (handler_ && preTask_) {
598         handler_->PostTask(preTask_);
599     }
600 }
601 } // namespace Rosen
602 } // namespace OHOS
603