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