1 /*
2  * Copyright (c) 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 
17 #include "pipeline/rs_uifirst_manager.h"
18 
19 #include "luminance/rs_luminance_control.h"
20 #include "rs_trace.h"
21 
22 #include "common/rs_optional_trace.h"
23 #include "drawable/rs_surface_render_node_drawable.h"
24 #include "params/rs_display_render_params.h"
25 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
26 #include "pipeline/rs_canvas_render_node.h"
27 #include "pipeline/rs_uni_render_util.h"
28 #include "pipeline/rs_main_thread.h"
29 #include "platform/common/rs_log.h"
30 
31 // use in mainthread, post subthread, not affect renderthread
32 namespace OHOS {
33 namespace Rosen {
34 namespace {
35     constexpr int EVENT_START_TIMEOUT = 500;
36     constexpr int EVENT_STOP_TIMEOUT = 150;
37     constexpr int EVENT_DISABLE_UIFIRST_GAP = 100;
38     constexpr int CLEAR_CACHE_DELAY = 400;
39     const std::string CLEAR_CACHE_TASK_PREFIX = "uifirst_clear_cache_";
40     constexpr std::string_view ARKTSCARDNODE_NAME = "ArkTSCardNode";
41     constexpr std::string_view EVENT_DISABLE_UIFIRST = "APP_LIST_FLING";
GetCurSysTime()42     inline int64_t GetCurSysTime()
43     {
44         auto curTime = std::chrono::system_clock::now().time_since_epoch();
45         return std::chrono::duration_cast<std::chrono::milliseconds>(curTime).count();
46     }
47 };
48 
Instance()49 RSUifirstManager& RSUifirstManager::Instance()
50 {
51     static RSUifirstManager instance; // store in mainthread instance ?
52     return instance;
53 }
54 
RSUifirstManager()55 RSUifirstManager::RSUifirstManager() :
56 #if defined(RS_ENABLE_VK)
57     useDmaBuffer_(RSSystemParameters::GetUIFirstDmaBufferEnabled() &&
58         RSSystemProperties::IsPhoneType() && RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN)
59 #else
60     useDmaBuffer_(false)
61 #endif
62 {}
63 
GetSurfaceDrawableByID(NodeId id)64 std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> RSUifirstManager::GetSurfaceDrawableByID(NodeId id)
65 {
66     if (const auto cacheIt = subthreadProcessingNode_.find(id); cacheIt != subthreadProcessingNode_.end()) {
67         if (const auto ptr = cacheIt->second) {
68             return std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(ptr);
69         }
70     }
71     // unlikely
72     auto ptr = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(id);
73     if (ptr) {
74         return std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(ptr);
75     }
76     return nullptr;
77 }
78 
SetUifirstNodeEnableParam(RSSurfaceRenderNode & node,MultiThreadCacheType type)79 void RSUifirstManager::SetUifirstNodeEnableParam(RSSurfaceRenderNode& node, MultiThreadCacheType type)
80 {
81     node.SetUifirstNodeEnableParam(type); // update drawable param
82     auto isType = type == MultiThreadCacheType::LEASH_WINDOW || type == MultiThreadCacheType::NONFOCUS_WINDOW;
83     if (node.IsLeashWindow() && type != MultiThreadCacheType::ARKTS_CARD) {
84         for (auto& child : *(node.GetChildren())) {
85             if (!child) {
86                 continue;
87             }
88             auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
89             if (!surfaceChild) {
90                 continue;
91             }
92             if (surfaceChild->IsMainWindowType()) {
93                 surfaceChild->SetIsParentUifirstNodeEnableParam(isType);
94                 continue;
95             }
96         }
97     }
98 }
99 
100 // unref in sub when cache done
AddProcessDoneNode(NodeId id)101 void RSUifirstManager::AddProcessDoneNode(NodeId id)
102 {
103     // mutex
104     if (id == INVALID_NODEID) {
105         return;
106     }
107     RS_OPTIONAL_TRACE_NAME_FMT("sub done %" PRIu64"", id);
108     std::lock_guard<std::mutex> lock(childernDrawableMutex_);
109     subthreadProcessDoneNode_.push_back(id);
110 }
111 
ResetUifirstNode(std::shared_ptr<RSSurfaceRenderNode> & nodePtr)112 void RSUifirstManager::ResetUifirstNode(std::shared_ptr<RSSurfaceRenderNode>& nodePtr)
113 {
114     if (!nodePtr) {
115         return;
116     }
117     nodePtr->SetUifirstUseStarting(false);
118     SetUifirstNodeEnableParam(*nodePtr, MultiThreadCacheType::NONE);
119     RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
120     auto drawable = GetSurfaceDrawableByID(nodePtr->GetId());
121     if (!drawable) {
122         return;
123     }
124     if (!nodePtr->IsOnTheTree() && nodePtr->IsNodeToBeCaptured()) {
125         drawable->ResetUifirst(true);
126         auto taskName = CLEAR_CACHE_TASK_PREFIX + std::to_string(nodePtr->GetId());
127         auto releaseTask = [drawable] {
128             auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
129             if (surfaceParams && surfaceParams->GetUifirstNodeEnableParam() == MultiThreadCacheType::NONE) {
130                 RS_TRACE_NAME_FMT("ResetUifirstNode clearCache id:%llu", surfaceParams->GetId());
131                 drawable->ResetUifirst(false);
132             }
133         };
134         RSUniRenderThread::Instance().PostTask(releaseTask, taskName, CLEAR_CACHE_DELAY);
135     } else {
136         nodePtr->SetIsNodeToBeCaptured(false);
137         drawable->ResetUifirst(false);
138     }
139 }
140 
MergeOldDirty(NodeId id)141 void RSUifirstManager::MergeOldDirty(NodeId id)
142 {
143     if (!mainThread_) {
144         return;
145     }
146     auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
147         mainThread_->GetContext().GetNodeMap().GetRenderNode(id));
148     if (!node) {
149         return;
150     }
151     if (node->IsAppWindow() &&
152         !RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node->GetParent().lock())) {
153         MergeOldDirtyToDrawable(node);
154         return;
155     }
156     for (auto& child : * node-> GetSortedChildren()) {
157         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
158         if (surfaceNode && surfaceNode->IsAppWindow()) {
159             MergeOldDirtyToDrawable(surfaceNode);
160             break;
161         }
162     }
163 }
164 
MergeOldDirtyToDrawable(std::shared_ptr<RSSurfaceRenderNode> node)165 void RSUifirstManager::MergeOldDirtyToDrawable(std::shared_ptr<RSSurfaceRenderNode> node)
166 {
167     auto drawable = node->GetRenderDrawable();
168     if (!drawable) {
169         return;
170     }
171     const auto& oldDirty = node->GetOldDirty();
172     RS_OPTIONAL_TRACE_NAME_FMT("uifirst MergeOldDirty %" PRIu64" [%d %d %d %d]",
173         node->GetId(), oldDirty.left_, oldDirty.top_, oldDirty.width_, oldDirty.height_);
174     auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
175     if (auto dirtyManager = surfaceDrawable->GetSyncDirtyManager()) {
176         dirtyManager->MergeDirtyRect(oldDirty);
177     }
178 }
179 
RenderGroupUpdate(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable)180 void RSUifirstManager::RenderGroupUpdate(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable)
181 {
182     if (mainThread_ == nullptr) {
183         return;
184     }
185     auto nodeSp = mainThread_->GetContext().GetNodeMap().GetRenderNode(drawable->GetId());
186     if (nodeSp == nullptr) {
187         return;
188     }
189     auto surfaceNode = std::static_pointer_cast<const RSSurfaceRenderNode>(nodeSp);
190     if (surfaceNode == nullptr) {
191         return;
192     }
193     // mark all parent rendergroup need update; planning: mark autoCache need update
194     auto node = surfaceNode->GetParent().lock();
195 
196     while (node != nullptr) {
197         if (node->GetType() == RSRenderNodeType::DISPLAY_NODE) {
198             break;
199         }
200         if (node->IsSuggestedDrawInGroup()) {
201             RS_OPTIONAL_TRACE_NAME_FMT("cache_changed by uifirst card %" PRIu64"", node->GetId());
202             node->SetDrawingCacheChanged(true);
203             node->AddToPendingSyncList();
204         }
205         node = node->GetParent().lock();
206     }
207 }
208 
ProcessForceUpdateNode()209 void RSUifirstManager::ProcessForceUpdateNode()
210 {
211     if (!mainThread_) {
212         return;
213     }
214     std::vector<std::shared_ptr<RSRenderNode>> toDirtyNodes;
215     for (auto id : pendingForceUpdateNode_) {
216         auto node = mainThread_->GetContext().GetNodeMap().GetRenderNode(id);
217         if (!node || node->GetLastFrameUifirstFlag() != MultiThreadCacheType::ARKTS_CARD) {
218             continue;
219         }
220         toDirtyNodes.push_back(node);
221         if (!node->IsDirty() && !node->IsSubTreeDirty()) {
222             markForceUpdateByUifirst_.push_back(node);
223             node->SetForceUpdateByUifirst(true);
224         }
225     }
226     for (auto& node : toDirtyNodes) {
227         node->SetDirty(true);
228     }
229     pendingForceUpdateNode_.clear();
230 }
231 
NotifyUIStartingWindow(NodeId id,bool wait)232 void RSUifirstManager::NotifyUIStartingWindow(NodeId id, bool wait)
233 {
234     if (mainThread_ == nullptr) {
235         return;
236     }
237     auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
238         mainThread_->GetContext().GetNodeMap().GetRenderNode(id));
239     if (node == nullptr || !node->IsLeashWindow()) {
240         return;
241     }
242     for (auto& child : *node->GetChildren()) {
243         if (!child) {
244             continue;
245         }
246         auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
247         if (surfaceChild && surfaceChild->IsMainWindowType()) {
248             surfaceChild->SetWaitUifirstFirstFrame(wait);
249             RS_TRACE_NAME_FMT("uifirst NotifyUIStartingWindow id:%llu, wait:%d", surfaceChild->GetId(), wait);
250             RS_LOGI("uifirst NotifyUIStartingWindow id:%{public}" PRIu64 ", wait:%{public}d",
251                 surfaceChild->GetId(), wait);
252         }
253     }
254 }
255 
ProcessDoneNodeInner()256 void RSUifirstManager::ProcessDoneNodeInner()
257 {
258     std::vector<NodeId> tmp;
259     {
260         std::lock_guard<std::mutex> lock(childernDrawableMutex_);
261         if (subthreadProcessDoneNode_.size() == 0) {
262             return;
263         }
264         std::swap(tmp, subthreadProcessDoneNode_);
265         subthreadProcessDoneNode_.clear();
266     }
267     RS_TRACE_NAME_FMT("ProcessDoneNode num%d", tmp.size());
268     for (auto& id : tmp) {
269         RS_OPTIONAL_TRACE_NAME_FMT("Done %" PRIu64"", id);
270         auto drawable = GetSurfaceDrawableByID(id);
271         if (drawable && drawable->GetCacheSurfaceNeedUpdated() &&
272             drawable->CheckCacheSurface()) {
273             drawable->UpdateCompletedCacheSurface();
274             RenderGroupUpdate(drawable);
275             SetHasDoneNodeFlag(true);
276             pendingForceUpdateNode_.push_back(id);
277         }
278         NotifyUIStartingWindow(id, false);
279         subthreadProcessingNode_.erase(id);
280     }
281 }
282 
ProcessDoneNode()283 void RSUifirstManager::ProcessDoneNode()
284 {
285     SetHasDoneNodeFlag(false);
286     ProcessDoneNodeInner();
287 
288     // reset node when node is not doing
289     for (auto it = capturedNodes_.begin(); it != capturedNodes_.end();) {
290         if (mainThread_ && subthreadProcessingNode_.find(*it) == subthreadProcessingNode_.end()) {
291             // reset uifirst
292             auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
293                 mainThread_->GetContext().GetNodeMap().GetRenderNode(*it));
294             if (node == nullptr) {
295                 it = capturedNodes_.erase(it);
296                 continue;
297             }
298             node->SetIsNodeToBeCaptured(false);
299             if (node->GetLastFrameUifirstFlag() == MultiThreadCacheType::NONE) {
300                 ResetUifirstNode(node);
301             }
302             it = capturedNodes_.erase(it);
303         } else {
304             it++;
305         }
306     }
307     for (auto it = pendingResetNodes_.begin(); it != pendingResetNodes_.end();) {
308         if (subthreadProcessingNode_.find(it->first) == subthreadProcessingNode_.end()) {
309             ResetUifirstNode(it->second);
310             it = pendingResetNodes_.erase(it);
311         } else {
312             it++;
313         }
314     }
315 
316     for (auto it = subthreadProcessingNode_.begin(); it != subthreadProcessingNode_.end();) {
317         auto id = it->first;
318         auto drawable = GetSurfaceDrawableByID(id);
319         if (!drawable) {
320             ++it;
321             continue;
322         }
323         auto cacheStatus = drawable->GetCacheSurfaceProcessedStatus();
324         if ((drawable->HasCachedTexture() && cacheStatus == CacheProcessStatus::WAITING) ||
325             cacheStatus == CacheProcessStatus::SKIPPED) {
326             it = subthreadProcessingNode_.erase(it);
327             continue;
328         }
329         pendingPostNodes_.erase(it->first); // dele doing node in pendingpostlist
330         pendingPostCardNodes_.erase(it->first);
331         ++it;
332     }
333 }
334 
SyncHDRDisplayParam(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable)335 void RSUifirstManager::SyncHDRDisplayParam(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable)
336 {
337     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
338     if (!surfaceParams || !surfaceParams->GetAncestorDisplayNode().lock()) {
339         return;
340     }
341     auto ancestor = surfaceParams->GetAncestorDisplayNode().lock()->ReinterpretCastTo<RSDisplayRenderNode>();
342     if (!ancestor) {
343         return;
344     }
345     auto displayParams = static_cast<RSDisplayRenderParams*>(ancestor->GetRenderParams().get());
346     if (!displayParams) {
347         return;
348     }
349     bool isHdrOn = displayParams->GetHDRPresent();
350     ScreenId id = displayParams->GetScreenId();
351     drawable->SetHDRPresent(isHdrOn);
352     if (isHdrOn) {
353         drawable->SetScreenId(id);
354         drawable->SetTargetColorGamut(displayParams->GetNewColorSpace());
355     }
356     RS_LOGD("UIFirstHDR SyncDisplayParam:%{public}d, ratio:%{public}f", drawable->GetHDRPresent(),
357         surfaceParams->GetBrightnessRatio());
358 }
359 
CheckVisibleDirtyRegionIsEmpty(const std::shared_ptr<RSSurfaceRenderNode> & node)360 bool RSUifirstManager::CheckVisibleDirtyRegionIsEmpty(const std::shared_ptr<RSSurfaceRenderNode>& node)
361 {
362     if (RSMainThread::Instance()->GetDeviceType() != DeviceType::PC) {
363         return false;
364     }
365     for (auto& child : *node->GetSortedChildren()) {
366         if (std::shared_ptr<RSSurfaceRenderNode> surfaceNode =
367                 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)) {
368             auto visibleRegion = surfaceNode->GetVisibleRegion();
369             if (visibleRegion.IsEmpty()) {
370                 surfaceNode->SetUIFirstIsPurge(false);
371                 return true;
372             }
373             auto drawable = surfaceNode->GetRenderDrawable();
374             if (!drawable) {
375                 continue;
376             }
377             auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
378             auto surfaceDirtyRect = surfaceDrawable->GetSyncDirtyManager()->GetCurrentFrameDirtyRegion();
379             Occlusion::Region surfaceDirtyRegion { { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
380                 surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() } };
381             Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
382             if (surfaceVisibleDirtyRegion.IsEmpty()) {
383                 surfaceNode->SetUIFirstIsPurge(false);
384                 return true;
385             }
386             if (!surfaceNode->GetUIFirstIsPurge()) {
387                 surfaceNode->SetUIFirstIsPurge(true);
388                 return false;
389             }
390         }
391     }
392     return false;
393 }
394 
DoPurgePendingPostNodes(std::unordered_map<NodeId,std::shared_ptr<RSSurfaceRenderNode>> & pendingNode)395 void RSUifirstManager::DoPurgePendingPostNodes(std::unordered_map<NodeId,
396     std::shared_ptr<RSSurfaceRenderNode>>& pendingNode)
397 {
398     auto deviceType = RSMainThread::Instance()->GetDeviceType();
399     for (auto it = pendingNode.begin(); it != pendingNode.end();) {
400         auto id = it->first;
401         auto drawable = GetSurfaceDrawableByID(id);
402         if (!drawable) {
403             ++it;
404             continue;
405         }
406         SyncHDRDisplayParam(drawable);
407         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
408         auto node = it->second;
409         if (!surfaceParams || !node) {
410             ++it;
411             continue;
412         }
413 
414         if (!node->IsOnTheTree() && subthreadProcessingNode_.find(id) == subthreadProcessingNode_.end()) {
415             it = pendingNode.erase(it);
416             continue;
417         }
418 
419         bool staticContent = drawable->IsCurFrameStatic(deviceType);
420         if (drawable->HasCachedTexture() && (staticContent || CheckVisibleDirtyRegionIsEmpty(node)) &&
421             (subthreadProcessingNode_.find(id) == subthreadProcessingNode_.end()) &&
422             !drawable->IsSubThreadSkip()) {
423             RS_OPTIONAL_TRACE_NAME_FMT("Purge node name %s", surfaceParams->GetName().c_str());
424             it = pendingNode.erase(it);
425         } else {
426             ++it;
427         }
428     }
429 }
430 
PurgePendingPostNodes()431 void RSUifirstManager::PurgePendingPostNodes()
432 {
433     RS_OPTIONAL_TRACE_NAME_FMT("PurgePendingPostNodes");
434     DoPurgePendingPostNodes(pendingPostNodes_);
435     DoPurgePendingPostNodes(pendingPostCardNodes_);
436     for (auto& node : markForceUpdateByUifirst_) {
437         node->SetForceUpdateByUifirst(false);
438     }
439     markForceUpdateByUifirst_.clear();
440     for (auto id : pendingForceUpdateNode_) {
441         MergeOldDirty(id);
442     }
443 }
444 
PostSubTask(NodeId id)445 void RSUifirstManager::PostSubTask(NodeId id)
446 {
447     RS_TRACE_NAME("post UpdateCacheSurface");
448 
449     if (subthreadProcessingNode_.find(id) != subthreadProcessingNode_.end()) { // drawable is doing, do not send
450         RS_TRACE_NAME_FMT("node %" PRIu64" is doing", id);
451         RS_LOGE("RSUifirstManager ERROR: post task twice");
452         return;
453     }
454 
455     // 1.find in cache list(done to dele) 2.find in global list
456     auto drawable = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(id);
457     if (drawable) {
458         // ref drawable
459         subthreadProcessingNode_.emplace(id, drawable);
460         // post task
461         RS_OPTIONAL_TRACE_NAME_FMT("Post_SubTask_s %" PRIu64"", id);
462         RSSubThreadManager::Instance()->ScheduleRenderNodeDrawable(
463             std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable));
464     }
465 }
466 
TryReleaseTextureForIdleThread()467 void RSUifirstManager::TryReleaseTextureForIdleThread()
468 {
469     if (noUifirstNodeFrameCount_.load() <= CLEAR_RES_THRESHOLD) {
470         return;
471     }
472     RSSubThreadManager::Instance()->TryReleaseTextureForIdleThread();
473 }
474 
PostReleaseCacheSurfaceSubTasks()475 void RSUifirstManager::PostReleaseCacheSurfaceSubTasks()
476 {
477     for (auto& cardNode : collectedCardNodes_) {
478         PostReleaseCacheSurfaceSubTask(cardNode);
479     }
480 }
481 
PostReleaseCacheSurfaceSubTask(NodeId id)482 void RSUifirstManager::PostReleaseCacheSurfaceSubTask(NodeId id)
483 {
484     RS_OPTIONAL_TRACE_NAME_FMT("post ReleaseCacheSurface %d", id);
485 
486     if (subthreadProcessingNode_.find(id) != subthreadProcessingNode_.end()) { // drawable is doing, do not send
487         RS_TRACE_NAME_FMT("node %" PRIu64" is doing", id);
488         RS_LOGE("RSUifirstManager ERROR: try to clean running node");
489         return;
490     }
491 
492     // 1.find in cache list(done to dele) 2.find in global list
493     auto drawable = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(id);
494     if (drawable) {
495         // post task
496         RS_OPTIONAL_TRACE_NAME_FMT("Post_SubTask_s %" PRIu64"", id);
497         RSSubThreadManager::Instance()->ScheduleReleaseCacheSurfaceOnly(
498             std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable));
499     }
500 }
501 
UpdateSkipSyncNode()502 void RSUifirstManager::UpdateSkipSyncNode()
503 {
504     processingNodeSkipSync_.clear();
505     processingNodePartialSync_.clear();
506     processingCardNodeSkipSync_.clear();
507     RS_OPTIONAL_TRACE_NAME_FMT("UpdateSkipSyncNode doning%d", subthreadProcessingNode_.size());
508     if (subthreadProcessingNode_.size() == 0) {
509         return;
510     }
511     if (!mainThread_) {
512         return;
513     }
514     for (auto it = subthreadProcessingNode_.begin(); it != subthreadProcessingNode_.end(); it++) {
515         RS_OPTIONAL_TRACE_NAME_FMT("doning%" PRIu64"", it->first);
516         auto node = mainThread_->GetContext().GetNodeMap().GetRenderNode(it->first);
517         if (!node) {
518             continue;
519         }
520         auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>();
521         if (!surfaceNode) {
522             continue;
523         }
524         // ArkTSCard
525         if (NodeIsInCardWhiteList(*node)) {
526             if (surfaceNode->GetLastFrameUifirstFlag() == MultiThreadCacheType::ARKTS_CARD) {
527                 processingCardNodeSkipSync_.insert(it->first);
528                 continue;
529             }
530         }
531 
532         // leash window
533         processingNodePartialSync_.insert(it->first); // partial sync
534         std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
535         surfaceNode->GetAllSubSurfaceNodes(allSubSurfaceNodes);
536         for (auto& [id, subSurfaceNode] : allSubSurfaceNodes) {
537             processingNodeSkipSync_.insert(id); // skip sync
538         }
539     }
540 }
541 
ProcessSubDoneNode()542 void RSUifirstManager::ProcessSubDoneNode()
543 {
544     RS_OPTIONAL_TRACE_NAME_FMT("ProcessSubDoneNode");
545     ConvertPendingNodeToDrawable();
546     ProcessDoneNode(); // release finish drawable
547     UpdateSkipSyncNode();
548     RestoreSkipSyncNode();
549     ResetCurrentFrameDeletedCardNodes();
550 }
551 
ConvertPendingNodeToDrawable()552 void RSUifirstManager::ConvertPendingNodeToDrawable()
553 {
554     {
555         std::lock_guard<std::mutex> lock(useDmaBufferMutex_);
556         if (!useDmaBuffer_) {
557             return;
558         }
559     }
560     pendingPostDrawables_.clear();
561     for (const auto& iter : pendingPostNodes_) {
562         if (iter.second && GetUseDmaBuffer(iter.second->GetName())) {
563             if (auto drawableNode = DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(iter.second)) {
564                 pendingPostDrawables_.emplace_back(
565                     std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawableNode));
566             }
567         }
568     }
569 }
570 
SetUifirstSkipPartialSync(const std::shared_ptr<RSRenderNode> & node,bool needSync)571 static inline void SetUifirstSkipPartialSync(const std::shared_ptr<RSRenderNode> &node, bool needSync)
572 {
573     // node not null in caller
574     if (!needSync) {
575         return;
576     }
577     node->SetUifirstSkipPartialSync(true);
578 }
579 
GetUifirstCachedState(NodeId id)580 CacheProcessStatus& RSUifirstManager::GetUifirstCachedState(NodeId id)
581 {
582     auto ret = uifirstCacheState_.insert({ id, CacheProcessStatus::UNKNOWN });
583     auto& curRootIdState = ret.first->second;
584     if (curRootIdState == CacheProcessStatus::UNKNOWN) {
585         /* first time to get the state of uifirstRoot, and cache the state for the remaining other times */
586         auto uifirstRootNodeDrawable = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(id);
587         if (uifirstRootNodeDrawable && uifirstRootNodeDrawable->GetNodeType() == RSRenderNodeType::SURFACE_NODE) {
588             auto drawableNode =
589                 std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(uifirstRootNodeDrawable);
590             curRootIdState = drawableNode->GetCacheSurfaceProcessedStatus();
591         }
592     }
593     return curRootIdState;
594 }
595 
CollectSkipSyncNodeWithDrawableState(const std::shared_ptr<RSRenderNode> & node)596 RSUifirstManager::SkipSyncState RSUifirstManager::CollectSkipSyncNodeWithDrawableState(
597     const std::shared_ptr<RSRenderNode>& node)
598 {
599     auto isPreDoing = IsPreFirstLevelNodeDoingAndTryClear(node);
600     auto drawable = node->GetRenderDrawable();
601     if (UNLIKELY(!drawable || !drawable->GetRenderParams())) {
602         RS_LOGE("RSUifirstManager::CollectSkipSyncNode drawable/params nullptr");
603         // must not be in the DOING state with the invalid drawable.
604         return SkipSyncState::STATE_NOT_SKIP;
605     }
606     auto& params = drawable->GetRenderParams();
607     // if node's UifirstRootNodeId is valid (e.g. ArkTsCard), use it first
608     auto uifirstRootId = params->GetUifirstRootNodeId() != INVALID_NODEID ?
609         params->GetUifirstRootNodeId() : params->GetFirstLevelNodeId();
610     auto& curRootIdState = GetUifirstCachedState(uifirstRootId);
611     RS_OPTIONAL_TRACE_NAME_FMT("node[%" PRIu64 " %" PRIu64 "] drawable[%"
612         PRIu64 " %" PRIu64 "] and curNodeId [%" PRIu64"] cacheState[%d]",
613         node->GetStagingRenderParams()->GetUifirstRootNodeId(), node->GetStagingRenderParams()->GetFirstLevelNodeId(),
614         params->GetUifirstRootNodeId(), params->GetFirstLevelNodeId(), node->GetId(), curRootIdState);
615 
616     if (curRootIdState == CacheProcessStatus::DOING || curRootIdState == CacheProcessStatus::WAITING ||
617         /* unknow state to check prefirstLevelNode */
618         (uifirstRootId == INVALID_NODEID && isPreDoing)) {
619         pendingSyncForSkipBefore_[uifirstRootId].push_back(node);
620         auto isUifirstRootNode = (uifirstRootId == node->GetId());
621         RS_OPTIONAL_TRACE_NAME_FMT("%s %" PRIu64 " root%" PRIu64,
622             isUifirstRootNode ? "set partial_sync" : "CollectSkipSyncNode", node->GetId(), uifirstRootId);
623         SetUifirstSkipPartialSync(node, isUifirstRootNode);
624         return isUifirstRootNode ? SkipSyncState::STATE_NOT_SKIP : SkipSyncState::STATE_NEED_SKIP;
625     }
626     return SkipSyncState::STATE_NEED_CHECK;
627 }
628 
CollectSkipSyncNode(const std::shared_ptr<RSRenderNode> & node)629 bool RSUifirstManager::CollectSkipSyncNode(const std::shared_ptr<RSRenderNode> &node)
630 {
631     if (!node) {
632         return false;
633     }
634     if (pendingPostNodes_.find(node->GetId()) != pendingPostNodes_.end() ||
635         pendingPostCardNodes_.find(node->GetId()) != pendingPostCardNodes_.end()) {
636         node->SetUifirstSyncFlag(true);
637     }
638 
639     auto ret = CollectSkipSyncNodeWithDrawableState(node);
640     if (ret != SkipSyncState::STATE_NEED_CHECK) {
641         return ret == SkipSyncState::STATE_NEED_SKIP;
642     }
643 
644     if (NodeIsInCardWhiteList(*node) && processingCardNodeSkipSync_.count(node->GetUifirstRootNodeId())) {
645         pendingSyncForSkipBefore_[node->GetUifirstRootNodeId()].push_back(node);
646         auto isUifirstRootNode = (node->GetUifirstRootNodeId() == node->GetId());
647         RS_OPTIONAL_TRACE_NAME_FMT("%s %" PRIu64 " root%" PRIu64,
648             isUifirstRootNode ? "set partial_sync card" : "CollectSkipSyncNode card",
649             node->GetId(), node->GetInstanceRootNodeId());
650         SetUifirstSkipPartialSync(node, isUifirstRootNode);
651         return !isUifirstRootNode;
652     }
653     if (processingNodePartialSync_.count(node->GetInstanceRootNodeId()) > 0) {
654         pendingSyncForSkipBefore_[node->GetInstanceRootNodeId()].push_back(node);
655         auto isInstanceRootNode = (node->GetInstanceRootNodeId() == node->GetId());
656         RS_OPTIONAL_TRACE_NAME_FMT("%s %" PRIu64 " root%" PRIu64,
657             isInstanceRootNode ? "set partial_sync" : "CollectSkipSyncNode",
658             node->GetId(), node->GetInstanceRootNodeId());
659         SetUifirstSkipPartialSync(node, isInstanceRootNode);
660         return !isInstanceRootNode;
661     } else if (processingNodeSkipSync_.count(node->GetInstanceRootNodeId()) > 0) {
662         RS_OPTIONAL_TRACE_NAME_FMT("CollectSkipSyncNode root %" PRIu64", node %" PRIu64,
663             node->GetInstanceRootNodeId(), node->GetId());
664         pendingSyncForSkipBefore_[node->GetInstanceRootNodeId()].push_back(node);
665         return true;
666     }
667     return false;
668 }
669 
RestoreSkipSyncNode()670 void RSUifirstManager::RestoreSkipSyncNode()
671 {
672     std::vector<NodeId> todele;
673     for (auto& it : pendingSyncForSkipBefore_) {
674         if (processingNodeSkipSync_.count(it.first) == 0 && processingNodePartialSync_.count(it.first) == 0 &&
675             processingCardNodeSkipSync_.count(it.first) == 0) {
676             todele.push_back(it.first);
677             RS_OPTIONAL_TRACE_NAME_FMT("RestoreSkipSyncNode %" PRIu64" num%d", it.first, it.second.size());
678             for (auto& node : it.second) {
679                 node->SetUifirstSkipPartialSync(false);
680                 node->AddToPendingSyncList();
681             }
682         }
683     }
684     for (auto id : todele) {
685         pendingSyncForSkipBefore_.erase(id);
686         if (!mainThread_) {
687             continue;
688         }
689         auto node = mainThread_->GetContext().GetNodeMap().GetRenderNode(id);
690         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
691         if (!surfaceNode) {
692             continue;
693         }
694         if (surfaceNode->GetLastFrameUifirstFlag() == MultiThreadCacheType::ARKTS_CARD &&
695             surfaceNode->GetUifirstRootNodeId() == surfaceNode->GetId() &&
696             pendingPostCardNodes_.find(surfaceNode->GetId()) == pendingPostCardNodes_.end()) {
697             pendingPostCardNodes_[surfaceNode->GetId()] = surfaceNode;
698             RS_OPTIONAL_TRACE_NAME_FMT("RestoreSkipSyncNode AddPendingPostCard %llu", id);
699         }
700     }
701 }
702 
ClearSubthreadRes()703 void RSUifirstManager::ClearSubthreadRes()
704 {
705     RS_OPTIONAL_TRACE_NAME_FMT("ClearSubthreadRes");
706     if (subthreadProcessingNode_.size() == 0 &&
707         pendingSyncForSkipBefore_.size() == 0) {
708         noUifirstNodeFrameCount_.fetch_add(1);
709         if (noUifirstNodeFrameCount_.load() == CLEAR_RES_THRESHOLD) {
710             RSSubThreadManager::Instance()->ResetSubThreadGrContext();
711             PostReleaseCacheSurfaceSubTasks();
712         }
713     } else {
714         noUifirstNodeFrameCount_.store(0);
715     }
716     reuseNodes_.clear();
717 }
718 
ForceClearSubthreadRes()719 void RSUifirstManager::ForceClearSubthreadRes()
720 {
721     noUifirstNodeFrameCount_.store(0);
722     RSSubThreadManager::Instance()->ReleaseTexture();
723 }
724 
IsPreFirstLevelNodeDoingAndTryClear(std::shared_ptr<RSRenderNode> node)725 bool RSUifirstManager::IsPreFirstLevelNodeDoingAndTryClear(std::shared_ptr<RSRenderNode> node)
726 {
727     if (!node) {
728         return true;
729     }
730     auto& preFirstLevelNodeIdSet = node->GetMutablePreFirstLevelNodeIdSet();
731     for (auto it = preFirstLevelNodeIdSet.begin(); it != preFirstLevelNodeIdSet.end();
732          it = preFirstLevelNodeIdSet.erase(it)) {
733         auto& curRootIdState = GetUifirstCachedState(*it);
734         if (curRootIdState == CacheProcessStatus::DOING || curRootIdState == CacheProcessStatus::WAITING) {
735             return true;
736         }
737     }
738     return false;
739 }
740 
SetNodePriorty(std::list<NodeId> & result,std::unordered_map<NodeId,std::shared_ptr<RSSurfaceRenderNode>> & pendingNode)741 void RSUifirstManager::SetNodePriorty(std::list<NodeId>& result,
742     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& pendingNode)
743 {
744     bool isFocusNodeFound = false;
745     auto isFocusId = RSMainThread::Instance()->GetFocusNodeId();
746     auto isLeashId = RSMainThread::Instance()->GetFocusLeashWindowId();
747     for (auto& item : pendingNode) {
748         auto const& [id, value] = item;
749         if (IsPreFirstLevelNodeDoingAndTryClear(value)) {
750             continue;
751         }
752         auto drawable = GetSurfaceDrawableByID(id);
753         if (!drawable) {
754             continue;
755         }
756         if (!isFocusNodeFound) {
757             if (id == isFocusId || id == isLeashId) {
758                 // for resolving response latency
759                 drawable->SetRenderCachePriority(NodePriorityType::SUB_FOCUSNODE_PRIORITY);
760                 isFocusNodeFound = true;
761             }
762         }
763         if (drawable->HasCachedTexture()) {
764             drawable->SetRenderCachePriority(NodePriorityType::SUB_LOW_PRIORITY);
765         } else {
766             drawable->SetRenderCachePriority(NodePriorityType::SUB_HIGH_PRIORITY);
767         }
768         if (drawable->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::WAITING) {
769             drawable->SetRenderCachePriority(NodePriorityType::SUB_HIGH_PRIORITY);
770         }
771         sortedSubThreadNodeIds_.emplace_back(id);
772     }
773 }
774 
SortSubThreadNodesPriority()775 void RSUifirstManager::SortSubThreadNodesPriority()
776 {
777     sortedSubThreadNodeIds_.clear();
778     SetNodePriorty(sortedSubThreadNodeIds_, pendingPostNodes_);
779     SetNodePriorty(sortedSubThreadNodeIds_, pendingPostCardNodes_);
780 
781     sortedSubThreadNodeIds_.sort([this](const auto& first, const auto& second) -> bool {
782         auto drawable1 = GetSurfaceDrawableByID(first);
783         auto drawable2 = GetSurfaceDrawableByID(second);
784         if (drawable1 == nullptr || drawable2 == nullptr) {
785             ROSEN_LOGE("RSUifirstManager::SortSubThreadNodesPriority sort nullptr found in pendingPostNodes_, "
786                 "this should not happen");
787             return false;
788         }
789         auto surfaceParams1 = static_cast<RSSurfaceRenderParams*>(drawable1->GetRenderParams().get());
790         if (!surfaceParams1) {
791             RS_LOGE("RSSurfaceRenderNodeDrawable::sortsubthread params1 is nullptr");
792             return false;
793         }
794         auto surfaceParams2 = static_cast<RSSurfaceRenderParams*>(drawable2->GetRenderParams().get());
795         if (!surfaceParams2) {
796             RS_LOGE("RSSurfaceRenderNodeDrawable::sortsubthread params2 is nullptr");
797             return false;
798         }
799         if (drawable1->GetRenderCachePriority() == drawable2->GetRenderCachePriority()) {
800             return surfaceParams2->GetPositionZ() < surfaceParams1->GetPositionZ();
801         } else {
802             return drawable1->GetRenderCachePriority() < drawable2->GetRenderCachePriority();
803         }
804     });
805 }
806 
807 // post in drawframe sync time
PostUifistSubTasks()808 void RSUifirstManager::PostUifistSubTasks()
809 {
810     // if screen is power-off, uifirst sub thread can be suspended.
811     if (RSUniRenderUtil::CheckRenderSkipIfScreenOff()) {
812         return;
813     }
814     PurgePendingPostNodes();
815     SortSubThreadNodesPriority();
816     if (sortedSubThreadNodeIds_.size() > 0) {
817         for (auto& id : sortedSubThreadNodeIds_) {
818             PostSubTask(id);
819         }
820         pendingPostNodes_.clear();
821         pendingPostCardNodes_.clear();
822         sortedSubThreadNodeIds_.clear();
823     } else {
824         ClearSubthreadRes();
825     }
826     UifirstCurStateClear();
827 }
828 
IsInLeashWindowTree(RSSurfaceRenderNode & node,NodeId instanceRootId)829 bool RSUifirstManager::IsInLeashWindowTree(RSSurfaceRenderNode& node, NodeId instanceRootId)
830 {
831     if (node.GetInstanceRootNodeId() == instanceRootId) {
832         return true;
833     }
834     if (!node.IsLeashWindow()) {
835         return false;
836     }
837     for (auto& child : *(node.GetChildren())) {
838         if (!child) {
839             continue;
840         }
841         auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
842         if (!surfaceChild) {
843             continue;
844         }
845         if (surfaceChild->GetInstanceRootNodeId() == instanceRootId) {
846             return true;
847         }
848     }
849     return false;
850 }
851 
LeashWindowContainMainWindow(RSSurfaceRenderNode & node)852 static inline bool LeashWindowContainMainWindow(RSSurfaceRenderNode& node)
853 {
854     if (node.IsLeashWindow() && node.HasSubSurfaceNodes()) {
855         return true;
856     }
857     return false;
858 }
859 
AddPendingPostNode(NodeId id,std::shared_ptr<RSSurfaceRenderNode> & node,MultiThreadCacheType currentFrameCacheType)860 void RSUifirstManager::AddPendingPostNode(NodeId id, std::shared_ptr<RSSurfaceRenderNode>& node,
861     MultiThreadCacheType currentFrameCacheType)
862 {
863     if (id == INVALID_NODEID || !node) {
864         return;
865     }
866 
867     // process for uifirst node
868     UpdateChildrenDirtyRect(*node);
869     node->SetHwcChildrenDisabledStateByUifirst();
870     node->AddToPendingSyncList();
871 
872     if (currentFrameCacheType == MultiThreadCacheType::LEASH_WINDOW ||
873         currentFrameCacheType == MultiThreadCacheType::NONFOCUS_WINDOW) {
874         if (isRecentTaskScene_.load() && !node->IsNodeToBeCaptured() &&
875             currentFrameCacheType == MultiThreadCacheType::LEASH_WINDOW) {
876             node->SetIsNodeToBeCaptured(true);
877         } else if (!isRecentTaskScene_.load()) {
878             node->SetIsNodeToBeCaptured(false);
879         }
880         // delete card node in leashwindow tree
881         for (auto it = pendingPostCardNodes_.begin(); it != pendingPostCardNodes_.end();) {
882             auto surfaceNode = it->second;
883             if (surfaceNode && IsInLeashWindowTree(*node, surfaceNode->GetInstanceRootNodeId())) {
884                 DisableUifirstNode(*surfaceNode);
885                 it = pendingPostCardNodes_.erase(it);
886             } else {
887                 it++;
888             }
889         }
890         pendingPostNodes_[id] = node;
891     } else if (currentFrameCacheType == MultiThreadCacheType::ARKTS_CARD) {
892         pendingPostCardNodes_[id] = node;
893     }
894 
895     pendingResetNodes_.erase(id); // enable uifirst when waiting for reset
896 }
897 
LeashWindowContainMainWindowAndStarting(RSSurfaceRenderNode & node)898 NodeId RSUifirstManager::LeashWindowContainMainWindowAndStarting(RSSurfaceRenderNode& node)
899 {
900     if (!node.IsLeashWindow()) {
901         return INVALID_NODEID;
902     }
903     int mainwindowNum = 0;
904     int canvasNodeNum = 0;
905     bool support = true;
906     std::shared_ptr<RSRenderNode> startingWindow = nullptr;
907     for (auto& child : *(node.GetSortedChildren())) {
908         if (!child) {
909             continue;
910         }
911         RS_TRACE_NAME_FMT("nID:%" PRIu64" , nType:%d, support:%d, canvasNodeNum:%d, mainwindowNum:%d",
912             child->GetId(), static_cast<int>(child->GetType()), support, canvasNodeNum, mainwindowNum);
913         auto canvasChild = child->ReinterpretCastTo<RSCanvasRenderNode>();
914         if (canvasChild && canvasChild->GetChildrenCount() == 0 && mainwindowNum > 0) {
915             canvasNodeNum++;
916             startingWindow = canvasChild;
917             continue;
918         }
919         auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
920         if (surfaceChild && surfaceChild->IsMainWindowType() && canvasNodeNum == 0) {
921             mainwindowNum++;
922             continue;
923         }
924         support = false;
925     }
926     RS_TRACE_NAME_FMT("uifirst_node support:%d, canvasNodeNum:%d, mainwindowNum:%d, startingWindow:%d",
927         support, canvasNodeNum, mainwindowNum, startingWindow != nullptr);
928     if (support && canvasNodeNum == 1 && mainwindowNum > 0 && startingWindow) { // starting window & appwindow
929         startingWindow->SetStartingWindowFlag(true);
930         return startingWindow->GetId();
931     } else {
932         return INVALID_NODEID;
933     }
934 }
935 
AddPendingResetNode(NodeId id,std::shared_ptr<RSSurfaceRenderNode> & node)936 void RSUifirstManager::AddPendingResetNode(NodeId id, std::shared_ptr<RSSurfaceRenderNode>& node)
937 {
938     if (id == INVALID_NODEID) {
939         return;
940     }
941     pendingResetNodes_[id] = node;
942 }
943 
GetNodeStatus(NodeId id)944 CacheProcessStatus RSUifirstManager::GetNodeStatus(NodeId id)
945 {
946     auto drawable = GetSurfaceDrawableByID(id);
947     if (drawable) {
948         return drawable->GetCacheSurfaceProcessedStatus();
949     }
950     return CacheProcessStatus::UNKNOWN;
951 }
952 
UpdateCompletedSurface(NodeId id)953 void RSUifirstManager::UpdateCompletedSurface(NodeId id)
954 {
955     auto drawable = GetSurfaceDrawableByID(id);
956     if (drawable) {
957         drawable->UpdateCompletedCacheSurface();
958     }
959 }
960 
961 // add&clear in render
AddReuseNode(NodeId id)962 void RSUifirstManager::AddReuseNode(NodeId id)
963 {
964     if (id == INVALID_NODEID) {
965         return;
966     }
967     reuseNodes_.insert(id);
968 }
969 
OnProcessEventResponse(DataBaseRs & info)970 void RSUifirstManager::OnProcessEventResponse(DataBaseRs& info)
971 {
972     RS_OPTIONAL_TRACE_NAME_FMT("uifirst uniqueId:%" PRId64", appPid:%" PRId32", sceneId:%s",
973         info.uniqueId, info.appPid, info.sceneId.c_str());
974     EventInfo eventInfo = {GetCurSysTime(), 0, info.uniqueId, info.appPid, info.sceneId, {}};
975     std::lock_guard<std::mutex> lock(globalFrameEventMutex_);
976     for (auto it = globalFrameEvent_.begin(); it != globalFrameEvent_.end(); it++) {
977         it->disableNodes.clear();
978     }
979     globalFrameEvent_.push_back(std::move(eventInfo));
980     currentFrameCanSkipFirstWait_ = EventsCanSkipFirstWait(globalFrameEvent_);
981 }
982 
OnProcessEventComplete(DataBaseRs & info)983 void RSUifirstManager::OnProcessEventComplete(DataBaseRs& info)
984 {
985     int64_t curSysTime = GetCurSysTime();
986     std::lock_guard<std::mutex> lock(globalFrameEventMutex_);
987     for (auto it = globalFrameEvent_.begin(); it != globalFrameEvent_.end(); it++) {
988         if (it->uniqueId == info.uniqueId && it->sceneId == info.sceneId) {
989             // delay delete for animation continue
990             it->stopTime = curSysTime;
991             break;
992         }
993     }
994 }
995 
EventDisableLeashWindowCache(NodeId id,EventInfo & info)996 void RSUifirstManager::EventDisableLeashWindowCache(NodeId id, EventInfo& info)
997 {
998     std::lock_guard<std::mutex> lock(globalFrameEventMutex_);
999     for (auto it = globalFrameEvent_.begin(); it != globalFrameEvent_.end(); it++) {
1000         if (it->uniqueId == info.uniqueId && it->sceneId == info.sceneId) {
1001             it->disableNodes.insert(id);
1002             break;
1003         }
1004     }
1005 }
1006 
PrepareCurrentFrameEvent()1007 void RSUifirstManager::PrepareCurrentFrameEvent()
1008 {
1009     int64_t curSysTime = GetCurSysTime();
1010     currentFrameEvent_.clear();
1011     if (!mainThread_ || entryViewNodeId_ == INVALID_NODEID || negativeScreenNodeId_ == INVALID_NODEID) {
1012         mainThread_ = RSMainThread::Instance();
1013         if (mainThread_) {
1014             entryViewNodeId_ = mainThread_->GetContext().GetNodeMap().GetEntryViewNodeId();
1015             negativeScreenNodeId_ = mainThread_->GetContext().GetNodeMap().GetNegativeScreenNodeId();
1016             scbPid_ = ExtractPid(entryViewNodeId_);
1017         }
1018     }
1019     {
1020         std::lock_guard<std::mutex> lock(globalFrameEventMutex_);
1021         for (auto it = globalFrameEvent_.begin(); it != globalFrameEvent_.end();) {
1022             if (it->stopTime != 0 &&
1023                 ((curSysTime > it->stopTime) && (curSysTime - it->stopTime) > EVENT_STOP_TIMEOUT)) {
1024                 it = globalFrameEvent_.erase(it);
1025                 continue;
1026             }
1027 
1028             if ((curSysTime > it->startTime) && (curSysTime - it->startTime) > EVENT_START_TIMEOUT) {
1029                 it = globalFrameEvent_.erase(it);
1030                 continue;
1031             }
1032             it++;
1033         }
1034         if (globalFrameEvent_.empty()) {
1035             currentFrameCanSkipFirstWait_ = false;
1036             return;
1037         }
1038         // copy global to current, judge leashwindow stop
1039         currentFrameEvent_.assign(globalFrameEvent_.begin(), globalFrameEvent_.end());
1040     }
1041     currentFrameCanSkipFirstWait_ = EventsCanSkipFirstWait(currentFrameEvent_);
1042 }
1043 
OnProcessAnimateScene(SystemAnimatedScenes systemAnimatedScene)1044 void RSUifirstManager::OnProcessAnimateScene(SystemAnimatedScenes systemAnimatedScene)
1045 {
1046     RS_TRACE_NAME_FMT("RSUifirstManager::OnProcessAnimateScene systemAnimatedScene:%d", systemAnimatedScene);
1047     if ((systemAnimatedScene == SystemAnimatedScenes::ENTER_RECENTS) && !isRecentTaskScene_.load()) {
1048         isRecentTaskScene_ = true;
1049     } else if ((systemAnimatedScene == SystemAnimatedScenes::EXIT_RECENTS) && isRecentTaskScene_.load()) {
1050         isRecentTaskScene_ = false;
1051     }
1052 }
1053 
NodeIsInCardWhiteList(RSRenderNode & node)1054 bool RSUifirstManager::NodeIsInCardWhiteList(RSRenderNode& node)
1055 {
1056     if ((entryViewNodeId_ != INVALID_NODEID) && (negativeScreenNodeId_ != INVALID_NODEID)) {
1057         auto instanceRootId = node.GetInstanceRootNodeId();
1058         if (instanceRootId == entryViewNodeId_ || instanceRootId == negativeScreenNodeId_) {
1059             return true;
1060         }
1061     }
1062     return false;
1063 }
1064 
IsCardSkipFirstWaitScene(std::string & scene,int32_t appPid)1065 bool RSUifirstManager::IsCardSkipFirstWaitScene(std::string& scene, int32_t appPid)
1066 {
1067     if (appPid != scbPid_) {
1068         return false;
1069     }
1070     for (auto& item : cardCanSkipFirstWaitScene_) {
1071         if ((scene.find(item) != std::string::npos)) {
1072             return true;
1073         }
1074     }
1075     return false;
1076 }
1077 
EventsCanSkipFirstWait(std::vector<EventInfo> & events)1078 bool RSUifirstManager::EventsCanSkipFirstWait(std::vector<EventInfo>& events)
1079 {
1080     if (events.empty()) {
1081         return false;
1082     }
1083     if (isCurrentFrameHasCardNodeReCreate_) {
1084         RS_OPTIONAL_TRACE_NAME("uifirst current frame can't skip wait");
1085         return false;
1086     }
1087     for (auto& item : events) {
1088         if (IsCardSkipFirstWaitScene(item.sceneId, item.appPid)) {
1089             return true;
1090         }
1091     }
1092     return false;
1093 }
1094 
IsScreenshotAnimation()1095 bool RSUifirstManager::IsScreenshotAnimation()
1096 {
1097     for (auto& it : currentFrameEvent_) {
1098         if (std::find(screenshotAnimation_.begin(), screenshotAnimation_.end(), it.sceneId) !=
1099             screenshotAnimation_.end()) {
1100             return true;
1101         }
1102     }
1103     return false;
1104 }
1105 
CheckIfAppWindowHasAnimation(RSSurfaceRenderNode & node)1106 bool RSUifirstManager::CheckIfAppWindowHasAnimation(RSSurfaceRenderNode& node)
1107 {
1108     if (currentFrameEvent_.empty()) {
1109         return false;
1110     }
1111 
1112     std::set<int32_t> appPids;
1113     if (node.IsAppWindow()) {
1114         appPids.insert(ExtractPid(node.GetId()));
1115     } else if (node.IsLeashWindow()) {
1116         for (auto& child : *(node.GetChildren())) {
1117             if (!child) {
1118                 continue;
1119             }
1120             auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
1121             if (!surfaceChild) {
1122                 continue;
1123             }
1124             if (surfaceChild->IsAppWindow()) {
1125                 appPids.insert(ExtractPid(surfaceChild->GetId()));
1126             }
1127         }
1128     }
1129 
1130     if (appPids.empty()) {
1131         return false;
1132     }
1133     for (auto& item : currentFrameEvent_) {
1134         if (item.disableNodes.count(node.GetId())) {
1135             return true;
1136         }
1137         if (appPids.count(item.appPid) && (node.GetUifirstStartTime() > 0) &&
1138             (node.GetUifirstStartTime() < (item.startTime - EVENT_DISABLE_UIFIRST_GAP)) &&
1139             (item.sceneId.find(EVENT_DISABLE_UIFIRST) != std::string::npos)) {
1140             EventDisableLeashWindowCache(node.GetId(), item);
1141             return true; // app has animation, stop leashwindow uifirst
1142         }
1143     }
1144     return false;
1145 }
1146 
IsArkTsCardCache(RSSurfaceRenderNode & node,bool animation)1147 bool RSUifirstManager::IsArkTsCardCache(RSSurfaceRenderNode& node, bool animation) // maybe canvas node ?
1148 {
1149     auto baseNode = node.GetAncestorDisplayNode().lock();
1150     if (!baseNode) {
1151         RS_LOGE("surfaceNode GetAncestorDisplayNode().lock() return nullptr");
1152         return false;
1153     }
1154     auto curDisplayNode = baseNode->ReinterpretCastTo<RSDisplayRenderNode>();
1155     if (curDisplayNode == nullptr) {
1156         RS_LOGE("surfaceNode GetAncestorDisplayNode().lock() return nullptr");
1157         return false;
1158     }
1159     if (RSLuminanceControl::Get().IsHdrOn(curDisplayNode->GetScreenId())) {
1160         return false;
1161     }
1162     bool flag = ((RSMainThread::Instance()->GetDeviceType() == DeviceType::PHONE) &&
1163         (node.GetSurfaceNodeType() == RSSurfaceNodeType::ABILITY_COMPONENT_NODE) &&
1164         RSUifirstManager::Instance().NodeIsInCardWhiteList(node) &&
1165         (node.ShouldPaint()) && (node.GetName().find(ARKTSCARDNODE_NAME) != std::string::npos));
1166     if (flag) { // Planning: mark by arkui or app
1167         return true;
1168     }
1169     return false;
1170 }
1171 
1172 // animation first, may reuse last image cache
IsLeashWindowCache(RSSurfaceRenderNode & node,bool animation)1173 bool RSUifirstManager::IsLeashWindowCache(RSSurfaceRenderNode& node, bool animation)
1174 {
1175     if (RSUifirstManager::Instance().GetUseDmaBuffer(node.GetName())) {
1176         return true;
1177     }
1178     bool isNeedAssignToSubThread = false;
1179     if ((RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) ||
1180         (node.GetFirstLevelNodeId() != node.GetId()) ||
1181         (RSUifirstManager::Instance().NodeIsInCardWhiteList(node)) ||
1182         (RSUifirstManager::Instance().CheckIfAppWindowHasAnimation(node))) {
1183         return false;
1184     }
1185     if (node.IsLeashWindow()) {
1186         if (RSUifirstManager::Instance().IsRecentTaskScene()) {
1187             isNeedAssignToSubThread = node.IsScale() && LeashWindowContainMainWindow(node);
1188         } else {
1189             isNeedAssignToSubThread = animation;
1190         }
1191         // 1: Planning: support multi appwindows
1192         isNeedAssignToSubThread = (isNeedAssignToSubThread || ROSEN_EQ(node.GetGlobalAlpha(), 0.0f) ||
1193                 node.GetForceUIFirst()) && !node.HasFilter() && !RSUifirstManager::Instance().rotationChanged_;
1194     }
1195 
1196     bool needFilterSCB = node.GetSurfaceWindowType() == SurfaceWindowType::SYSTEM_SCB_WINDOW;
1197     if (needFilterSCB || node.IsSelfDrawingType()) {
1198         RS_TRACE_NAME_FMT("IsLeashWindowCache: needFilterSCB [%d]", needFilterSCB);
1199         return false;
1200     }
1201     RS_TRACE_NAME_FMT("IsLeashWindowCache: toSubThread[%d] IsScale[%d]"
1202         " filter:[%d] rotate[%d] captured[%d] snapshot[%d]",
1203         isNeedAssignToSubThread, node.IsScale(),
1204         node.HasFilter(), RSUifirstManager::Instance().rotationChanged_, node.IsNodeToBeCaptured(),
1205         RSUniRenderThread::GetCaptureParam().isSnapshot_);
1206     return isNeedAssignToSubThread;
1207 }
1208 
1209 // NonFocusWindow, may reuse last image cache
IsNonFocusWindowCache(RSSurfaceRenderNode & node,bool animation)1210 bool RSUifirstManager::IsNonFocusWindowCache(RSSurfaceRenderNode& node, bool animation)
1211 {
1212     bool isDisplayRotation = RSUifirstManager::Instance().rotationChanged_;
1213     if ((RSMainThread::Instance()->GetDeviceType() != DeviceType::PC) ||
1214         (node.GetFirstLevelNodeId() != node.GetId()) ||
1215         (RSUifirstManager::Instance().NodeIsInCardWhiteList(node))) {
1216         return false;
1217     }
1218 
1219     std::string surfaceName = node.GetName();
1220     bool needFilterSCB = node.GetSurfaceWindowType() == SurfaceWindowType::SYSTEM_SCB_WINDOW;
1221     if (!node.GetForceUIFirst() && (needFilterSCB || node.IsSelfDrawingType())) {
1222         return false;
1223     }
1224     if ((node.IsFocusedNode(RSMainThread::Instance()->GetFocusNodeId()) ||
1225         node.IsFocusedNode(RSMainThread::Instance()->GetFocusLeashWindowId())) &&
1226         node.GetHasSharedTransitionNode()) {
1227         return false;
1228     }
1229     return node.QuerySubAssignable(isDisplayRotation);
1230 }
1231 
1232 
ForceUpdateUifirstNodes(RSSurfaceRenderNode & node)1233 bool RSUifirstManager::ForceUpdateUifirstNodes(RSSurfaceRenderNode& node)
1234 {
1235     if (node.isForceFlag_ && node.IsLeashWindow()) {
1236         RS_OPTIONAL_TRACE_NAME_FMT("ForceUpdateUifirstNodes: isUifirstEnable: %d", node.isUifirstEnable_);
1237         if (!node.isUifirstEnable_) {
1238             UifirstStateChange(node, MultiThreadCacheType::NONE);
1239             return true;
1240         }
1241         UifirstStateChange(node, MultiThreadCacheType::LEASH_WINDOW);
1242         return true;
1243     }
1244     return false;
1245 }
1246 
UpdateUifirstNodes(RSSurfaceRenderNode & node,bool ancestorNodeHasAnimation)1247 void RSUifirstManager::UpdateUifirstNodes(RSSurfaceRenderNode& node, bool ancestorNodeHasAnimation)
1248 {
1249     RS_TRACE_NAME_FMT("UpdateUifirstNodes: Id[%llu] name[%s] FLId[%llu] Ani[%d] Support[%d] isUiFirstOn[%d],"
1250         " isForceFlag:[%d]",
1251         node.GetId(), node.GetName().c_str(), node.GetFirstLevelNodeId(),
1252         ancestorNodeHasAnimation, node.GetUifirstSupportFlag(), isUiFirstOn_, node.isForceFlag_);
1253     if (ForceUpdateUifirstNodes(node)) {
1254         return;
1255     }
1256     if (!isUiFirstOn_ || !node.GetUifirstSupportFlag()) {
1257         UifirstStateChange(node, MultiThreadCacheType::NONE);
1258         if (!node.isUifirstNode_) {
1259             node.isUifirstDelay_++;
1260             if (node.isUifirstDelay_ > EVENT_STOP_TIMEOUT) {
1261                 node.isUifirstNode_ = true;
1262             }
1263         }
1264         return;
1265     }
1266     if (RSUifirstManager::IsLeashWindowCache(node, ancestorNodeHasAnimation)) {
1267         UifirstStateChange(node, MultiThreadCacheType::LEASH_WINDOW);
1268         return;
1269     }
1270     if (RSUifirstManager::IsNonFocusWindowCache(node, ancestorNodeHasAnimation)) {
1271         UifirstStateChange(node, MultiThreadCacheType::NONFOCUS_WINDOW);
1272         return;
1273     }
1274     if (RSUifirstManager::IsArkTsCardCache(node, ancestorNodeHasAnimation)) {
1275         UifirstStateChange(node, MultiThreadCacheType::ARKTS_CARD);
1276         return;
1277     }
1278     UifirstStateChange(node, MultiThreadCacheType::NONE);
1279 }
1280 
UpdateUIFirstNodeUseDma(RSSurfaceRenderNode & node,const std::vector<RectI> & rects)1281 void RSUifirstManager::UpdateUIFirstNodeUseDma(RSSurfaceRenderNode& node, const std::vector<RectI>& rects)
1282 {
1283     if (!GetUseDmaBuffer(node.GetName())) {
1284         return;
1285     }
1286     bool intersect = false;
1287     for (auto& rect : rects) {
1288         if (rect.Intersect(node.GetAbsDrawRect())) {
1289             intersect = true;
1290             break;
1291         }
1292     }
1293     node.SetHardwareForcedDisabledState(intersect);
1294 
1295     Drawing::Matrix totalMatrix;
1296     float alpha = 1.f;
1297     auto surfaceNode = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1298     RSUniRenderUtil::AccumulateMatrixAndAlpha(surfaceNode, totalMatrix, alpha);
1299     node.SetTotalMatrix(totalMatrix);
1300 }
1301 
UifirstStateChange(RSSurfaceRenderNode & node,MultiThreadCacheType currentFrameCacheType)1302 void RSUifirstManager::UifirstStateChange(RSSurfaceRenderNode& node, MultiThreadCacheType currentFrameCacheType)
1303 {
1304     auto lastFrameCacheType = node.GetLastFrameUifirstFlag();
1305     if ((lastFrameCacheType != MultiThreadCacheType::NONE) && (lastFrameCacheType != currentFrameCacheType)) {
1306         // not support cache type switch, just disable multithread cache
1307         currentFrameCacheType = MultiThreadCacheType::NONE;
1308     }
1309     if (lastFrameCacheType == MultiThreadCacheType::NONE) { // likely branch: last is disable
1310         if (currentFrameCacheType != MultiThreadCacheType::NONE) { // switch: disable -> enable
1311             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.shared_from_this());
1312             RS_OPTIONAL_TRACE_NAME_FMT("UIFirst_switch disable -> enable %" PRIu64"", node.GetId());
1313             SetUifirstNodeEnableParam(node, currentFrameCacheType);
1314             if (currentFrameCacheType == MultiThreadCacheType::ARKTS_CARD) { // now only update ArkTSCardNode
1315                 node.UpdateTreeUifirstRootNodeId(node.GetId());
1316             }
1317             if (currentFrameCacheType == MultiThreadCacheType::LEASH_WINDOW) {
1318                 node.SetUifirstUseStarting(LeashWindowContainMainWindowAndStarting(*surfaceNode));
1319                 NotifyUIStartingWindow(node.GetId(), true);
1320             }
1321             auto func = &RSUifirstManager::ProcessTreeStateChange;
1322             node.RegisterTreeStateChangeCallback(func);
1323             node.SetUifirstStartTime(GetCurSysTime());
1324             AddPendingPostNode(node.GetId(), surfaceNode, currentFrameCacheType); // clear pending reset status
1325             AddCardNodes(node.GetId(), currentFrameCacheType);
1326         } else { // keep disable
1327             RS_OPTIONAL_TRACE_NAME_FMT("UIFirst_keep disable  %" PRIu64"", node.GetId());
1328         }
1329     } else { // last is enable
1330         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.shared_from_this());
1331         if (currentFrameCacheType != MultiThreadCacheType::NONE) { // keep enable
1332             RS_OPTIONAL_TRACE_NAME_FMT("UIFirst_keep enable  %" PRIu64"", node.GetId());
1333             AddPendingPostNode(node.GetId(), surfaceNode, currentFrameCacheType);
1334         } else { // switch: enable -> disable
1335             RS_OPTIONAL_TRACE_NAME_FMT("UIFirst_switch enable -> disable %" PRIu64"", node.GetId());
1336             node.SetUifirstStartTime(-1); // -1: default start time
1337             NotifyUIStartingWindow(node.GetId(), false);
1338             AddPendingResetNode(node.GetId(), surfaceNode); // set false onsync when task done
1339             RemoveCardNodes(node.GetId());
1340         }
1341     }
1342     node.SetLastFrameUifirstFlag(currentFrameCacheType);
1343 }
1344 
1345 // appwindow will not be traversed in process when cache leashwindow
UpdateChildrenDirtyRect(RSSurfaceRenderNode & node)1346 void RSUifirstManager::UpdateChildrenDirtyRect(RSSurfaceRenderNode& node)
1347 {
1348     RectI rect(0, 0, 0, 0);
1349     if (node.IsLeashWindow()) {
1350         for (auto& child : *(node.GetChildren())) {
1351             if (!child) {
1352                 continue;
1353             }
1354             auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
1355             if (!surfaceChild) {
1356                 continue;
1357             }
1358             if (surfaceChild->IsMainWindowType()) {
1359                 rect = rect.JoinRect(surfaceChild->GetOldDirtyInSurface());
1360                 continue;
1361             }
1362         }
1363     }
1364     node.SetUifirstChildrenDirtyRectParam(rect);
1365 }
1366 
CreateUIFirstLayer(std::shared_ptr<RSProcessor> & processor)1367 void RSUifirstManager::CreateUIFirstLayer(std::shared_ptr<RSProcessor>& processor)
1368 {
1369     if (!processor) {
1370         return;
1371     }
1372     {
1373         std::lock_guard<std::mutex> lock(useDmaBufferMutex_);
1374         if (!useDmaBuffer_) {
1375             return;
1376         }
1377     }
1378     for (auto& drawable : pendingPostDrawables_) {
1379         if (!drawable) {
1380             continue;
1381         }
1382         auto& param = drawable->GetRenderParams();
1383         if (!param) {
1384             continue;
1385         }
1386         auto params = static_cast<RSSurfaceRenderParams*>(param.get());
1387         if (params && params->GetHardwareEnabled()) {
1388             processor->CreateUIFirstLayer(*drawable, *params);
1389         }
1390     }
1391 }
1392 
UpdateUIFirstLayerInfo(const ScreenInfo & screenInfo,float zOrder)1393 void RSUifirstManager::UpdateUIFirstLayerInfo(const ScreenInfo& screenInfo, float zOrder)
1394 {
1395     {
1396         std::lock_guard<std::mutex> lock(useDmaBufferMutex_);
1397         if (!useDmaBuffer_) {
1398             return;
1399         }
1400     }
1401     for (const auto& iter : pendingPostNodes_) {
1402         auto& node = iter.second;
1403         if (node && GetUseDmaBuffer(node->GetName())) {
1404             node->GetRSSurfaceHandler()->SetGlobalZOrder(node->IsHardwareForcedDisabled() ? -1.f : zOrder++);
1405             auto transform = RSUniRenderUtil::GetLayerTransform(*node, screenInfo);
1406             node->UpdateHwcNodeLayerInfo(transform);
1407             node->SetIsLastFrameHwcEnabled(!node->IsHardwareForcedDisabled());
1408         }
1409     }
1410 }
1411 
ProcessTreeStateChange(RSSurfaceRenderNode & node)1412 void RSUifirstManager::ProcessTreeStateChange(RSSurfaceRenderNode& node)
1413 {
1414     RSUifirstManager::Instance().CheckCurrentFrameHasCardNodeReCreate(node);
1415     // Planning: do not clear complete image for card
1416     if (node.IsOnTheTree()) {
1417         return;
1418     }
1419     RSUifirstManager::Instance().DisableUifirstNode(node);
1420     RSUifirstManager::Instance().ForceClearSubthreadRes();
1421     RSUifirstManager::Instance().RemoveCardNodes(node.GetId());
1422 }
1423 
DisableUifirstNode(RSSurfaceRenderNode & node)1424 void RSUifirstManager::DisableUifirstNode(RSSurfaceRenderNode& node)
1425 {
1426     RS_TRACE_NAME_FMT("DisableUifirstNode");
1427     UifirstStateChange(node, MultiThreadCacheType::NONE);
1428 }
1429 
AddCapturedNodes(NodeId id)1430 void RSUifirstManager::AddCapturedNodes(NodeId id)
1431 {
1432     capturedNodes_.push_back(id);
1433 }
1434 
SetUseDmaBuffer(bool val)1435 void RSUifirstManager::SetUseDmaBuffer(bool val)
1436 {
1437     std::lock_guard<std::mutex> lock(useDmaBufferMutex_);
1438 #if defined(RS_ENABLE_VK)
1439     useDmaBuffer_ = val && RSSystemParameters::GetUIFirstDmaBufferEnabled() &&
1440         RSSystemProperties::IsPhoneType() && RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN;
1441 #else
1442     useDmaBuffer_ = false;
1443 #endif
1444 }
1445 
GetUseDmaBuffer(const std::string & name)1446 bool RSUifirstManager::GetUseDmaBuffer(const std::string& name)
1447 {
1448     std::lock_guard<std::mutex> lock(useDmaBufferMutex_);
1449     return useDmaBuffer_ && name.find("ScreenShotWindow") != std::string::npos;
1450 }
1451 
ResetCurrentFrameDeletedCardNodes()1452 void RSUifirstManager::ResetCurrentFrameDeletedCardNodes()
1453 {
1454     currentFrameDeletedCardNodes_.clear();
1455     isCurrentFrameHasCardNodeReCreate_ = false;
1456 }
1457 
CheckCurrentFrameHasCardNodeReCreate(const RSSurfaceRenderNode & node)1458 void RSUifirstManager::CheckCurrentFrameHasCardNodeReCreate(const RSSurfaceRenderNode& node)
1459 {
1460     if (node.GetSurfaceNodeType() != RSSurfaceNodeType::ABILITY_COMPONENT_NODE ||
1461         node.GetName().find(ARKTSCARDNODE_NAME) == std::string::npos) {
1462         return;
1463     }
1464     if (!node.IsOnTheTree()) {
1465         currentFrameDeletedCardNodes_.emplace_back(node.GetId());
1466     } else if (std::find(currentFrameDeletedCardNodes_.begin(), currentFrameDeletedCardNodes_.end(),
1467         node.GetId()) != currentFrameDeletedCardNodes_.end()) {
1468         isCurrentFrameHasCardNodeReCreate_ = true;
1469     }
1470 }
1471 
CheckMatchAndWaitNotify(const RSRenderParams & params,bool checkMatch)1472 bool RSUiFirstProcessStateCheckerHelper::CheckMatchAndWaitNotify(const RSRenderParams& params, bool checkMatch)
1473 {
1474     if (checkMatch && IsCurFirstLevelMatch(params)) {
1475         return true;
1476     }
1477     return CheckAndWaitPreFirstLevelDrawableNotify(params);
1478 }
1479 
CheckAndWaitPreFirstLevelDrawableNotify(const RSRenderParams & params)1480 bool RSUiFirstProcessStateCheckerHelper::CheckAndWaitPreFirstLevelDrawableNotify(const RSRenderParams& params)
1481 {
1482     auto firstLevelNodeId = params.GetFirstLevelNodeId();
1483     auto uifirstRootNodeId = params.GetUifirstRootNodeId();
1484     auto rootId = uifirstRootNodeId != INVALID_NODEID ? uifirstRootNodeId : firstLevelNodeId;
1485     if (rootId == INVALID_NODEID) {
1486         /* uifirst will not draw with no firstlevel node, and there's no need to check and wait for uifirst onDraw */
1487         RS_LOGW("uifirst node %{public}" PRIu64 " uifirstrootNodeId is INVALID_NODEID", params.GetId());
1488         return true;
1489     }
1490 
1491     auto uifirstRootNodeDrawable = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(rootId);
1492     if (!uifirstRootNodeDrawable) {
1493         // drawable may release when node off tree
1494         // uifirst will not draw with null uifirstRootNodeDrawable
1495         RS_LOGW("uifirstnode %{public}" PRIu64 " uifirstroot %{public}" PRIu64 " nullptr", params.GetId(), rootId);
1496         return true;
1497     }
1498 
1499     if (UNLIKELY(uifirstRootNodeDrawable->GetNodeType() != RSRenderNodeType::SURFACE_NODE)) {
1500         RS_LOGE("uifirst invalid uifirstrootNodeId %{public}" PRIu64, rootId);
1501         return false;
1502     }
1503     auto uifirstRootSurfaceNodeDrawable =
1504         std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(uifirstRootNodeDrawable);
1505 
1506     RS_TRACE_NAME_FMT("CheckAndWaitPreFirstLevelDrawableNotify %" PRIu64 " wait for %" PRIu64 "",
1507         params.GetId(), uifirstRootSurfaceNodeDrawable->GetId());
1508 
1509     static constexpr auto TIME_OUT = std::chrono::milliseconds(32); // 32ms
1510     auto pred = [uifirstRootSurfaceNodeDrawable] {
1511         auto curState = uifirstRootSurfaceNodeDrawable->GetCacheSurfaceProcessedStatus();
1512         return curState == CacheProcessStatus::DONE || curState == CacheProcessStatus::UNKNOWN ||
1513             curState == CacheProcessStatus::SKIPPED;
1514     };
1515     std::unique_lock<std::mutex> lock(notifyMutex_);
1516     notifyCv_.wait_for(lock, TIME_OUT, pred);
1517     return pred();
1518 }
1519 
IsCurFirstLevelMatch(const RSRenderParams & params)1520 bool RSUiFirstProcessStateCheckerHelper::IsCurFirstLevelMatch(const RSRenderParams& params)
1521 {
1522     auto uifirstRootNodeId = params.GetUifirstRootNodeId();
1523     auto firstLevelNodeId = params.GetFirstLevelNodeId();
1524 
1525     RS_OPTIONAL_TRACE_NAME_FMT("RSUiFirstProcessStateCheckerHelper IsCurFirstLevelMatch In node[%"
1526         PRIu64 "  %" PRIu64"] cur[%" PRIu64 "  %" PRIu64 "] in nodeId[%" PRIu64 "]",
1527         uifirstRootNodeId, firstLevelNodeId, curUifirstRootNodeId_, curFirstLevelNodeId_, params.GetId());
1528 
1529     if (curUifirstRootNodeId_ == INVALID_NODEID && curFirstLevelNodeId_ == INVALID_NODEID) {
1530         // should draw because uifirst may not inited
1531         return true;
1532     }
1533     auto uiFirstCheckRet = uifirstRootNodeId == curUifirstRootNodeId_ && curUifirstRootNodeId_ != INVALID_NODEID;
1534     auto firstLevelCheckRet = firstLevelNodeId == curFirstLevelNodeId_ && curFirstLevelNodeId_ != INVALID_NODEID;
1535     if (uiFirstCheckRet || firstLevelCheckRet) {
1536         return true;
1537     }
1538     return false;
1539 }
1540 
IsSubTreeNeedPrepareForSnapshot(RSSurfaceRenderNode & node)1541 bool RSUifirstManager::IsSubTreeNeedPrepareForSnapshot(RSSurfaceRenderNode& node)
1542 {
1543     return RSUifirstManager::Instance().IsRecentTaskScene() &&
1544         (node.IsFocusedNode(RSMainThread::Instance()->GetFocusLeashWindowId()) ||
1545         node.IsFocusedNode(RSMainThread::Instance()->GetFocusNodeId()));
1546 }
1547 } // namespace Rosen
1548 } // namespace OHOS
1549