• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "common/rs_optional_trace.h"
17 #include "drawable/rs_screen_render_node_drawable.h"
18 #include "drawable/rs_surface_render_node_drawable.h"
19 #include "feature/hdr/rs_hdr_util.h"
20 #include "feature/hetero_hdr/rs_hetero_hdr_util.h"
21 #include "feature/hetero_hdr/rs_hdr_manager.h"
22 #include "feature/uifirst/rs_uifirst_manager.h"
23 #include "hetero_hdr/rs_hdr_pattern_manager.h"
24 #include "metadata_helper.h"
25 #include "pipeline/render_thread/rs_uni_render_util.h"
26 #include "pipeline/rs_canvas_render_node.h"
27 #include "platform/common/rs_log.h"
28 #include "rs_trace.h"
29 
30 namespace OHOS {
31 namespace Rosen {
Instance()32 RSHdrManager &RSHdrManager::Instance()
33 {
34     static RSHdrManager instance;
35     return instance;
36 }
37 
RSHdrManager()38 RSHdrManager::RSHdrManager()
39 {
40     isHeterogComputingHdrOn_ = RSSystemProperties::GetHeterogComputingHDREnabled();
41     if (!RSHDRPatternManager::Instance().MHCDlOpen()) {
42         RS_LOGE("MHCDlOpen() failed!");
43         isHeterogComputingHdrOn_ = false;
44         return;
45     }
46     if (!RSHDRPatternManager::Instance().MHCGraphPatternInit(GRAPH_NUM)) {
47         RS_LOGE("MHCGraphPatternInit() failed!");
48         isHeterogComputingHdrOn_ = false;
49     }
50 }
51 
RectRound(RectI srcRect)52 RectI RSHdrManager::RectRound(RectI srcRect)
53 {
54     int32_t srcWidth = srcRect.width_ & ~1;
55     int32_t srcHeight = srcRect.height_ & ~1;
56     int32_t srcTop = srcRect.top_ & ~1;
57     int32_t srcLeft = srcRect.left_ & ~1;
58 
59     RectI dstRect = {srcLeft, srcTop, srcWidth, srcHeight};
60     return dstRect;
61 }
62 
EquRect(RectI a,RectI b)63 bool RSHdrManager::EquRect(RectI a, RectI b)
64 {
65     if ((a.top_ != b.top_) || (a.height_ != b.height_) || (a.left_ != b.left_) || (a.width_ != b.width_)) {
66         return false;
67     }
68     return true;
69 }
70 
UpdateHdrNodes(RSSurfaceRenderNode & node,bool isCurrentFrameBufferConsumed)71 void RSHdrManager::UpdateHdrNodes(RSSurfaceRenderNode &node, bool isCurrentFrameBufferConsumed)
72 {
73     if (isHeterogComputingHdrOn_ && node.GetVideoHdrStatus() == HdrStatus::HDR_VIDEO) {
74         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.shared_from_this());
75         pendingPostNodes_[node.GetId()] = surfaceNode;
76         isCurrentFrameBufferConsumedMap_[node.GetId()] = isCurrentFrameBufferConsumed;
77     }
78 }
79 
GetFixDstRectStatus(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable,bool isUifistR,RSSurfaceRenderParams * surfaceParams,RectI & finalDstRect,bool & isFixDstRect)80 void RSHdrManager::GetFixDstRectStatus(
81     std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable,
82     bool isUifistR, RSSurfaceRenderParams *surfaceParams, RectI &finalDstRect, bool &isFixDstRect)
83 {
84     if (surfaceParams == nullptr) {
85         RS_LOGE("surfaceParams is nullptr");
86         return;
87     }
88 
89     auto srcRect = surfaceParams->GetLayerInfo().srcRect;
90     auto dstRect = surfaceParams->GetLayerInfo().dstRect;
91     Drawing::Matrix matrix = surfaceParams->GetLayerInfo().matrix;
92 
93     float ratio = 1.0f;
94     if (float(dstRect.h) * float(srcRect.w) != 0.0f) {
95         ratio = float(srcRect.h) * float(dstRect.w) / (float(dstRect.h) * float(srcRect.w));
96     }
97 
98     bool ratiojudge = (abs(ratio - 1.0) > 0.02);
99     ScreenInfo curScreenInfo = CreateOrGetScreenManager()->QueryScreenInfo(GetScreenIDByDrawable(drawable));
100     int realRotation = RSBaseRenderUtil::RotateEnumToInt(
101         RSBaseRenderUtil::GetRotateTransform(surfaceParams->GetLayerInfo().transformType));
102 
103     Vector2f HpaeBufferSize = (realRotation == ROTATION_90 || realRotation == ROTATION_270)
104                                ? Vector2f(curScreenInfo.height, curScreenInfo.width)
105                                : Vector2f(curScreenInfo.width, curScreenInfo.height);
106     Vector2f boundSize = surfaceParams->GetCacheSize();
107     bool sizejudge = abs(matrix.Get(1)) > HDR_EPSILON || abs(matrix.Get(3)) > HDR_EPSILON;
108     sptr<SurfaceBuffer> srcBuffer = surfaceParams->GetBuffer();
109 
110     if (realRotation == ROTATION_90 || realRotation == ROTATION_270) {
111         boundSize.y_ = HpaeBufferSize.y_;
112         if (srcBuffer->GetSurfaceBufferHeight() > 0) {
113             boundSize.x_ = round(boundSize.y_ * srcBuffer->GetSurfaceBufferWidth() /
114                 srcBuffer->GetSurfaceBufferHeight());
115         }
116         boundSize.x_ = (boundSize.x_ > HpaeBufferSize.x_) ? HpaeBufferSize.x_ : boundSize.x_;
117         sizejudge = true;
118     } else {
119         boundSize.x_ = HpaeBufferSize.x_;
120         if (srcBuffer->GetSurfaceBufferWidth() > 0) {
121             boundSize.x_ = round(boundSize.y_ * srcBuffer->GetSurfaceBufferWidth() /
122                 srcBuffer->GetSurfaceBufferHeight());
123         }
124         boundSize.y_ = round(boundSize.x_ * srcBuffer->GetSurfaceBufferHeight() / srcBuffer->GetSurfaceBufferWidth());
125         boundSize.y_ = (boundSize.y_ > HpaeBufferSize.y_) ? HpaeBufferSize.y_ : boundSize.y_;
126     }
127 
128     finalDstRect.left_ = 0;
129     finalDstRect.top_ = 0;
130     finalDstRect.width_ = boundSize.x_;
131     finalDstRect.height_ = boundSize.y_;
132     isFixDstRect = isUifistR || ratiojudge || sizejudge;
133     if (!isFixDstRect) {
134         finalDstRect.width_ = dstRect.w;
135         finalDstRect.height_ = dstRect.h;
136     }
137     finalDstRect = RectRound(finalDstRect);
138 }
139 
PrepareHapeTask(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> nodeDrawable,uint64_t curFrameId)140 bool RSHdrManager::PrepareHapeTask(
141     std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> nodeDrawable, uint64_t curFrameId)
142 {
143     auto surfaceParams = static_cast<RSSurfaceRenderParams *>(nodeDrawable->GetRenderParams().get());
144     // 1. Hpae Device is ready
145     std::unique_lock<std::mutex> lock(HpaeMtx_);
146     bool ret0 = cond_.wait_for(lock, std::chrono::milliseconds(HPAE_TIMEOUT), [
147                                 this] { return this->destroyedFlag_.load(); });
148     if (ret0 == false) {
149         RS_LOGE("Hpae device is not ready!");
150         return false;
151     }
152     // 2. Request Graph
153     if (!RSHDRPatternManager::Instance().MHCRequestEGraph(curFrameId)) {
154         RS_LOGE("mhc_so MHCRequestEGraph failed. frameId:%{public}" PRIu64 " ", curFrameId);
155         return false;
156     }
157     // 3. Set Current Frame Id
158     bool ret1 = RSHDRPatternManager::Instance().MHCSetCurFrameId(curFrameId);
159     if (ret1 == false) {
160         RS_LOGE("MHCSetCurFrameId failed!");
161         RSHDRPatternManager::Instance().MHCReleaseEGraph(curFrameId);
162         return false;
163     }
164 
165     // 4. Apply for ION memory
166     bool ret2 = RSHDRPatternManager::Instance().TryConsumeBuffer(
167         [nodeDrawable]() { (nodeDrawable->GetRsHdrBUfferLayer())->ConsumeAndUpdateBuffer(); });
168     if (ret2 == false) {
169         RS_LOGE("TryConsumeBuffer failed");
170         RSHDRPatternManager::Instance().MHCReSetCurFrameId();
171         RSHDRPatternManager::Instance().MHCReleaseEGraph(curFrameId);
172         return false;
173     }
174     dstBuffer_ = (nodeDrawable->GetRsHdrBUfferLayer())->PrepareHDRDstBuffer(surfaceParams,
175         GetScreenIDByDrawable(nodeDrawable));
176     if (dstBuffer_ == nullptr) {
177         RS_LOGE("dstBuffer is nullptr");
178         RSHDRPatternManager::Instance().MHCReSetCurFrameId();
179         RSHDRPatternManager::Instance().MHCReleaseEGraph(curFrameId);
180         return false;
181     }
182 
183     (nodeDrawable->GetRsHdrBUfferLayer())->FlushHDRDstBuffer(dstBuffer_);
184     RSHDRPatternManager::Instance().SetBufferFlushed();
185 
186     return true;
187 }
188 
GetCurFrameHeterogHandleCanBeUsed()189 bool RSHdrManager::GetCurFrameHeterogHandleCanBeUsed()
190 {
191     return curFrameHeterogHandleCanBeUesed_;
192 }
193 
ProcessPendingNode(uint32_t nodeId,uint64_t curFrameId)194 void RSHdrManager::ProcessPendingNode(uint32_t nodeId, uint64_t curFrameId)
195 {
196     auto drawable = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(nodeId);
197     if (!drawable) {
198         curFrameHeterogHandleCanBeUesed_ = false;
199         RS_LOGE("RSHdrManager::PostHdrSubTasks drawable is nullptr!");
200         return;
201     }
202 
203     auto nodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
204     nodeDrawable->SetVideoHdrStatus(HdrStatus::HDR_VIDEO);
205 
206     if (!CheckWindowOwnership(nodeId)) {
207         curFrameHeterogHandleCanBeUesed_ = false;
208         return;
209     }
210 
211     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
212     if (!ValidateSurface(surfaceParams)) {
213         curFrameHeterogHandleCanBeUesed_ = false;
214         return;
215     }
216 
217     if (!PrepareAndSubmitHdrTask(nodeDrawable, surfaceParams, nodeId, curFrameId)) {
218         curFrameHeterogHandleCanBeUesed_ = false;
219     }
220 }
221 
CheckWindowOwnership(uint32_t nodeId)222 bool RSHdrManager::CheckWindowOwnership(uint32_t nodeId)
223 {
224     const auto& pendingNodes = RSUifirstManager::Instance().GetPendingPostNodes();
225     if (ownedLeashWindowIdMap_.find(nodeId) == ownedLeashWindowIdMap_.end() &&
226         ownedAppWindowIdMap_.find(nodeId) == ownedAppWindowIdMap_.end()) {
227         RS_LOGE("Cannot find the owned Leash Window of the video surface!");
228         return false;
229     }
230 
231     if (ownedAppWindowIdMap_.find(nodeId) != ownedAppWindowIdMap_.end()) {
232         auto ownedAppWindowDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(
233             DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(ownedAppWindowIdMap_[nodeId]));
234         if (ownedAppWindowDrawable && IsHDRSurfaceNodeSkipped(ownedAppWindowDrawable)) {
235             RS_LOGE("ownedAppWindowDrawable IsHDRSurfaceNodeSkipped!");
236             return false;
237         }
238     }
239 
240     if (ownedLeashWindowIdMap_.find(nodeId) != ownedLeashWindowIdMap_.end()) {
241         auto drawable = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(ownedLeashWindowIdMap_[nodeId]);
242         if (drawable == nullptr) {
243             RS_LOGE("RSHdrManager::CheckWindowOwnership drawable is nullptr");
244             return false;
245         }
246 
247         auto ownedLeashWindowDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
248         if (ownedLeashWindowDrawable && IsHDRSurfaceNodeSkipped(ownedLeashWindowDrawable) &&
249             pendingNodes.find(ownedLeashWindowIdMap_[nodeId]) == pendingNodes.end()) {
250             RS_LOGE("DrawWithUIFirstCache and not rendered in UIFirst SubThread!");
251             return false;
252         }
253     }
254     return true;
255 }
256 
ValidateSurface(RSSurfaceRenderParams * surfaceParams)257 bool RSHdrManager::ValidateSurface(RSSurfaceRenderParams* surfaceParams)
258 {
259     if (surfaceParams == nullptr) {
260         RS_LOGE("surfaceParams is nullptr");
261         return false;
262     }
263 
264     const auto& dstRect = surfaceParams->GetLayerInfo().dstRect;
265     if (dstRect.w == 0 || dstRect.h == 0) {
266         RS_LOGE("dstRect is invalid");
267         return false;
268     }
269     return true;
270 }
271 
PrepareAndSubmitHdrTask(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> nodeDrawable,RSSurfaceRenderParams * surfaceParams,uint32_t nodeId,uint64_t curFrameId)272 bool RSHdrManager::PrepareAndSubmitHdrTask(
273     std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> nodeDrawable,
274     RSSurfaceRenderParams* surfaceParams,
275     uint32_t nodeId,
276     uint64_t curFrameId)
277 {
278     sptr<SurfaceBuffer> srcBuffer = surfaceParams->GetBuffer();
279     auto srcRect = surfaceParams->GetLayerInfo().srcRect;
280     const auto& pendingNodes = RSUifirstManager::Instance().GetPendingPostNodes();
281 
282     bool need2Handle = isCurrentFrameBufferConsumedMap_[nodeId] ||
283                       (!nodeDrawable->GetCurHeterogComputingHdr());
284     auto src = RectRound(RectI(srcRect.x, srcRect.y, srcRect.w, srcRect.h));
285 
286     GetFixDstRectStatus(nodeDrawable, (pendingNodes.find(ownedLeashWindowIdMap_[nodeId]) != pendingNodes.end()),
287         surfaceParams, dst_, isFixedDstBuffer_);
288     // isFixedDstBuffer is true when hpae and GPU are used separately for scaling
289     if (isFixedDstBuffer_ || srcRect.w == 0 || srcRect.h == 0) {
290         // this condition, crop and scale need to be handle by gpu, so the output of hpae shulde
291         // be full size and the input of the video should also be full size
292         src = {0, 0, srcBuffer->GetSurfaceBufferWidth(), srcBuffer->GetSurfaceBufferHeight()};
293     }
294 
295     RectI prevSrc = nodeSrcRect_[nodeId];
296     if (!EquRect(src, prevSrc)) {
297         need2Handle = true;
298     }
299     nodeSrcRect_[nodeId] = src;
300 
301     MdcRectT srcRect_mdc{src.GetLeft(), src.GetTop(), src.GetRight(), src.GetBottom()};
302     nodeDrawable->SetNodeDrawableNodeDstRect(isFixedDstBuffer_, dst_);
303 
304     if (!need2Handle) {
305         return true;
306     }
307     if (!PrepareHapeTask(nodeDrawable, curFrameId)) {
308         RS_LOGE("Hape hdr heterog PrepareHapeTask failed!");
309         return false;
310     }
311 
312     // 5. Submit HDR task
313     RSHeteroHdrUtil::GetInstance().RequestHpaeChannel();
314     destroyedFlag_.store(false);
315     nodeDrawable->SetHpaeDstRect(dst_);
316 
317     RSHDRPatternManager::Instance().MHCSubmitHDRTask(
318         curFrameId, MHC_PATTERN_TASK_HDR_HPAE,
319         [surfaceParams, nodeId, srcRect_mdc, this] {
320             uint32_t taskId = 0;
321             this->buildHDRTaskStatus = BuildHDRTask(surfaceParams, srcRect_mdc, &taskId, &(this->taskPtr_));
322             this->taskId_.store(taskId);
323         },
324         &taskPtr_,
325         [this, curFrameId] {
326             RSHeteroHdrUtil::GetInstance().DestroyHpaeHdrTask(this->taskId_.load());
327             this->taskPtr_ = nullptr;
328             destroyedFlag_.store(true);
329             this->cond_.notify_one();
330         });
331     return true;
332 }
333 
PostHdrSubTasks()334 void RSHdrManager::PostHdrSubTasks()
335 {
336     if (!isHeterogComputingHdrOn_) {
337         return;
338     }
339 
340     uint64_t curFrameId = OHOS::Rosen::HgmCore::Instance().GetVsyncId();
341     RSHDRPatternManager::Instance().MHCSetVsyncId(curFrameId);
342     RSHdrManager::Instance().FindParentLeashWindowNode();
343 
344     if (pendingPostNodes_.size() == 1 && curFrameId != 0) {
345         curFrameHeterogHandleCanBeUesed_ = true;
346         for (auto &item : pendingPostNodes_) {
347             ProcessPendingNode(item.first, curFrameId);
348             if (!curFrameHeterogHandleCanBeUesed_) {
349                 break;
350             }
351         }
352     } else {
353         curFrameHeterogHandleCanBeUesed_ = false;
354         if (destroyedFlag_.load()) {
355             RSHeteroHdrUtil::GetInstance().ReleaseHpaeHdrChannel();
356         } else {
357             RS_LOGI("AAE device is not ready or aae task doesnt exit ");
358         }
359     }
360 
361     pendingPostNodes_.clear();
362     ownedLeashWindowIdMap_.clear();
363     ownedAppWindowIdMap_.clear();
364 }
365 
GetScreenIDByDrawable(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable)366 ScreenId RSHdrManager::GetScreenIDByDrawable(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable)
367 {
368 #ifdef RS_ENABLE_GPU
369     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
370     if (!surfaceParams || !surfaceParams->GetAncestorScreenNode().lock()) {
371         return INVALID_SCREEN_ID;
372     }
373     auto ancestor = surfaceParams->GetAncestorScreenNode().lock()->ReinterpretCastTo<RSScreenRenderNode>();
374     if (!ancestor) {
375         return INVALID_SCREEN_ID;
376     }
377     auto screenParams = static_cast<RSScreenRenderParams*>(ancestor->GetRenderParams().get());
378     if (!screenParams) {
379         return INVALID_SCREEN_ID;
380     }
381     return screenParams->GetScreenId();
382 #else
383     return INVALID_SCREEN_ID;
384 #endif
385 }
386 
FindParentLeashWindowNode()387 void RSHdrManager::FindParentLeashWindowNode()
388 {
389     if (pendingPostNodes_.size() != 1) {
390         return;
391     }
392     for (auto &item : pendingPostNodes_) {
393         windowSceneNode_ = nullptr;
394         appWindowNode_ = nullptr;
395         ReverseParentNode(item.second->GetParent().lock());
396         if (windowSceneNode_ != nullptr) {
397             ownedLeashWindowIdMap_[item.first] = windowSceneNode_->GetId();
398         }
399         if (appWindowNode_ != nullptr) {
400             ownedAppWindowIdMap_[item.first] = appWindowNode_->GetId();
401         }
402     }
403     return;
404 }
405 
ReverseParentNode(std::shared_ptr<RSRenderNode> node)406 void RSHdrManager::ReverseParentNode(std::shared_ptr<RSRenderNode> node)
407 {
408     if (node == nullptr) {
409         return;
410     }
411     auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
412     if (surfaceNode && surfaceNode->IsAppWindow()) {
413         appWindowNode_ = surfaceNode;
414     }
415     if (surfaceNode && surfaceNode->IsLeashWindow()) {
416         windowSceneNode_ = surfaceNode;
417     }
418     auto displayNode = RSBaseRenderNode::ReinterpretCast<RSScreenRenderNode>(node);
419     if (displayNode) {
420         auto drawable = displayNode->GetRenderDrawable();
421         if (drawable == nullptr) {
422             return;
423         }
424         auto displayDrawable = std::static_pointer_cast<DrawableV2::RSScreenRenderNodeDrawable>(drawable);
425         displayDrawable->CheckAndUpdateFilterCacheOcclusionFast();
426         return;
427     }
428     ReverseParentNode(node->GetParent().lock());
429 }
430 
BuildHDRTask(RSSurfaceRenderParams * surfaceParams,MdcRectT srcRect,uint32_t * taskId,void ** taskPtr)431 int32_t RSHdrManager::BuildHDRTask(
432     RSSurfaceRenderParams *surfaceParams, MdcRectT srcRect, uint32_t *taskId, void **taskPtr)
433 {
434     auto dstRect = surfaceParams->GetLayerInfo().dstRect;
435     BufferHandle *dstHandle = dstBuffer_->GetBufferHandle();
436     if (!dstHandle) {
437         RS_LOGE("QM: dstHandle is not available");
438         return -1;
439     }
440     MdcRectT HpaeDstRect = {dst_.GetLeft(), dst_.GetTop(), dst_.GetRight(), dst_.GetBottom()};
441 
442     sptr<SurfaceBuffer> srcBuffer = surfaceParams->GetBuffer();
443     constexpr float GAMMA2_2 = 2.2f;
444 
445     hapeTaskInfoT taskInfo;
446     taskInfo.taskId = taskId;
447     taskInfo.taskPtr = taskPtr;
448     taskInfo.srcRect = srcRect;
449     taskInfo.dstRect = HpaeDstRect;
450     taskInfo.srcHandle = srcBuffer->GetBufferHandle();
451     taskInfo.dstHandle = dstHandle;
452     taskInfo.displaySDRNits = surfaceParams->GetSdrNit();
453     taskInfo.displayHDRNits =
454         (surfaceParams->GetDisplayNit()) / std::pow(surfaceParams->GetBrightnessRatio(), GAMMA2_2);
455 
456     return RSHeteroHdrUtil::GetInstance().BuildHpaeHdrTask(taskInfo);
457 }
458 
IsHDRSurfaceNodeSkipped(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> surfaceDrawable)459 bool RSHdrManager::IsHDRSurfaceNodeSkipped(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> surfaceDrawable)
460 {
461     auto surfaceParams = static_cast<RSSurfaceRenderParams *>(surfaceDrawable->GetRenderParams().get());
462     if (RSUniRenderUtil::CheckRenderSkipIfScreenOff(true, GetScreenIDByDrawable(surfaceDrawable))) {
463         return true;
464     }
465     if (!surfaceDrawable->ShouldPaint()) {
466         return true;
467     }
468     auto &uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
469     if (UNLIKELY(!uniParam)) {
470         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw uniParam is nullptr");
471         return true;
472     }
473 
474     if (!surfaceParams) {
475         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw params is nullptr");
476         return true;
477     }
478     if (surfaceParams->GetOccludedByFilterCache()) {
479         RS_TRACE_NAME("RSSurfaceRenderNodeDrawable::FilterCache Skip");
480         return true;
481     }
482     auto enableType = surfaceParams->GetUifirstNodeEnableParam();
483     auto cacheState = surfaceDrawable->GetRsSubThreadCache().GetCacheSurfaceProcessedStatus();
484     if ((!RSUniRenderThread::GetCaptureParam().isSnapshot_ && enableType == MultiThreadCacheType::NONE &&
485             cacheState != CacheProcessStatus::WAITING && cacheState != CacheProcessStatus::DOING) ||
486         (RSUniRenderThread::GetCaptureParam().isSnapshot_ &&
487             !surfaceDrawable->GetRsSubThreadCache().HasCachedTexture())) {
488         return false;
489     }
490     return true;
491 }
492 }  // namespace Rosen
493 }  // namespace OHOS
494