• 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 "drawable/rs_screen_render_node_drawable.h"
17 
18 #include <memory>
19 #include <parameters.h>
20 #include <string>
21 
22 #include "graphic_feature_param_manager.h"
23 #include "rs_trace.h"
24 #include "system/rs_system_parameters.h"
25 
26 #include "common/rs_common_def.h"
27 #include "common/rs_optional_trace.h"
28 #include "common/rs_singleton.h"
29 #include "common/rs_special_layer_manager.h"
30 #include "display_engine/rs_luminance_control.h"
31 #include "drawable/rs_surface_render_node_drawable.h"
32 #include "feature/anco_manager/rs_anco_manager.h"
33 #include "feature/uifirst/rs_uifirst_manager.h"
34 #ifdef RS_ENABLE_OVERLAY_DISPLAY
35 #include "feature/overlay_display/rs_overlay_display_manager.h"
36 #endif
37 #include "hgm_core.h"
38 #include "memory/rs_tag_tracker.h"
39 #include "params/rs_screen_render_params.h"
40 #include "params/rs_surface_render_params.h"
41 #include "feature/dirty/rs_uni_dirty_compute_util.h"
42 #include "feature/drm/rs_drm_util.h"
43 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
44 #include "feature/round_corner_display/rs_rcd_surface_render_node_drawable.h"
45 #include "feature/round_corner_display/rs_message_bus.h"
46 #include "pipeline/render_thread/rs_base_render_engine.h"
47 #include "pipeline/rs_screen_render_node.h"
48 #include "pipeline/main_thread/rs_main_thread.h"
49 #include "pipeline/rs_paint_filter_canvas.h"
50 #include "pipeline/rs_processor_factory.h"
51 #include "pipeline/rs_pointer_window_manager.h"
52 #include "pipeline/rs_surface_handler.h"
53 #include "pipeline/main_thread/rs_uni_render_listener.h"
54 #include "pipeline/render_thread/rs_uni_render_thread.h"
55 #include "pipeline/render_thread/rs_uni_render_util.h"
56 #include "pipeline/render_thread/rs_uni_render_virtual_processor.h"
57 #include "pipeline/sk_resource_manager.h"
58 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
59 #include "pipeline/magic_pointer_render/rs_magic_pointer_render_manager.h"
60 #endif
61 #include "platform/common/rs_log.h"
62 #include "platform/ohos/rs_jank_stats_helper.h"
63 #include "render/rs_pixel_map_util.h"
64 #include "screen_manager/rs_screen_manager.h"
65 #include "rs_frame_report.h"
66 // dfx
67 #include "drawable/dfx/rs_dirty_rects_dfx.h"
68 #include "drawable/dfx/rs_skp_capture_dfx.h"
69 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
70 #include "utils/performanceCaculate.h"
71 // cpu boost
72 #include "c/ffrt_cpu_boost.h"
73 // xml parser
74 #include "graphic_feature_param_manager.h"
75 // hpae offline
76 #include "feature/hwc/hpae_offline/rs_hpae_offline_processor.h"
77 
78 #ifdef SUBTREE_PARALLEL_ENABLE
79 #include "rs_parallel_manager.h"
80 #endif
81 
82 namespace OHOS::Rosen::DrawableV2 {
83 namespace {
84 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
85 constexpr const char* DEFAULT_CLEAR_GPU_CACHE = "DefaultClearGpuCache";
86 constexpr int32_t CAPTURE_WINDOW = 2; // To be deleted after captureWindow being deleted
87 constexpr int64_t MAX_JITTER_NS = 2000000; // 2ms
88 
RectVectorToString(const std::vector<RectI> & regionRects)89 std::string RectVectorToString(const std::vector<RectI>& regionRects)
90 {
91     std::string results = "";
92     for (auto& rect : regionRects) {
93         results += rect.ToString();
94     }
95     return results;
96 }
97 
GetFlippedRegion(const std::vector<RectI> & rects,ScreenInfo & screenInfo)98 Drawing::Region GetFlippedRegion(const std::vector<RectI>& rects, ScreenInfo& screenInfo)
99 {
100     Drawing::Region region;
101 
102     for (const auto& r : rects) {
103         int32_t topAfterFilp = 0;
104 #ifdef RS_ENABLE_VK
105         topAfterFilp = (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
106                            RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR)
107                            ? r.top_
108                            : static_cast<int32_t>(screenInfo.GetRotatedHeight()) - r.GetBottom();
109 #else
110         topAfterFilp = static_cast<int32_t>(screenInfo.GetRotatedHeight()) - r.GetBottom();
111 #endif
112         Drawing::Region tmpRegion;
113         tmpRegion.SetRect(Drawing::RectI(r.left_, topAfterFilp, r.left_ + r.width_, topAfterFilp + r.height_));
114         RS_OPTIONAL_TRACE_NAME_FMT("GetFlippedRegion orig ltrb[%d %d %d %d] to fliped rect ltrb[%d %d %d %d]",
115             r.left_, r.top_, r.left_ + r.width_, r.top_ + r.height_, r.left_, topAfterFilp, r.left_ + r.width_,
116             topAfterFilp + r.height_);
117         region.Op(tmpRegion, Drawing::RegionOp::UNION);
118     }
119     return region;
120 }
121 }
122 
123 // Rcd node will be handled by RS tree in OH 6.0 rcd refactoring, should remove this later
DoScreenRcdTask(RSScreenRenderParams & params,std::shared_ptr<RSProcessor> & processor)124 void DoScreenRcdTask(RSScreenRenderParams& params, std::shared_ptr<RSProcessor> &processor)
125 {
126     if (processor == nullptr) {
127         RS_LOGD("DoScreenRcdTask has no processor");
128         return;
129     }
130     const auto &screenInfo = params.GetScreenInfo();
131     if (screenInfo.state != ScreenState::HDI_OUTPUT_ENABLE) {
132         RS_LOGD("DoScreenRcdTask is not at HDI_OUPUT mode");
133         return;
134     }
135 
136     bool res = true;
137     bool resourceChanged = false;
138     auto drawables = params.GetRoundCornerDrawables();
139     for (auto drawable : drawables) {
140         auto rcdDrawable = std::static_pointer_cast<DrawableV2::RSRcdSurfaceRenderNodeDrawable>(drawable);
141         if (rcdDrawable) {
142             resourceChanged |= rcdDrawable->IsResourceChanged();
143             res &= rcdDrawable->DoProcessRenderTask(processor);
144         }
145     }
146     if (resourceChanged && res) {
147         RSSingleton<RsMessageBus>::GetInstance().SendMsg<NodeId, bool>(
148             TOPIC_RCD_DISPLAY_HWRESOURCE, params.GetId(), true);
149     }
150 }
151 
152 RSScreenRenderNodeDrawable::Registrar RSScreenRenderNodeDrawable::instance_;
153 
RSScreenRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)154 RSScreenRenderNodeDrawable::RSScreenRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
155     : RSRenderNodeDrawable(std::move(node)), surfaceHandler_(std::make_shared<RSSurfaceHandler>(nodeId_)),
156       syncDirtyManager_(std::make_shared<RSDirtyRegionManager>(true))
157 {}
158 
OnGenerate(std::shared_ptr<const RSRenderNode> node)159 RSRenderNodeDrawable::Ptr RSScreenRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
160 {
161     return new RSScreenRenderNodeDrawable(std::move(node));
162 }
163 
RequestFrame(RSScreenRenderParams & params,std::shared_ptr<RSProcessor> processor)164 std::unique_ptr<RSRenderFrame> RSScreenRenderNodeDrawable::RequestFrame(
165     RSScreenRenderParams& params, std::shared_ptr<RSProcessor> processor)
166 {
167     RS_TRACE_NAME_FMT("RSScreenRenderNodeDrawable:RequestFrame with colorSpace: %d, pixelformat: %d, ",
168         "lastPixelFormat: %d", params.GetNewColorSpace(), params.GetNewPixelFormat(), GetLastPixelFormat());
169     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
170     if (UNLIKELY(!renderEngine)) {
171         RS_LOGE("RSScreenRenderNodeDrawable::RequestFrame RenderEngine is null!");
172         return nullptr;
173     }
174 
175     if (!processor->InitForRenderThread(*this, renderEngine)) {
176         RS_LOGE("RSScreenRenderNodeDrawable::RequestFrame processor init failed!");
177         return nullptr;
178     }
179 
180     if (!IsSurfaceCreated()) {
181         sptr<IBufferConsumerListener> listener = new RSUniRenderListener(surfaceHandler_);
182         if (!CreateSurface(listener)) {
183             RS_LOGE("RSScreenRenderNodeDrawable::RequestFrame CreateSurface failed");
184             return nullptr;
185         }
186     }
187 
188     auto rsSurface = GetRSSurface();
189     if (!rsSurface) {
190         RS_LOGE("RSScreenRenderNodeDrawable::RequestFrame No RSSurface found");
191         return nullptr;
192     }
193     auto bufferConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(params.GetScreenInfo(), false,
194         params.GetNewColorSpace(), params.GetNewPixelFormat());
195     RS_LOGD("RequestFrame colorspace is %{public}d, pixelformat is %{public}d, lastPixelFormat: %{public}d",
196         params.GetNewColorSpace(), params.GetNewPixelFormat(), GetLastPixelFormat());
197 
198     bool isHebc = true;
199     if (RSAncoManager::Instance()->GetAncoHebcStatus() == AncoHebcStatus::NOT_USE_HEBC) {
200         isHebc = false;
201         RS_LOGI("anco request frame not use hebc");
202     }
203     RSAncoManager::Instance()->SetAncoHebcStatus(AncoHebcStatus::INITIAL);
204     if (IsPixelFormatChanged(params)) {
205         auto ohosSurface = std::static_pointer_cast<RSSurfaceOhos>(rsSurface);
206         auto surface = ohosSurface->GetSurface();
207         if (surface == nullptr) {
208             RS_LOGE("RSScreenRenderNodeDrawable::rsSurface->GetSurface is nullptr!!");
209         } else {
210             RS_TRACE_NAME("RSScreenRenderNodeDrawable::SetBufferReallocFlag succeed");
211             surface->SetBufferReallocFlag(true);
212             RS_LOGI("RSScreenRenderNodeDrawable::SetBufferReallocFlag succeed");
213         }
214     }
215     SetLastPixelFormat(params.GetNewPixelFormat());
216     auto renderFrame = renderEngine->RequestFrame(std::static_pointer_cast<RSSurfaceOhos>(rsSurface),
217         bufferConfig, false, isHebc);
218     if (!renderFrame) {
219         RS_LOGE("RSScreenRenderNodeDrawable::RequestFrame renderEngine requestFrame is null");
220         return nullptr;
221     }
222 
223     return renderFrame;
224 }
225 
ClipRegion(Drawing::Canvas & canvas,Drawing::Region & region,bool clear=true)226 static void ClipRegion(Drawing::Canvas& canvas, Drawing::Region& region, bool clear = true)
227 {
228     if (region.IsEmpty()) {
229         // [planning] Remove this after frame buffer can cancel
230         canvas.ClipRect(Drawing::Rect());
231     } else if (region.IsRect()) {
232         canvas.ClipRegion(region);
233     } else {
234         RS_TRACE_NAME("RSScreenRenderNodeDrawable: clipPath");
235 #ifdef RS_ENABLE_VK
236         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
237             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
238             canvas.ClipRegion(region);
239         } else {
240             Drawing::Path dirtyPath;
241             region.GetBoundaryPath(&dirtyPath);
242             canvas.ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
243         }
244 #else
245         Drawing::Path dirtyPath;
246         region.GetBoundaryPath(&dirtyPath);
247         canvas.ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
248 #endif
249     }
250 
251     // clear canvas after clip region if need
252     if (clear && !region.IsEmpty()) {
253         canvas.Clear(Drawing::Color::COLOR_TRANSPARENT);
254     }
255 }
256 
HardCursorCreateLayer(std::shared_ptr<RSProcessor> processor)257 bool RSScreenRenderNodeDrawable::HardCursorCreateLayer(std::shared_ptr<RSProcessor> processor)
258 {
259     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
260     if (!uniParam) {
261         RS_LOGE("RSScreenRenderNodeDrawable::HardCursorCreateLayer uniParam is null");
262         return false;
263     }
264     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
265     if (hardCursorDrawables.empty()) {
266         return false;
267     }
268     auto iter = std::find_if(hardCursorDrawables.begin(), hardCursorDrawables.end(), [id = GetId()](const auto& node) {
269         return std::get<0>(node) == id;
270     });
271     if (iter == hardCursorDrawables.end()) {
272         return false;
273     }
274     auto& hardCursorDrawable = std::get<2>(*iter);
275     if (!hardCursorDrawable) {
276         return false;
277     }
278     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(hardCursorDrawable->GetRenderParams().get());
279     if (!surfaceParams) {
280         RS_LOGE("RSScreenRenderNodeDrawable::HardCursorCreateLayer surfaceParams is null");
281         return false;
282     }
283     auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable);
284     if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
285         processor->CreateLayerForRenderThread(*surfaceDrawable);
286         return true;
287     }
288     return false;
289 }
290 
RenderOverDraw()291 void RSScreenRenderNodeDrawable::RenderOverDraw()
292 {
293     bool isEnabled = false;
294     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
295     if (LIKELY(uniParam)) {
296         isEnabled = uniParam->IsOverDrawEnabled();
297     }
298     bool enable = isEnabled && curCanvas_ != nullptr;
299     if (!enable) {
300         return;
301     }
302     auto gpuContext = curCanvas_->GetGPUContext();
303     if (gpuContext == nullptr) {
304         RS_LOGE("RSScreenRenderNodeDrawable::RenderOverDraw failed: need gpu canvas");
305         return;
306     }
307     Drawing::ImageInfo info = Drawing::ImageInfo { curCanvas_->GetWidth(), curCanvas_->GetHeight(),
308         Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL };
309     auto overdrawSurface = Drawing::Surface::MakeRenderTarget(gpuContext.get(), false, info);
310     if (!overdrawSurface) {
311         RS_LOGE("RSScreenRenderNodeDrawable::RenderOverDraw failed: surface is nullptr");
312         return;
313     }
314     auto overdrawCanvas = std::make_shared<Drawing::OverDrawCanvas>(overdrawSurface->GetCanvas());
315     overdrawCanvas->SetGrContext(gpuContext);
316     auto paintCanvas = std::make_shared<RSPaintFilterCanvas>(overdrawCanvas.get());
317     // traverse all drawable to detect overdraw
318     auto params = static_cast<RSScreenRenderParams*>(renderParams_.get());
319     paintCanvas->ConcatMatrix(params->GetMatrix());
320     RS_TRACE_NAME_FMT("RSScreenRenderNodeDrawable::RenderOverDraw");
321     RSRenderNodeDrawable::OnDraw(*paintCanvas);
322     // show overdraw result in main display
323     auto image = overdrawSurface->GetImageSnapshot();
324     if (image == nullptr) {
325         RS_LOGE("RSScreenRenderNodeDrawable::RenderOverDraw image is nullptr");
326         return;
327     }
328     Drawing::Brush brush;
329     auto overdrawColors = RSOverdrawController::GetInstance().GetColorArray();
330     auto colorFilter = Drawing::ColorFilter::CreateOverDrawColorFilter(overdrawColors.data());
331     Drawing::Filter filter;
332     filter.SetColorFilter(colorFilter);
333     brush.SetFilter(filter);
334     curCanvas_->AttachBrush(brush);
335     curCanvas_->DrawImage(*image, 0, 0, Drawing::SamplingOptions());
336     curCanvas_->DetachBrush();
337 }
338 
IsForceCommit(uint32_t forceCommitReason,bool needForceUpdateHwcNode,bool hasHardCursor)339 static inline bool IsForceCommit(uint32_t forceCommitReason, bool needForceUpdateHwcNode,
340     bool hasHardCursor)
341 {
342     /* force commit in 3 situations:
343      1.force commit reasons is not hwc nodes updated or cursor moved
344      2.hwc nodes forced commit and hwc nodes is visible
345      3.soft cursor's position changed */
346     return (forceCommitReason & ~(ForceCommitReason::FORCED_BY_HWC_UPDATE |
347                                   ForceCommitReason::FORCED_BY_POINTER_WINDOW)) ||
348            ((forceCommitReason & ForceCommitReason::FORCED_BY_HWC_UPDATE) && needForceUpdateHwcNode) ||
349            ((forceCommitReason & ForceCommitReason::FORCED_BY_POINTER_WINDOW) && !hasHardCursor);
350 }
351 
CheckScreenNodeSkip(RSScreenRenderParams & params,std::shared_ptr<RSProcessor> processor)352 bool RSScreenRenderNodeDrawable::CheckScreenNodeSkip(
353     RSScreenRenderParams& params, std::shared_ptr<RSProcessor> processor)
354 {
355     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
356     if (params.HasChildCrossNode() && !params.IsMirrorScreen() &&
357         uniParam->GetCrossNodeOffScreenStatus() != CrossNodeOffScreenRenderDebugType::DISABLED) {
358         return false;
359     }
360     if (GetSyncDirtyManager()->IsCurrentFrameDirty() ||
361         (params.GetMainAndLeashSurfaceDirty() || RSUifirstManager::Instance().HasForceUpdateNode()) ||
362         RSMainThread::Instance()->GetDirtyFlag()) {
363         return false;
364     }
365     if (params.IsHDRStatusChanged()) {
366         RS_LOGD("RSScreenRenderNodeDrawable::CheckScreenNodeSkip IsHDRStatusChanged");
367         return false;
368     }
369 
370     RS_LOGD("ScreenNode skip");
371     RS_TRACE_NAME("DisplayNode skip");
372     GpuDirtyRegionCollection::GetInstance().AddSkipProcessFramesNumberForDFX(RSBaseRenderUtil::GetLastSendingPid());
373 #ifdef OHOS_PLATFORM
374     RSJankStatsRenderFrameHelper::GetInstance().SetSkipJankAnimatorFrame(true);
375 #endif
376     auto hardCursorDrawable = RSPointerWindowManager::Instance().GetHardCursorDrawable(GetId());
377     bool hasHardCursor = (hardCursorDrawable != nullptr);
378     bool hardCursorNeedCommit = (hasHardCursor != hardCursorLastCommitSuccess_);
379     auto forceCommitReason = uniParam->GetForceCommitReason();
380     bool layersNeedCommit = IsForceCommit(forceCommitReason, params.GetNeedForceUpdateHwcNodes(), hasHardCursor);
381     RS_TRACE_NAME_FMT("DisplayNode skip, forceCommitReason: %d, forceUpdateByHwcNodes %d, "
382         "byHardCursor: %d", forceCommitReason, params.GetNeedForceUpdateHwcNodes(), hardCursorNeedCommit);
383     if (!layersNeedCommit && !hardCursorNeedCommit) {
384         RS_TRACE_NAME("DisplayNodeSkip skip commit");
385         return true;
386     }
387 
388     if (!processor->InitForRenderThread(*this, RSUniRenderThread::Instance().GetRenderEngine())) {
389         RS_LOGE("RSScreenRenderNodeDrawable::CheckScreenNodeSkip processor init failed");
390         return false;
391     }
392     hardCursorLastCommitSuccess_ = hasHardCursor;
393     if (hardCursorDrawable != nullptr) {
394         processor->CreateLayerForRenderThread(*hardCursorDrawable);
395     }
396     auto& hardwareDrawables =
397         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
398     for (const auto& [screenNodeId, _, drawable] : hardwareDrawables) {
399         if (UNLIKELY(!drawable || !drawable->GetRenderParams()) || screenNodeId != params.GetId()) {
400             continue;
401         }
402 
403         if (drawable->GetRenderParams()->GetHardwareEnabled()) {
404             auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
405             auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
406             // hpae offline
407             if (surfaceParams->GetLayerInfo().useDeviceOffline &&
408                 ProcessOfflineSurfaceDrawable(processor, surfaceDrawable, false)) {
409                 continue;
410             }
411             processor->CreateLayerForRenderThread(*surfaceDrawable);
412         }
413     }
414     if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
415         RS_LOGW("RSScreenRenderNodeDrawable::CheckScreenNodeSkip: hardwareThread task has too many to Execute"
416                 " TaskNum:[%{public}d]", RSHardwareThread::Instance().GetunExecuteTaskNum());
417         RSHardwareThread::Instance().DumpEventQueue();
418     }
419     processor->ProcessScreenSurfaceForRenderThread(*this);
420 
421     // commit RCD layers
422 
423     DoScreenRcdTask(params, processor);
424     processor->PostProcess();
425     return true;
426 }
427 
PostClearMemoryTask() const428 void RSScreenRenderNodeDrawable::PostClearMemoryTask() const
429 {
430     auto& unirenderThread = RSUniRenderThread::Instance();
431     if (unirenderThread.IsDefaultClearMemroyFinished()) {
432         unirenderThread.DefaultClearMemoryCache(); //default clean with no rendering in 5s
433         unirenderThread.SetDefaultClearMemoryFinished(false);
434     }
435 }
436 
SetScreenNodeSkipFlag(RSRenderThreadParams & uniParam,bool flag)437 void RSScreenRenderNodeDrawable::SetScreenNodeSkipFlag(RSRenderThreadParams& uniParam, bool flag)
438 {
439     isScreenNodeSkipStatusChanged_ = (isScreenNodeSkip_ != flag);
440     isScreenNodeSkip_ = flag;
441     uniParam.SetForceMirrorScreenDirty(isScreenNodeSkipStatusChanged_ && isScreenNodeSkip_);
442 }
443 
CheckFilterCacheFullyCovered(RSSurfaceRenderParams & surfaceParams,RectI screenRect)444 void RSScreenRenderNodeDrawable::CheckFilterCacheFullyCovered(RSSurfaceRenderParams& surfaceParams, RectI screenRect)
445 {
446     surfaceParams.SetFilterCacheFullyCovered(false);
447     if (!surfaceParams.IsTransparent() || surfaceParams.GetIsRotating() || surfaceParams.GetAttractionAnimation()) {
448         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterCacheFullyCovered NodeId[%" PRIu64 "], isOpaque: %d, "
449             "isRotating: %d, isAttractionAnimation: %d", surfaceParams.GetId(), !surfaceParams.IsTransparent(),
450             surfaceParams.GetIsRotating(), surfaceParams.GetAttractionAnimation());
451         return;
452     }
453     bool dirtyBelowContainsFilterNode = false;
454     for (auto& filterNodeId : surfaceParams.GetVisibleFilterChild()) {
455         auto drawableAdapter = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(filterNodeId);
456         if (drawableAdapter == nullptr) {
457             continue;
458         }
459         auto filterNodeDrawable = std::static_pointer_cast<DrawableV2::RSRenderNodeDrawable>(drawableAdapter);
460         if (filterNodeDrawable == nullptr) {
461             RS_LOGD("CheckFilterCacheFullyCovered filter node drawable is nullptr, Name[%{public}s],"
462                 "NodeId[%" PRIu64 "]", surfaceParams.GetName().c_str(), filterNodeId);
463             continue;
464         }
465         const auto& filterParams = filterNodeDrawable->GetRenderParams();
466         if (filterParams == nullptr || !filterParams->HasBlurFilter()) {
467             RS_LOGD("CheckFilterCacheFullyCovered filter params is nullptr or has no blur, Name[%{public}s],"
468                 "NodeId[%" PRIu64 "]", surfaceParams.GetName().c_str(), filterNodeId);
469             continue;
470         }
471         // Filter cache occlusion need satisfy:
472         // 1.The filter node global alpha equals 1;
473         // 2.There is no invalid filter cache node below, which should take snapshot;
474         // 3.The filter node has no global corner;
475         // 4.The node type is not EFFECT_NODE;
476         if (ROSEN_EQ(filterParams->GetGlobalAlpha(), 1.f) && !dirtyBelowContainsFilterNode &&
477             !filterParams->HasGlobalCorner() && filterParams->GetType() != RSRenderNodeType::EFFECT_NODE) {
478             bool cacheValid = filterNodeDrawable->IsFilterCacheValidForOcclusion();
479             RectI filterCachedRect = filterNodeDrawable->GetFilterCachedRegion();
480             surfaceParams.CheckValidFilterCacheFullyCoverTarget(cacheValid, filterCachedRect, screenRect);
481             RSFilterDirtyCollector::RecordFilterCacheValidForOcclusion(filterNodeId,
482                 surfaceParams.IsMainWindowType() && cacheValid && screenRect.IsInsideOf(filterCachedRect));
483         }
484         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterCacheFullyCovered NodeId[%" PRIu64 "], globalAlpha: %f, "
485             "hasInvalidFilterCacheBefore: %d, hasNoCorner: %d, isNodeTypeCorrect: %d, isCacheValid: %d, "
486             "cacheRect: %s", filterNodeId, filterParams->GetGlobalAlpha(), !dirtyBelowContainsFilterNode,
487             !filterParams->HasGlobalCorner(), filterParams->GetType() != RSRenderNodeType::EFFECT_NODE,
488             filterNodeDrawable->IsFilterCacheValidForOcclusion(),
489             filterNodeDrawable->GetFilterCachedRegion().ToString().c_str());
490         if (filterParams->GetEffectNodeShouldPaint() && !filterNodeDrawable->IsFilterCacheValidForOcclusion()) {
491             dirtyBelowContainsFilterNode = true;
492         }
493     }
494 }
495 
CheckAndUpdateFilterCacheOcclusionFast()496 void RSScreenRenderNodeDrawable::CheckAndUpdateFilterCacheOcclusionFast()
497 {
498     auto params = static_cast<RSScreenRenderParams*>(renderParams_.get());
499     ScreenId paramScreenId = params->GetScreenId();
500     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
501     if (!screenManager) {
502         SetDrawSkipType(DrawSkipType::SCREEN_MANAGER_NULL);
503         RS_LOGE("RSScreenRenderNodeDrawable::OnDraw ScreenManager is nullptr");
504         return;
505     }
506     ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(paramScreenId);
507     CheckAndUpdateFilterCacheOcclusion(*params, curScreenInfo);
508     filterCacheOcclusionUpdated_ = true;
509 }
510 
CheckAndUpdateFilterCacheOcclusion(RSScreenRenderParams & params,const ScreenInfo & screenInfo)511 void RSScreenRenderNodeDrawable::CheckAndUpdateFilterCacheOcclusion(
512     RSScreenRenderParams& params, const ScreenInfo& screenInfo)
513 {
514     if (!RSSystemParameters::GetFilterCacheOcculusionEnabled()) {
515         return;
516     }
517     bool isScreenOccluded = false;
518     RectI screenRect = {0, 0, screenInfo.width, screenInfo.height};
519     // top-down traversal all mainsurface
520     // if upper surface reuse filter cache which fully cover whole screen
521     // mark lower layers for process skip
522     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
523     for (const auto& adapter : curAllSurfaceDrawables) {
524         if (adapter == nullptr || adapter->GetNodeType() != RSRenderNodeType::SURFACE_NODE) {
525             RS_LOGD("CheckAndUpdateFilterCacheOcclusion adapter is nullptr or error type");
526             continue;
527         }
528         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(adapter);
529         if (surfaceNodeDrawable == nullptr) {
530             RS_LOGD("CheckAndUpdateFilterCacheOcclusion surfaceNodeDrawable is nullptr");
531             continue;
532         }
533         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
534         if (surfaceParams == nullptr) {
535             RS_LOGD("CheckAndUpdateFilterCacheOcclusion surface params is nullptr");
536             continue;
537         }
538 
539         CheckFilterCacheFullyCovered(*surfaceParams, screenRect);
540 
541         if (surfaceParams->IsMainWindowType()) {
542             // reset occluded status for all mainwindow
543             surfaceParams->SetOccludedByFilterCache(isScreenOccluded);
544         }
545         isScreenOccluded = isScreenOccluded || surfaceParams->GetFilterCacheFullyCovered();
546     }
547 }
548 
GetBufferAge()549 int32_t RSScreenRenderNodeDrawable::GetBufferAge()
550 {
551     return expandRenderFrame_ ? expandRenderFrame_->GetBufferAge() : 0;
552 }
553 
SetDamageRegion(const std::vector<RectI> & rects)554 void RSScreenRenderNodeDrawable::SetDamageRegion(const std::vector<RectI>& rects)
555 {
556     if (expandRenderFrame_ == nullptr) {
557         return;
558     }
559     expandRenderFrame_->SetDamageRegion(rects);
560 }
561 
OnDraw(Drawing::Canvas & canvas)562 void RSScreenRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
563 {
564     Drawing::GPUResourceTag::SetCurrentNodeId(GetId());
565     SetDrawSkipType(DrawSkipType::NONE);
566     // canvas will generate in every request frame
567     (void)canvas;
568 
569     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
570     if (UNLIKELY(!renderParams_ || !uniParam)) {
571         SetDrawSkipType(DrawSkipType::RENDER_PARAMS_OR_UNI_PARAMS_NULL);
572         RS_LOGE("RSScreenRenderNodeDrawable::OnDraw renderParams/uniParam is null!");
573         return;
574     }
575     auto params = static_cast<RSScreenRenderParams*>(renderParams_.get());
576     if (params->GetChildDisplayCount() == 0) {
577         SetDrawSkipType(DrawSkipType::NO_DISPLAY_NODE);
578         return;
579     }
580     auto screenInfo = params->GetScreenInfo();
581     if (screenInfo.state == ScreenState::DISABLED) {
582         SetDrawSkipType(DrawSkipType::SCREEN_STATE_INVALID);
583         return;
584     }
585     // [Attention] do not return before layer created set false, otherwise will result in buffer not released
586     auto& hardwareDrawables = uniParam->GetHardwareEnabledTypeDrawables();
587     for (const auto& [screenNodeId, _, drawable] : hardwareDrawables) {
588         if (UNLIKELY(!drawable || !drawable->GetRenderParams()) ||
589             screenNodeId != params->GetId()) {
590             continue;
591         }
592         drawable->GetRenderParams()->SetLayerCreated(false);
593     }
594     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
595     auto iter = std::find_if(hardCursorDrawables.begin(), hardCursorDrawables.end(), [id = GetId()](const auto& node) {
596         return std::get<0>(node) == id;
597     });
598     if (iter != hardCursorDrawables.end()) {
599         auto drawable = std::get<2>(*iter);
600         if (drawable && drawable->GetRenderParams()) {
601             drawable->GetRenderParams()->SetLayerCreated(false);
602         }
603     }
604 
605     // if screen power off, skip on draw, needs to draw one more frame.
606     isRenderSkipIfScreenOff_ = RSUniRenderUtil::CheckRenderSkipIfScreenOff(true, params->GetScreenId());
607     if (isRenderSkipIfScreenOff_) {
608         SetDrawSkipType(DrawSkipType::RENDER_SKIP_IF_SCREEN_OFF);
609         return;
610     }
611 
612     if (CheckScreenFreezeSkip(*params)) {
613         return;
614     }
615 
616     PostClearMemoryTask();
617 
618     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
619     if (!screenManager) {
620         SetDrawSkipType(DrawSkipType::SCREEN_MANAGER_NULL);
621         RS_LOGE("RSScreenRenderNodeDrawable::OnDraw ScreenManager is nullptr");
622         return;
623     }
624 
625     if (RSSystemProperties::IsFoldScreenFlag() && screenManager->IsScreenSwitching()) {
626         SetDrawSkipType(DrawSkipType::RENDER_SKIP_IF_SCREEN_SWITCHING);
627         RS_LOGI("RSScreenRenderNodeDrawable::OnDraw FoldScreenNodeSwitching is true, do not drawframe");
628         RS_TRACE_NAME_FMT("RSScreenRenderNodeDrawable FoldScreenNodeSwitching is true");
629         return;
630     }
631 
632     // dfx
633     RSRenderNodeDrawable::InitDfxForCacheInfo();
634     // set for cache and draw cross node in extended screen model
635     uniParam->SetIsMirrorScreen(params->IsMirrorScreen());
636     uniParam->SetCurrentVisitDisplayDrawableId(GetId());
637     uniParam->SetIsFirstVisitCrossNodeDisplay(params->IsFirstVisitCrossNodeDisplay());
638     uniParam->SetCompositeType(params->GetCompositeType());
639     params->SetDirtyAlignEnabled(uniParam->IsDirtyAlignEnabled());
640     ScreenId paramScreenId = params->GetScreenId();
641     offsetX_ = params->GetScreenOffsetX();
642     offsetY_ = params->GetScreenOffsetY();
643     curDisplayScreenId_ = paramScreenId;
644     RS_LOGD("RSScreenRenderNodeDrawable::OnDraw curScreenId=[%{public}" PRIu64 "], "
645         "offsetX=%{public}d, offsetY=%{public}d", paramScreenId, offsetX_, offsetY_);
646 
647     auto syncDirtyManager = GetSyncDirtyManager();
648     const RectI& dirtyRegion = syncDirtyManager->GetCurrentFrameDirtyRegion();
649     const auto& activeSurfaceRect = syncDirtyManager->GetActiveSurfaceRect().IsEmpty() ?
650         syncDirtyManager->GetSurfaceRect() : syncDirtyManager->GetActiveSurfaceRect();
651     uint32_t vsyncRefreshRate = RSMainThread::Instance()->GetVsyncRefreshRate();
652     RS_TRACE_NAME_FMT("RSScreenRenderNodeDrawable::OnDraw[%" PRIu64 "][%" PRIu64"] zoomed(%d), "
653         "currentFrameDirty(%d, %d, %d, %d), screen(%d, %d), active(%d, %d, %d, %d), vsyncRefreshRate(%u)",
654         paramScreenId, GetId(), params->GetZoomed(),
655         dirtyRegion.left_, dirtyRegion.top_, dirtyRegion.width_, dirtyRegion.height_,
656         screenInfo.width, screenInfo.height,
657         activeSurfaceRect.left_, activeSurfaceRect.top_, activeSurfaceRect.width_, activeSurfaceRect.height_,
658         vsyncRefreshRate);
659     RS_LOGD("RSScreenRenderNodeDrawable::OnDraw node: %{public}" PRIu64 "", GetId());
660     ScreenId activeScreenId = HgmCore::Instance().GetActiveScreenId();
661 
662     // when set expectedRefreshRate, the vsyncRefreshRate maybe change from 60 to 120
663     // so that need change whether equal vsync period and whether use virtual dirty
664     if (screenInfo.skipFrameStrategy == SKIP_FRAME_BY_REFRESH_RATE) {
665         bool isEqualVsyncPeriod = (vsyncRefreshRate == screenInfo.expectedRefreshRate);
666         if (screenInfo.isEqualVsyncPeriod != isEqualVsyncPeriod) {
667             screenInfo.isEqualVsyncPeriod = isEqualVsyncPeriod;
668             screenManager->SetEqualVsyncPeriod(paramScreenId, isEqualVsyncPeriod);
669         }
670     }
671     screenManager->RemoveForceRefreshTask();
672 
673     bool isVirtualExpandComposite =
674         params->GetCompositeType() == CompositeType::UNI_RENDER_EXPAND_COMPOSITE;
675     if (isVirtualExpandComposite) {
676         RSUniDirtyComputeUtil::UpdateVirtualExpandScreenAccumulatedParams(*params, *this);
677         if (RSUniDirtyComputeUtil::CheckVirtualExpandScreenSkip(*params, *this)) {
678             RS_TRACE_NAME("VirtualExpandScreenNode skip");
679             return;
680         }
681     }
682 
683     if (SkipFrame(vsyncRefreshRate, screenInfo)) {
684         SetDrawSkipType(DrawSkipType::SKIP_FRAME);
685         RS_TRACE_NAME_FMT("SkipFrame, screenId:%lu, strategy:%d, interval:%u, refreshrate:%u", paramScreenId,
686             screenInfo.skipFrameStrategy, screenInfo.skipFrameInterval, screenInfo.expectedRefreshRate);
687         screenManager->PostForceRefreshTask();
688         return;
689     }
690     if (!screenInfo.isEqualVsyncPeriod) {
691         uniParam->SetVirtualDirtyRefresh(true);
692     }
693 
694     auto processor = RSProcessorFactory::CreateProcessor(params->GetCompositeType());
695     if (!processor) {
696         SetDrawSkipType(DrawSkipType::CREATE_PROCESSOR_FAIL);
697         RS_LOGE("RSScreenRenderNodeDrawable::OnDraw RSProcessor is null!");
698         return;
699     }
700 
701     uniParam->SetRSProcessor(processor);
702     auto mirroredDrawable = params->GetMirrorSourceDrawable().lock();
703     auto mirroredRenderParams = mirroredDrawable ?
704         static_cast<RSScreenRenderParams*>(mirroredDrawable->GetRenderParams().get()) : nullptr;
705     if (mirroredRenderParams ||
706         params->GetCompositeType() == CompositeType::UNI_RENDER_EXPAND_COMPOSITE) {
707         DirtyStatusAutoUpdate dirtyStatusAutoUpdate(*uniParam, params->GetChildDisplayCount() == 1);
708         if (!processor->InitForRenderThread(*this, RSUniRenderThread::Instance().GetRenderEngine())) {
709             SetDrawSkipType(DrawSkipType::RENDER_ENGINE_NULL);
710             syncDirtyManager_->ResetDirtyAsSurfaceSize();
711             syncDirtyManager_->UpdateDirty(false);
712             RS_LOGE("RSScreenRenderNodeDrawable::OnDraw processor init failed!");
713             return;
714         }
715         if (mirroredRenderParams) {
716             offsetX_ = mirroredRenderParams->GetScreenOffsetX();
717             offsetY_ = mirroredRenderParams->GetScreenOffsetY();
718             RSUniRenderThread::Instance().SetEnableVisibleRect(screenInfo.enableVisibleRect);
719             if (screenInfo.enableVisibleRect) {
720                 const auto& rect = screenManager->GetMirrorScreenVisibleRect(paramScreenId);
721                 auto curVisibleRect = Drawing::RectI(rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
722                 RSUniRenderThread::Instance().SetVisibleRect(curVisibleRect);
723             }
724             if (params->GetCompositeType() == CompositeType::UNI_RENDER_COMPOSITE) {
725                 SetDrawSkipType(DrawSkipType::WIRED_SCREEN_PROJECTION);
726                 RSUniRenderThread::Instance().WaitUntilScreenNodeBufferReleased(*this);
727                 expandRenderFrame_ = RequestFrame(*params, processor);
728                 if (!expandRenderFrame_) {
729                     SetDrawSkipType(DrawSkipType::REQUEST_FRAME_FAIL);
730                     RS_LOGE("RSScreenRenderNodeDrawable::OnDraw failed to request frame");
731                     return;
732                 }
733                 auto drSurface = expandRenderFrame_->GetFrame()->GetSurface();
734                 if (!drSurface) {
735                     RS_LOGE("RSScreenRenderNodeDrawable::OnDraw DrawingSurface is null");
736                     return;
737                 }
738                 curCanvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
739                 RSRenderNodeDrawable::OnDraw(*curCanvas_);
740                 expandRenderFrame_->Flush();
741                 processor->ProcessScreenSurfaceForRenderThread(*this);
742                 HardCursorCreateLayer(processor);
743                 processor->PostProcess();
744                 expandRenderFrame_ = nullptr;
745                 return;
746             }
747             auto virtualProcessor = RSProcessor::ReinterpretCast<RSUniRenderVirtualProcessor>(processor);
748             if (!virtualProcessor) {
749                 RS_LOGE("RSScreenRenderNodeDrawable::OnDraw virtualProcessor is null!");
750                 return;
751             }
752             curCanvas_ = virtualProcessor->GetCanvas();
753             RSRenderNodeDrawable::OnDraw(*curCanvas_);
754             params->ResetVirtualExpandAccumulatedParams();
755         } else {
756             RS_LOGD("RSScreenRenderNodeDrawable::OnDraw Expand screen.");
757             bool isOpDropped = uniParam->IsOpDropped();
758             uniParam->SetOpDropped(false);
759             auto expandProcessor = RSProcessor::ReinterpretCast<RSUniRenderVirtualProcessor>(processor);
760             if (!expandProcessor) {
761                 SetDrawSkipType(DrawSkipType::EXPAND_PROCESSOR_NULL);
762                 RS_LOGE("RSScreenRenderNodeDrawable::OnDraw expandProcessor is null!");
763                 return;
764             }
765             RSDirtyRectsDfx rsDirtyRectsDfx(*this);
766             std::vector<RectI> damageRegionRects;
767             // disable expand screen dirty when isEqualVsyncPeriod is false, because the dirty history is incorrect
768             if (uniParam->IsExpandScreenDirtyEnabled() && uniParam->IsVirtualDirtyEnabled() &&
769                 screenInfo.isEqualVsyncPeriod) {
770                 int32_t bufferAge = expandProcessor->GetBufferAge();
771                 damageRegionRects = RSUniRenderUtil::MergeDirtyHistory(
772                     *this, bufferAge, screenInfo, rsDirtyRectsDfx, *params);
773                 uniParam->Reset();
774                 if (!uniParam->IsVirtualDirtyDfxEnabled()) {
775                     expandProcessor->SetDirtyInfo(damageRegionRects);
776                 }
777             } else {
778                 std::vector<RectI> emptyRects = {};
779                 expandProcessor->SetRoiRegionToCodec(emptyRects);
780             }
781             rsDirtyRectsDfx.SetVirtualDirtyRects(damageRegionRects, screenInfo);
782             curCanvas_ = expandProcessor->GetCanvas();
783             curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
784             RSRenderNodeDrawable::OnDraw(*curCanvas_);
785             params->ResetVirtualExpandAccumulatedParams();
786             auto targetSurfaceRenderNodeDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(
787                 params->GetTargetSurfaceRenderNodeDrawable().lock());
788             if ((targetSurfaceRenderNodeDrawable || params->HasMirrorScreen()) && curCanvas_->GetSurface()) {
789                 RS_TRACE_NAME("DrawExpandScreen cacheImgForMultiScreenView");
790                 cacheImgForMultiScreenView_ = curCanvas_->GetSurface()->GetImageSnapshot();
791             } else {
792                 cacheImgForMultiScreenView_ = nullptr;
793             }
794             // Restore the initial state of the canvas to avoid state accumulation
795             curCanvas_->RestoreToCount(0);
796             if (curCanvas_) {
797                 rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
798             }
799             uniParam->SetOpDropped(isOpDropped);
800         }
801         DrawCurtainScreen();
802         processor->PostProcess();
803         SetDrawSkipType(DrawSkipType::MIRROR_DRAWABLE_SKIP);
804         return;
805     }
806 
807     bool isHdrOn = params->GetHDRPresent();
808     // 0 means defalut hdrBrightnessRatio
809     float hdrBrightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(paramScreenId, 0);
810 #ifdef RS_ENABLE_OVERLAY_DISPLAY // only for TV
811     /*
812      * Force hdrBrightnessRatio to be set to 1.0 when overlay_display display enabled.
813      * Do not change pixel value; the pixel value is encoded when overlay display enabled.
814      * If hdrBrightnessRatio is not equal 1.0, DSS will change the pixel value, so the
815      * decoded pixels is wrong and display is abnormal.
816      */
817     if (RSOverlayDisplayManager::Instance().IsOverlayDisplayEnableForCurrentVsync()) {
818         hdrBrightnessRatio = 1.0f;
819     }
820 #endif
821     if (!isHdrOn) {
822         params->SetBrightnessRatio(hdrBrightnessRatio);
823         hdrBrightnessRatio = 1.0f;
824     }
825     params->SetHdrBrightnessRatio(hdrBrightnessRatio);
826     RS_LOGD("RSScreenRenderNodeDrawable::OnDraw HDRDraw isHdrOn: %{public}d, BrightnessRatio: %{public}f",
827         isHdrOn, hdrBrightnessRatio);
828 
829     // checkScreenNodeSkip need to be judged at the end
830     if (RSAncoManager::Instance()->GetAncoHebcStatus() == AncoHebcStatus::INITIAL &&
831         uniParam->IsOpDropped() && CheckScreenNodeSkip(*params, processor)) {
832         SetDrawSkipType(DrawSkipType::SCREEN_NODE_SKIP);
833         RSMainThread::Instance()->SetFrameIsRender(false);
834         SetScreenNodeSkipFlag(*uniParam, true);
835         return;
836     }
837     SetScreenNodeSkipFlag(*uniParam, false);
838     RSMainThread::Instance()->SetFrameIsRender(true);
839 
840     if (filterCacheOcclusionUpdated_) {
841         filterCacheOcclusionUpdated_ = false;
842     } else {
843         CheckAndUpdateFilterCacheOcclusion(*params, screenInfo);
844     }
845     if (isHdrOn) {
846         params->SetNewPixelFormat(RSHdrUtil::GetRGBA1010108Enabled() && params->GetExistHWCNode() ?
847             GRAPHIC_PIXEL_FMT_RGBA_1010108 : GRAPHIC_PIXEL_FMT_RGBA_1010102);
848     }
849     // hpae offline: post offline task
850     CheckAndPostAsyncProcessOfflineTask();
851     RSUniRenderThread::Instance().WaitUntilScreenNodeBufferReleased(*this);
852     // displayNodeSp to get  rsSurface witch only used in renderThread
853     auto renderFrame = RequestFrame(*params, processor);
854     if (!renderFrame) {
855         SetDrawSkipType(DrawSkipType::REQUEST_FRAME_FAIL);
856         RS_LOGE("RSScreenRenderNodeDrawable::OnDraw failed to request frame");
857         return;
858     }
859 
860     UpdateSlrScale(screenInfo);
861     RSDirtyRectsDfx rsDirtyRectsDfx(*this);
862     std::vector<RectI> damageRegionrects;
863     std::vector<RectI> curFrameVisibleRegionRects;
864     Drawing::Region clipRegion;
865     if (uniParam->IsPartialRenderEnabled()) {
866         damageRegionrects = RSUniRenderUtil::MergeDirtyHistory(
867             *this, renderFrame->GetBufferAge(), screenInfo, rsDirtyRectsDfx, *params);
868         curFrameVisibleRegionRects = RSUniDirtyComputeUtil::GetCurrentFrameVisibleDirty(*this, screenInfo, *params);
869         uniParam->Reset();
870         clipRegion = GetFlippedRegion(damageRegionrects, screenInfo);
871         RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
872             damageRegionrects.size(), RectVectorToString(damageRegionrects).c_str());
873         if (!uniParam->IsRegionDebugEnabled()) {
874             renderFrame->SetDamageRegion(damageRegionrects);
875         }
876     }
877 
878     auto drSurface = renderFrame->GetFrame()->GetSurface();
879     if (!drSurface) {
880         SetDrawSkipType(DrawSkipType::SURFACE_NULL);
881         RS_LOGE("RSScreenRenderNodeDrawable::OnDraw DrawingSurface is null");
882         return;
883     }
884 
885     curCanvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
886     if (!curCanvas_) {
887         SetDrawSkipType(DrawSkipType::CANVAS_NULL);
888         RS_LOGE("RSScreenRenderNodeDrawable::OnDraw failed to create canvas");
889         return;
890     }
891     curCanvas_->SetDrawnRegion(params->GetDrawnRegion());
892     curCanvas_->SetTargetColorGamut(params->GetNewColorSpace());
893     curCanvas_->SetScreenId(paramScreenId);
894     curCanvas_->SetHdrOn(isHdrOn);
895     curCanvas_->SetDisableFilterCache(params->GetZoomed());
896 
897 #ifdef DDGR_ENABLE_FEATURE_OPINC
898     if (RSOpincDrawCache::IsAutoCacheEnable()) {
899         RSOpincDrawCache::SetScreenRectInfo({0, 0, screenInfo.width, screenInfo.height});
900     }
901 #endif
902     UpdateSurfaceDrawRegion(curCanvas_, params);
903 
904     // canvas draw
905     {
906         {
907             RSSkpCaptureDfx capture(curCanvas_);
908             Drawing::AutoCanvasRestore acr(*curCanvas_, true);
909 
910 #ifdef SUBTREE_PARALLEL_ENABLE
911             RSParallelManager::Singleton().Reset(curCanvas_, uniParam, params, vsyncRefreshRate);
912 #endif
913             if (uniParam->IsOpDropped()) {
914                 if (uniParam->IsDirtyAlignEnabled()) {
915                     RS_TRACE_NAME_FMT("dirty align enabled and no clip operation");
916                     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
917                 } else {
918                     uniParam->SetClipRegion(clipRegion);
919                     ClipRegion(*curCanvas_, clipRegion);
920                 }
921             } else {
922                 curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
923             }
924             // just used in SubTree, used for check whether a new Surface needs to be created in the SubTree thread.
925             curCanvas_->SetWeakSurface(drSurface);
926 
927             curCanvas_->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
928             // cpu boost feature start
929             ffrt_cpu_boost_start(CPUBOOST_START_POINT + 1);
930             RSRenderNodeDrawable::OnDraw(*curCanvas_);
931             // cpu boost feature end
932             ffrt_cpu_boost_end(CPUBOOST_START_POINT + 1);
933             curCanvas_->Save();
934             curCanvas_->ResetMatrix();
935             if (screenInfo.isSamplingOn) {
936                 curCanvas_->ConcatMatrix(params->GetSlrMatrix());
937             }
938             rsDirtyRectsDfx.OnDraw(*curCanvas_);
939             curCanvas_->Restore();
940             DrawCurtainScreen();
941             bool displayP3Enable = (params->GetNewColorSpace() == GRAPHIC_COLOR_GAMUT_DISPLAY_P3);
942             RSUniRenderUtil::SwitchColorFilter(*curCanvas_, hdrBrightnessRatio, displayP3Enable);
943 
944 #ifdef RS_ENABLE_OVERLAY_DISPLAY
945             // add post filter for TV overlay display conversion
946             RSOverlayDisplayManager::Instance().PostProcFilter(*curCanvas_);
947 #endif
948             auto dirtyManager = GetSyncDirtyManager();
949             const auto& activeRect = dirtyManager->GetActiveSurfaceRect();
950             if (!activeRect.IsEmpty() && (!dirtyManager->GetDirtyRegion().IsInsideOf(activeRect) ||
951                 !uniParam->IsPartialRenderEnabled() || uniParam->IsRegionDebugEnabled())) {
952                 RS_TRACE_NAME_FMT("global dirty region:[%s] is not inside of active surface rect:[%s], "
953                     "clear extra area to black", dirtyManager->GetDirtyRegion().ToString().c_str(),
954                     activeRect.ToString().c_str());
955                 curCanvas_->Save();
956                 auto activeRegion = RSUniDirtyComputeUtil::ScreenIntersectDirtyRects(
957                     Occlusion::Region(activeRect), screenInfo);
958                 curCanvas_->ClipRegion(GetFlippedRegion(activeRegion, screenInfo), Drawing::ClipOp::DIFFERENCE);
959                 curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
960                 curCanvas_->Restore();
961             }
962         }
963 
964         if (RSSystemProperties::GetDrawMirrorCacheImageEnabled() && params->HasMirrorScreen() &&
965             curCanvas_->GetSurface() != nullptr) {
966             cacheImgForMultiScreenView_ = curCanvas_->GetSurface()->GetImageSnapshot();
967         } else {
968             cacheImgForMultiScreenView_ = nullptr;
969         }
970     }
971     RenderOverDraw();
972     RSMainThread::Instance()->SetDirtyFlag(false);
973 
974     if (Drawing::PerformanceCaculate::GetDrawingFlushPrint()) {
975         RS_LOGI("Drawing Performance Flush start %{public}lld", Drawing::PerformanceCaculate::GetUpTime(false));
976     }
977 #ifdef SUBTREE_PARALLEL_ENABLE
978     // Wait for all sub threads process completely.
979     RSParallelManager::Singleton().WaitUntilSubTreeFinish(curCanvas_);
980 #endif
981     RS_TRACE_BEGIN("RSScreenRenderNodeDrawable Flush");
982     RsFrameReport::GetInstance().CheckBeginFlushPoint();
983     Drawing::GPUResourceTag::SetCurrentNodeId(GetId());
984 
985     renderFrame->Flush();
986     RS_TRACE_END();
987     if (Drawing::PerformanceCaculate::GetDrawingFlushPrint()) {
988         RS_LOGI("Drawing Performance Flush end %{public}lld", Drawing::PerformanceCaculate::GetUpTime(false));
989         Drawing::PerformanceCaculate::ResetCaculateTimeCount();
990     }
991 
992     // process round corner display
993     DoScreenRcdTask(*params, processor);
994 
995     if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
996         RS_LOGW("RSScreenRenderNodeDrawable::ondraw: hardwareThread task has too many to Execute"
997                 " TaskNum:[%{public}d]", RSHardwareThread::Instance().GetunExecuteTaskNum());
998         RSHardwareThread::Instance().DumpEventQueue();
999     }
1000 
1001     RS_TRACE_BEGIN("RSScreenRenderNodeDrawable CommitLayer");
1002     for (const auto& [screenNodeId, _, drawable] : hardwareDrawables) {
1003         if (UNLIKELY(!drawable || !drawable->GetRenderParams())) {
1004             continue;
1005         }
1006         auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
1007         if (!surfaceDrawable || screenNodeId != params->GetId()) {
1008             continue;
1009         }
1010         if (drawable->GetRenderParams()->GetHardwareEnabled()) {
1011             auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
1012             // hpae offline: wait task and create layer
1013             if (surfaceParams->GetLayerInfo().useDeviceOffline &&
1014                 ProcessOfflineSurfaceDrawable(processor, surfaceDrawable, true)) {
1015                 continue;
1016             }
1017             processor->CreateLayerForRenderThread(*surfaceDrawable);
1018         }
1019     }
1020     HardCursorCreateLayer(processor);
1021     if (screenInfo.activeRect.IsEmpty() ||
1022         screenInfo.activeRect == RectI(0, 0, screenInfo.width, screenInfo.height) ||
1023         DirtyRegionParam::IsComposeDirtyRegionEnableInPartialDisplay()) {
1024         if (uniParam->IsRegionDebugEnabled()) {
1025             std::vector<RectI> emptyRegionRects = {};
1026             SetDirtyRects(emptyRegionRects);
1027         } else {
1028             SetDirtyRects(RSSystemProperties::GetOptimizeHwcComposeAreaEnabled() ?
1029                 curFrameVisibleRegionRects : damageRegionrects);
1030         }
1031     } else {
1032         SetDirtyRects({GetSyncDirtyManager()->GetRectFlipWithinSurface(screenInfo.activeRect)});
1033     }
1034     processor->ProcessScreenSurfaceForRenderThread(*this);
1035     processor->PostProcess();
1036     RS_TRACE_END();
1037 
1038 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1039     if (RSMagicPointerRenderManager::GetInstance().GetPointerColorInversionEnabled() && !mirroredDrawable) {
1040         RSMagicPointerRenderManager::GetInstance().ProcessColorPicker(processor, curCanvas_->GetGPUContext());
1041         RSMagicPointerRenderManager::GetInstance().SetCacheImgForPointer(nullptr);
1042     }
1043 #endif
1044 }
1045 
UpdateSlrScale(ScreenInfo & screenInfo)1046 void RSScreenRenderNodeDrawable::UpdateSlrScale(ScreenInfo& screenInfo)
1047 {
1048     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1049     uniParam->SetSLRScaleManager(nullptr);
1050     if (screenInfo.isSamplingOn && RSSystemProperties::GetSLRScaleEnabled()) {
1051         auto scaleManager = std::make_shared<RSSLRScaleFunction>(
1052             screenInfo.phyWidth, screenInfo.phyHeight, screenInfo.width, screenInfo.height);
1053         screenInfo.samplingDistance = scaleManager->GetKernelSize();
1054         uniParam->SetSLRScaleManager(scaleManager);
1055     }
1056 }
1057 
DrawCurtainScreen() const1058 void RSScreenRenderNodeDrawable::DrawCurtainScreen() const
1059 {
1060     if (!RSUniRenderThread::Instance().IsCurtainScreenOn() || !curCanvas_) {
1061         return;
1062     }
1063     RS_TRACE_FUNC();
1064     curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
1065 }
1066 
UpdateSurfaceDrawRegion(std::shared_ptr<RSPaintFilterCanvas> & mainCanvas,RSScreenRenderParams * params)1067 void RSScreenRenderNodeDrawable::UpdateSurfaceDrawRegion(std::shared_ptr<RSPaintFilterCanvas>& mainCanvas,
1068     RSScreenRenderParams* params)
1069 {
1070     auto& curAllSurfaces = params->GetAllMainAndLeashSurfaceDrawables();
1071 
1072     for (auto& renderNodeDrawable : curAllSurfaces) {
1073         if (renderNodeDrawable != nullptr &&
1074             renderNodeDrawable->GetNodeType() == RSRenderNodeType::SURFACE_NODE) {
1075             auto surfaceNodeDrawable =
1076                 std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(renderNodeDrawable);
1077             surfaceNodeDrawable->UpdateSurfaceDirtyRegion(mainCanvas);
1078         }
1079     }
1080 }
1081 
1082 #ifndef ROSEN_CROSS_PLATFORM
CreateSurface(sptr<IBufferConsumerListener> listener)1083 bool RSScreenRenderNodeDrawable::CreateSurface(sptr<IBufferConsumerListener> listener)
1084 {
1085     auto consumer = surfaceHandler_->GetConsumer();
1086     if (consumer != nullptr && surface_ != nullptr) {
1087         RS_LOGI("RSScreenRenderNodeDrawable::CreateSurface already created, return");
1088         return true;
1089     }
1090     consumer = IConsumerSurface::Create("ScreenNode");
1091     if (consumer == nullptr) {
1092         RS_LOGE("RSScreenRenderNodeDrawable::CreateSurface get consumer surface fail");
1093         return false;
1094     }
1095     SurfaceError ret = consumer->RegisterConsumerListener(listener);
1096     if (ret != SURFACE_ERROR_OK) {
1097         RS_LOGE("RSScreenRenderNodeDrawable::CreateSurface RegisterConsumerListener fail");
1098         return false;
1099     }
1100     consumerListener_ = listener;
1101     auto producer = consumer->GetProducer();
1102     sptr<Surface> surface = Surface::CreateSurfaceAsProducer(producer);
1103     if (!surface) {
1104         RS_LOGE("RSScreenRenderNodeDrawable::CreateSurface CreateSurfaceAsProducer fail");
1105         return false;
1106     }
1107     surface->SetQueueSize(BUFFER_SIZE);
1108     auto client = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
1109     surface_ = client->CreateRSSurface(surface);
1110     RS_LOGI("RSScreenRenderNodeDrawable::CreateSurface end");
1111     surfaceCreated_ = true;
1112     surfaceHandler_->SetConsumer(consumer);
1113     return true;
1114 }
1115 #endif
1116 
SkipFrameByInterval(uint32_t refreshRate,uint32_t skipFrameInterval)1117 bool RSScreenRenderNodeDrawable::SkipFrameByInterval(uint32_t refreshRate, uint32_t skipFrameInterval)
1118 {
1119     if (refreshRate == 0 || skipFrameInterval <= 1) {
1120         return false;
1121     }
1122     int64_t currentTime = std::chrono::duration_cast<std::chrono::nanoseconds>(
1123         std::chrono::steady_clock::now().time_since_epoch()).count();
1124     // the skipFrameInterval is equal to 60 divide the virtual screen refresh rate
1125     int64_t refreshInterval = currentTime - lastRefreshTime_;
1126     // 1000000000ns == 1s, 110/100 allows 10% over.
1127     bool needSkip = refreshInterval < (1000000000LL / refreshRate) * (skipFrameInterval - 1) * 110 / 100;
1128     if (!needSkip) {
1129         lastRefreshTime_ = currentTime;
1130     }
1131     return needSkip;
1132 }
1133 
SkipFrameByRefreshRate(uint32_t refreshRate,uint32_t expectedRefreshRate)1134 bool RSScreenRenderNodeDrawable::SkipFrameByRefreshRate(uint32_t refreshRate, uint32_t expectedRefreshRate)
1135 {
1136     if (refreshRate == 0 || expectedRefreshRate == 0 || refreshRate == expectedRefreshRate) {
1137         return false;
1138     }
1139     int64_t currentTime = RSMainThread::Instance()->GetCurrentVsyncTime();
1140     int64_t minFrameInterval = 1000000000LL / expectedRefreshRate;
1141     if (minFrameInterval == 0) {
1142         return false;
1143     }
1144     // lastRefreshTime_ is next frame expected refresh time for virtual display
1145     if (lastRefreshTime_ <= 0) {
1146         lastRefreshTime_ = currentTime + minFrameInterval;
1147         return false;
1148     }
1149     if (currentTime < (lastRefreshTime_ - MAX_JITTER_NS)) {
1150         return true;
1151     }
1152     int64_t intervalNums = (currentTime - lastRefreshTime_ + MAX_JITTER_NS) / minFrameInterval;
1153     lastRefreshTime_ += (intervalNums + 1) * minFrameInterval;
1154     return false;
1155 }
1156 
SkipFrame(uint32_t refreshRate,ScreenInfo screenInfo)1157 bool RSScreenRenderNodeDrawable::SkipFrame(uint32_t refreshRate, ScreenInfo screenInfo)
1158 {
1159     bool needSkip = false;
1160     switch (screenInfo.skipFrameStrategy) {
1161         case SKIP_FRAME_BY_INTERVAL:
1162             needSkip = SkipFrameByInterval(refreshRate, screenInfo.skipFrameInterval);
1163             break;
1164         case SKIP_FRAME_BY_REFRESH_RATE:
1165             needSkip = SkipFrameByRefreshRate(refreshRate, screenInfo.expectedRefreshRate);
1166             break;
1167         default:
1168             break;
1169     }
1170     return needSkip;
1171 }
1172 
ProcessOfflineSurfaceDrawable(const std::shared_ptr<RSProcessor> & processor,std::shared_ptr<RSSurfaceRenderNodeDrawable> & surfaceDrawable,bool async)1173 bool RSScreenRenderNodeDrawable::ProcessOfflineSurfaceDrawable(
1174     const std::shared_ptr<RSProcessor>& processor,
1175     std::shared_ptr<RSSurfaceRenderNodeDrawable>& surfaceDrawable, bool async)
1176 {
1177     if (processor->ProcessOfflineLayer(surfaceDrawable, async)) {
1178         // use offline layer to display
1179         return true;
1180     }
1181     // reset offline tag, use original layer to display
1182     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceDrawable->GetRenderParams().get());
1183     surfaceParams->SetUseDeviceOffline(false);
1184     return false;
1185 }
1186 
CheckAndPostAsyncProcessOfflineTask()1187 void RSScreenRenderNodeDrawable::CheckAndPostAsyncProcessOfflineTask()
1188 {
1189     auto& hardwareDrawables =
1190         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
1191     for (const auto& [screenNodeId, _, drawable] : hardwareDrawables) {
1192         if (UNLIKELY(!drawable || !drawable->GetRenderParams())) {
1193             continue;
1194         }
1195         auto params = static_cast<RSScreenRenderParams*>(renderParams_.get());
1196         if (screenNodeId != params->GetId()) {
1197             continue;
1198         }
1199         auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
1200         if (surfaceDrawable->GetRenderParams()->GetHardwareEnabled() &&
1201             surfaceDrawable->GetRenderParams()->GetLayerInfo().useDeviceOffline) {
1202             if (!RSHpaeOfflineProcessor::GetOfflineProcessor().PostProcessOfflineTask(
1203                 surfaceDrawable, RSUniRenderThread::Instance().GetVsyncId())) {
1204                 RS_LOGW("RSUniRenderProcessor::ProcessSurface: post offline task failed, go redraw");
1205             }
1206         }
1207     }
1208 }
1209 
CheckScreenFreezeSkip(RSScreenRenderParams & params)1210 bool RSScreenRenderNodeDrawable::CheckScreenFreezeSkip(RSScreenRenderParams& params)
1211 {
1212     if (UNLIKELY(params.GetForceFreeze())) {
1213         SetDrawSkipType(DrawSkipType::SCREEN_FREEZE);
1214         RS_TRACE_NAME("Screen frozen, skip");
1215         return true;
1216     }
1217 
1218     auto mirrorDrawable = params.GetMirrorSourceDrawable().lock();
1219     if (!mirrorDrawable) {
1220         return false;
1221     }
1222     auto mirrorParams = static_cast<RSScreenRenderParams*>(mirrorDrawable->GetRenderParams().get());
1223     if (mirrorParams && UNLIKELY(mirrorParams->GetForceFreeze())) {
1224         RS_TRACE_NAME("MirrorScreen frozen, skip");
1225         SetDrawSkipType(DrawSkipType::SCREEN_FREEZE);
1226         return true;
1227     }
1228     return false;
1229 }
1230 
1231 } // namespace OHOS::Rosen::DrawableV2
1232