• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "drawable/rs_display_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 "include/gpu/vk/GrVulkanTrackerInterface.h"
27 #include "common/rs_common_def.h"
28 #include "common/rs_optional_trace.h"
29 #include "common/rs_singleton.h"
30 #include "common/rs_special_layer_manager.h"
31 #include "display_engine/rs_luminance_control.h"
32 #include "drawable/rs_surface_render_node_drawable.h"
33 #ifdef RS_ENABLE_OVERLAY_DISPLAY
34 #include "feature/overlay_display/rs_overlay_display_manager.h"
35 #endif
36 #include "hgm_core.h"
37 #include "memory/rs_tag_tracker.h"
38 #include "params/rs_display_render_params.h"
39 #include "params/rs_surface_render_params.h"
40 #include "feature/anco_manager/rs_anco_manager.h"
41 #include "feature/round_corner_display/rs_rcd_surface_render_node.h"
42 #include "feature/round_corner_display/rs_rcd_surface_render_node_drawable.h"
43 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
44 #include "feature/round_corner_display/rs_message_bus.h"
45 #include "feature/uifirst/rs_uifirst_manager.h"
46 #include "pipeline/render_thread/rs_base_render_engine.h"
47 #include "pipeline/rs_display_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.h"
63 #include "property/rs_point_light_manager.h"
64 #include "render/rs_pixel_map_util.h"
65 #include "screen_manager/rs_screen_manager.h"
66 #include "static_factory.h"
67 #include "rs_frame_report.h"
68 // dfx
69 #include "drawable/dfx/rs_dirty_rects_dfx.h"
70 #include "drawable/dfx/rs_skp_capture_dfx.h"
71 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
72 #include "utils/performanceCaculate.h"
73 // cpu boost
74 #include "c/ffrt_cpu_boost.h"
75 // xml parser
76 #include "graphic_feature_param_manager.h"
77 namespace OHOS::Rosen::DrawableV2 {
78 namespace {
79 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
80 constexpr const char* DEFAULT_CLEAR_GPU_CACHE = "DefaultClearGpuCache";
81 constexpr int32_t NO_SPECIAL_LAYER = 0;
82 constexpr int32_t HAS_SPECIAL_LAYER = 1;
83 constexpr int32_t CAPTURE_WINDOW = 2; // To be deleted after captureWindow being deleted
84 constexpr int64_t MAX_JITTER_NS = 2000000; // 2ms
85 constexpr const float HALF = 2.0f;
86 static std::once_flag g_initTranslateForWallpaperFlag;
87 
RectVectorToString(std::vector<RectI> & regionRects)88 std::string RectVectorToString(std::vector<RectI>& regionRects)
89 {
90     std::string results = "";
91     for (auto& rect : regionRects) {
92         results += rect.ToString();
93     }
94     return results;
95 }
96 
GetFlippedRegion(const std::vector<RectI> & rects,ScreenInfo & screenInfo)97 Drawing::Region GetFlippedRegion(const std::vector<RectI>& rects, ScreenInfo& screenInfo)
98 {
99     Drawing::Region region;
100 
101     for (const auto& r : rects) {
102         int32_t topAfterFilp = 0;
103 #ifdef RS_ENABLE_VK
104         topAfterFilp = (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
105                            RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR)
106                            ? r.top_
107                            : static_cast<int32_t>(screenInfo.GetRotatedHeight()) - r.GetBottom();
108 #else
109         topAfterFilp = static_cast<int32_t>(screenInfo.GetRotatedHeight()) - r.GetBottom();
110 #endif
111         Drawing::Region tmpRegion;
112         tmpRegion.SetRect(Drawing::RectI(r.left_, topAfterFilp, r.left_ + r.width_, topAfterFilp + r.height_));
113         RS_OPTIONAL_TRACE_NAME_FMT("GetFlippedRegion orig ltrb[%d %d %d %d] to fliped rect ltrb[%d %d %d %d]",
114             r.left_, r.top_, r.left_ + r.width_, r.top_ + r.height_, r.left_, topAfterFilp, r.left_ + r.width_,
115             topAfterFilp + r.height_);
116         region.Op(tmpRegion, Drawing::RegionOp::UNION);
117     }
118     return region;
119 }}  // namespace
120 
121 // Rcd node will be handled by RS tree in OH 6.0 rcd refactoring, should remove this later
DoScreenRcdTask(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> & processor)122 void DoScreenRcdTask(RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> &processor)
123 {
124     if (processor == nullptr) {
125         RS_LOGD("DoScreenRcdTask has no processor");
126         return;
127     }
128     const auto &screenInfo = params.GetScreenInfo();
129     if (screenInfo.state != ScreenState::HDI_OUTPUT_ENABLE) {
130         RS_LOGD("DoScreenRcdTask is not at HDI_OUPUT mode");
131         return;
132     }
133 
134     bool res = true;
135     bool resourceChanged = false;
136     auto drawables = params.GetRoundCornerDrawables();
137     for (auto drawable : drawables) {
138         auto rcdDrawable = std::static_pointer_cast<DrawableV2::RSRcdSurfaceRenderNodeDrawable>(drawable);
139         if (rcdDrawable) {
140             resourceChanged |= rcdDrawable->IsResourceChanged();
141             res &= rcdDrawable->DoProcessRenderTask(processor);
142         }
143     }
144     if (resourceChanged && res) {
145         RSSingleton<RsMessageBus>::GetInstance().SendMsg<NodeId, bool>(
146             TOPIC_RCD_DISPLAY_HWRESOURCE, params.GetId(), true);
147     }
148 }
149 
150 RSDisplayRenderNodeDrawable::Registrar RSDisplayRenderNodeDrawable::instance_;
151 std::shared_ptr<Drawing::RuntimeEffect> RSDisplayRenderNodeDrawable::brightnessAdjustmentShaderEffect_ = nullptr;
152 
RSDisplayRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)153 RSDisplayRenderNodeDrawable::RSDisplayRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
154     : RSRenderNodeDrawable(std::move(node)), surfaceHandler_(std::make_shared<RSSurfaceHandler>(nodeId_)),
155       syncDirtyManager_(std::make_shared<RSDirtyRegionManager>(true))
156 {}
157 
~RSDisplayRenderNodeDrawable()158 RSDisplayRenderNodeDrawable::~RSDisplayRenderNodeDrawable()
159 {
160     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
161     if (renderEngine) {
162         renderEngine->ClearVirtualScreenCacheSet();
163     }
164 }
165 
OnGenerate(std::shared_ptr<const RSRenderNode> node)166 RSRenderNodeDrawable::Ptr RSDisplayRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
167 {
168     return new RSDisplayRenderNodeDrawable(std::move(node));
169 }
170 
InitTranslateForWallpaper()171 void RSDisplayRenderNodeDrawable::InitTranslateForWallpaper()
172 {
173     if (!RSSystemProperties::GetCacheOptimizeRotateEnable()) {
174         return;
175     }
176     std::call_once(g_initTranslateForWallpaperFlag, [this]() { CalculateTranslationForWallpaper(); });
177 }
178 
CalculateTranslationForWallpaper()179 void RSDisplayRenderNodeDrawable::CalculateTranslationForWallpaper()
180 {
181     if (!RSSystemProperties::GetCacheOptimizeRotateEnable()) {
182         return;
183     }
184     auto params = static_cast<RSDisplayRenderParams*>(renderParams_.get());
185     if (UNLIKELY(!params)) {
186         return;
187     }
188     auto framesize = params->GetFrameRect();
189     int32_t offscreenWidth = static_cast<int32_t>(framesize.GetWidth());
190     int32_t offscreenHeight = static_cast<int32_t>(framesize.GetHeight());
191     int32_t screenWidth = params->GetScreenInfo().width;
192     int32_t screenHeight = params->GetScreenInfo().height;
193     auto maxRenderSize = std::ceil(std::sqrt(screenWidth * screenWidth + screenHeight * screenHeight));
194     auto translateX = std::round((maxRenderSize - offscreenWidth) / HALF);
195     auto translateY = std::round((maxRenderSize - offscreenHeight) / HALF);
196     RSUniRenderThread::Instance().SetWallpaperTranslate(translateX, translateY);
197 }
198 
RequestFrame(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)199 std::unique_ptr<RSRenderFrame> RSDisplayRenderNodeDrawable::RequestFrame(
200     RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
201 {
202     RS_TRACE_NAME("RSDisplayRenderNodeDrawable:RequestFrame");
203     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
204     if (UNLIKELY(!renderEngine)) {
205         RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame RenderEngine is null!");
206         return nullptr;
207     }
208 
209     if (!processor->InitForRenderThread(*this, INVALID_SCREEN_ID, renderEngine)) {
210         RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame processor InitForRenderThread failed!");
211         return nullptr;
212     }
213 
214     if (!IsSurfaceCreated()) {
215         sptr<IBufferConsumerListener> listener = new RSUniRenderListener(surfaceHandler_);
216         if (!CreateSurface(listener)) {
217             RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame CreateSurface failed");
218             return nullptr;
219         }
220     }
221 
222     auto rsSurface = GetRSSurface();
223     if (!rsSurface) {
224         RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame No RSSurface found");
225         return nullptr;
226     }
227     auto bufferConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(params.GetScreenInfo(), false,
228         params.GetNewColorSpace(), params.GetNewPixelFormat());
229     RS_LOGD("RequestFrame colorspace is %{public}d, pixelformat is %{public}d", params.GetNewColorSpace(),
230         params.GetNewPixelFormat());
231 
232     bool isHebc = true;
233     if (RSAncoManager::Instance()->GetAncoHebcStatus() == AncoHebcStatus::NOT_USE_HEBC) {
234         isHebc = false;
235         RS_LOGI("anco request frame not use hebc");
236     }
237     RSAncoManager::Instance()->SetAncoHebcStatus(AncoHebcStatus::INITIAL);
238 
239     auto renderFrame = renderEngine->RequestFrame(std::static_pointer_cast<RSSurfaceOhos>(rsSurface),
240         bufferConfig, false, isHebc);
241     if (!renderFrame) {
242         RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame renderEngine requestFrame is null");
243         return nullptr;
244     }
245 
246     return renderFrame;
247 }
248 
ClipRegion(Drawing::Canvas & canvas,Drawing::Region & region,bool clear=true)249 static void ClipRegion(Drawing::Canvas& canvas, Drawing::Region& region, bool clear = true)
250 {
251     if (region.IsEmpty()) {
252         // [planning] Remove this after frame buffer can cancel
253         canvas.ClipRect(Drawing::Rect());
254     } else if (region.IsRect()) {
255         canvas.ClipRegion(region);
256     } else {
257         RS_TRACE_NAME("RSDisplayDrawable: clipPath");
258 #ifdef RS_ENABLE_VK
259         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
260             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
261             canvas.ClipRegion(region);
262         } else {
263             Drawing::Path dirtyPath;
264             region.GetBoundaryPath(&dirtyPath);
265             canvas.ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
266         }
267 #else
268         Drawing::Path dirtyPath;
269         region.GetBoundaryPath(&dirtyPath);
270         canvas.ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
271 #endif
272     }
273 
274     // clear canvas after clip region if need
275     if (clear && !region.IsEmpty()) {
276         canvas.Clear(Drawing::Color::COLOR_TRANSPARENT);
277     }
278 }
279 
HardCursorCreateLayer(std::shared_ptr<RSProcessor> processor)280 bool RSDisplayRenderNodeDrawable::HardCursorCreateLayer(std::shared_ptr<RSProcessor> processor)
281 {
282     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
283     if (!uniParam) {
284         RS_LOGE("RSDisplayRenderNodeDrawable::HardCursorCreateLayer uniParam is null");
285         return false;
286     }
287     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
288     if (hardCursorDrawables.empty()) {
289         return false;
290     }
291     auto iter = hardCursorDrawables.find(GetId());
292     if (iter == hardCursorDrawables.end()) {
293         return false;
294     }
295     auto& hardCursorDrawable = iter->second;
296     if (!hardCursorDrawable) {
297         return false;
298     }
299     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(hardCursorDrawable->GetRenderParams().get());
300     if (!surfaceParams) {
301         RS_LOGE("RSDisplayRenderNodeDrawable::HardCursorCreateLayer surfaceParams is null");
302         return false;
303     }
304     auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable);
305     if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
306         processor->CreateLayerForRenderThread(*surfaceDrawable);
307         return true;
308     }
309     return false;
310 }
311 
RenderOverDraw()312 void RSDisplayRenderNodeDrawable::RenderOverDraw()
313 {
314     bool isEnabled = false;
315     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
316     if (LIKELY(uniParam)) {
317         isEnabled = uniParam->IsOverDrawEnabled();
318     }
319     bool enable = isEnabled && curCanvas_ != nullptr;
320     if (!enable) {
321         return;
322     }
323     auto gpuContext = curCanvas_->GetGPUContext();
324     if (gpuContext == nullptr) {
325         RS_LOGE("RSDisplayRenderNodeDrawable::RenderOverDraw failed: need gpu canvas");
326         return;
327     }
328     Drawing::ImageInfo info = Drawing::ImageInfo { curCanvas_->GetWidth(), curCanvas_->GetHeight(),
329         Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL };
330     auto overdrawSurface = Drawing::Surface::MakeRenderTarget(gpuContext.get(), false, info);
331     if (!overdrawSurface) {
332         RS_LOGE("RSDisplayRenderNodeDrawable::RenderOverDraw failed: surface is nullptr");
333         return;
334     }
335     auto overdrawCanvas = std::make_shared<Drawing::OverDrawCanvas>(overdrawSurface->GetCanvas());
336     overdrawCanvas->SetGrContext(gpuContext);
337     auto paintCanvas = std::make_shared<RSPaintFilterCanvas>(overdrawCanvas.get());
338     // traverse all drawable to detect overdraw
339     auto params = static_cast<RSDisplayRenderParams*>(renderParams_.get());
340     if (!params->GetNeedOffscreen()) {
341         paintCanvas->ConcatMatrix(params->GetMatrix());
342     }
343     RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable::RenderOverDraw");
344     RSRenderNodeDrawable::OnDraw(*paintCanvas);
345     DrawWatermarkIfNeed(*params, *paintCanvas);
346     // show overdraw result in main display
347     auto image = overdrawSurface->GetImageSnapshot();
348     if (image == nullptr) {
349         RS_LOGE("RSDisplayRenderNodeDrawable::RenderOverDraw image is nullptr");
350         return;
351     }
352     Drawing::Brush brush;
353     auto overdrawColors = RSOverdrawController::GetInstance().GetColorArray();
354     auto colorFilter = Drawing::ColorFilter::CreateOverDrawColorFilter(overdrawColors.data());
355     Drawing::Filter filter;
356     filter.SetColorFilter(colorFilter);
357     brush.SetFilter(filter);
358     curCanvas_->AttachBrush(brush);
359     curCanvas_->DrawImage(*image, 0, 0, Drawing::SamplingOptions());
360     curCanvas_->DetachBrush();
361 }
362 
CheckDisplayNodeSkip(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)363 bool RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip(
364     RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
365 {
366     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
367     if (params.HasChildCrossNode() && !params.IsMirrorScreen() &&
368         uniParam->GetCrossNodeOffScreenStatus() != CrossNodeOffScreenRenderDebugType::DISABLED) {
369         return false;
370     }
371     if (GetSyncDirtyManager()->IsCurrentFrameDirty() ||
372         (params.GetMainAndLeashSurfaceDirty() || RSUifirstManager::Instance().HasForceUpdateNode()) ||
373         RSMainThread::Instance()->GetDirtyFlag()) {
374         return false;
375     }
376 
377     RS_LOGD("DisplayNode skip");
378     RS_TRACE_NAME("DisplayNode skip");
379     GpuDirtyRegionCollection::GetInstance().AddSkipProcessFramesNumberForDFX(RSBaseRenderUtil::GetLastSendingPid());
380 #ifdef OHOS_PLATFORM
381     RSUniRenderThread::Instance().SetSkipJankAnimatorFrame(true);
382 #endif
383     auto isHardCursor = HardCursorCreateLayer(processor);
384     RS_TRACE_NAME_FMT("DisplayNode skip, isForceCommitLayer: %d, isHardCursor: %d",
385         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetForceCommitLayer(), isHardCursor);
386     if (!RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetForceCommitLayer() && !isHardCursor) {
387         RS_TRACE_NAME("DisplayNodeSkip skip commit");
388         return true;
389     }
390 
391     if (!processor->InitForRenderThread(*this, INVALID_SCREEN_ID, RSUniRenderThread::Instance().GetRenderEngine())) {
392         RS_LOGE("RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip processor init failed");
393         return false;
394     }
395 
396     auto& hardwareDrawables =
397         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
398     for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
399         if (UNLIKELY(!drawable || !drawable->GetRenderParams()) || displayNodeId != params.GetId()) {
400             continue;
401         }
402 
403         if (drawable->GetRenderParams()->GetHardwareEnabled()) {
404             auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
405             processor->CreateLayerForRenderThread(*surfaceDrawable);
406         }
407     }
408     if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
409         RS_LOGW("RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip: hardwareThread task has too many to Execute"
410                 " TaskNum:[%{public}d]", RSHardwareThread::Instance().GetunExecuteTaskNum());
411         RSHardwareThread::Instance().DumpEventQueue();
412     }
413     processor->ProcessDisplaySurfaceForRenderThread(*this);
414 
415     // commit RCD layers
416     DoScreenRcdTask(params, processor);
417     processor->PostProcess();
418     return true;
419 }
420 
PostClearMemoryTask() const421 void RSDisplayRenderNodeDrawable::PostClearMemoryTask() const
422 {
423     auto& unirenderThread = RSUniRenderThread::Instance();
424     if (unirenderThread.IsDefaultClearMemroyFinished()) {
425         unirenderThread.DefaultClearMemoryCache(); //default clean with no rendering in 5s
426         unirenderThread.SetDefaultClearMemoryFinished(false);
427     }
428 }
429 
SetDisplayNodeSkipFlag(RSRenderThreadParams & uniParam,bool flag)430 void RSDisplayRenderNodeDrawable::SetDisplayNodeSkipFlag(RSRenderThreadParams& uniParam, bool flag)
431 {
432     isDisplayNodeSkipStatusChanged_ = (isDisplayNodeSkip_ != flag);
433     isDisplayNodeSkip_ = flag;
434     uniParam.SetForceMirrorScreenDirty(isDisplayNodeSkipStatusChanged_ && isDisplayNodeSkip_);
435 }
436 
CheckFilterCacheFullyCovered(RSSurfaceRenderParams & surfaceParams,RectI screenRect)437 void RSDisplayRenderNodeDrawable::CheckFilterCacheFullyCovered(RSSurfaceRenderParams& surfaceParams, RectI screenRect)
438 {
439     surfaceParams.SetFilterCacheFullyCovered(false);
440     if (!surfaceParams.IsTransparent() || surfaceParams.GetIsRotating()) {
441         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterCacheFullyCovered NodeId[%" PRIu64 "], isOpaque: %d, isRotating: %d",
442             surfaceParams.GetId(), !surfaceParams.IsTransparent(), surfaceParams.GetIsRotating());
443         return;
444     }
445     bool dirtyBelowContainsFilterNode = false;
446     for (auto& filterNodeId : surfaceParams.GetVisibleFilterChild()) {
447         auto drawableAdapter = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(filterNodeId);
448         if (drawableAdapter == nullptr) {
449             continue;
450         }
451         auto filterNodeDrawable = std::static_pointer_cast<DrawableV2::RSRenderNodeDrawable>(drawableAdapter);
452         if (filterNodeDrawable == nullptr) {
453             RS_LOGD("CheckFilterCacheFullyCovered filter node drawable is nullptr, Name[%{public}s],"
454                 "NodeId[%" PRIu64 "]", surfaceParams.GetName().c_str(), filterNodeId);
455             continue;
456         }
457         const auto& filterParams = filterNodeDrawable->GetRenderParams();
458         if (filterParams == nullptr || !filterParams->HasBlurFilter()) {
459             RS_LOGD("CheckFilterCacheFullyCovered filter params is nullptr or has no blur, Name[%{public}s],"
460                 "NodeId[%" PRIu64 "]", surfaceParams.GetName().c_str(), filterNodeId);
461             continue;
462         }
463         // Filter cache occlusion need satisfy:
464         // 1.The filter node global alpha equals 1;
465         // 2.There is no invalid filter cache node below, which should take snapshot;
466         // 3.The filter node has no global corner;
467         // 4.The node type is not EFFECT_NODE;
468         if (ROSEN_EQ(filterParams->GetGlobalAlpha(), 1.f) && !dirtyBelowContainsFilterNode &&
469             !filterParams->HasGlobalCorner() && filterParams->GetType() != RSRenderNodeType::EFFECT_NODE) {
470             surfaceParams.CheckValidFilterCacheFullyCoverTarget(
471                 filterNodeDrawable->IsFilterCacheValidForOcclusion(),
472                 filterNodeDrawable->GetFilterCachedRegion(), screenRect);
473         }
474         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterCacheFullyCovered NodeId[%" PRIu64 "], globalAlpha: %f, "
475             "hasInvalidFilterCacheBefore: %d, hasNoCorner: %d, isNodeTypeCorrect: %d, isCacheValid: %d, "
476             "cacheRect: %s", filterNodeId, filterParams->GetGlobalAlpha(), !dirtyBelowContainsFilterNode,
477             !filterParams->HasGlobalCorner(), filterParams->GetType() != RSRenderNodeType::EFFECT_NODE,
478             filterNodeDrawable->IsFilterCacheValidForOcclusion(),
479             filterNodeDrawable->GetFilterCachedRegion().ToString().c_str());
480         if (filterParams->GetEffectNodeShouldPaint() && !filterNodeDrawable->IsFilterCacheValidForOcclusion()) {
481             dirtyBelowContainsFilterNode = true;
482         }
483     }
484 }
485 
CheckAndUpdateFilterCacheOcclusion(RSDisplayRenderParams & params,ScreenInfo & screenInfo)486 void RSDisplayRenderNodeDrawable::CheckAndUpdateFilterCacheOcclusion(
487     RSDisplayRenderParams& params, ScreenInfo& screenInfo)
488 {
489     if (!RSSystemParameters::GetFilterCacheOcculusionEnabled()) {
490         return;
491     }
492     bool isScreenOccluded = false;
493     RectI screenRect = {0, 0, screenInfo.width, screenInfo.height};
494     // top-down traversal all mainsurface
495     // if upper surface reuse filter cache which fully cover whole screen
496     // mark lower layers for process skip
497     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
498     for (const auto& adapter : curAllSurfaceDrawables) {
499         if (adapter == nullptr || adapter->GetNodeType() != RSRenderNodeType::SURFACE_NODE) {
500             RS_LOGD("CheckAndUpdateFilterCacheOcclusion adapter is nullptr or error type");
501             continue;
502         }
503         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(adapter);
504         if (surfaceNodeDrawable == nullptr) {
505             RS_LOGD("CheckAndUpdateFilterCacheOcclusion surfaceNodeDrawable is nullptr");
506             continue;
507         }
508         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
509         if (surfaceParams == nullptr) {
510             RS_LOGD("CheckAndUpdateFilterCacheOcclusion surface params is nullptr");
511             continue;
512         }
513 
514         CheckFilterCacheFullyCovered(*surfaceParams, screenRect);
515 
516         if (surfaceParams->IsMainWindowType()) {
517             // reset occluded status for all mainwindow
518             surfaceParams->SetOccludedByFilterCache(isScreenOccluded);
519         }
520         isScreenOccluded = isScreenOccluded || surfaceParams->GetFilterCacheFullyCovered();
521     }
522 }
523 
OnDraw(Drawing::Canvas & canvas)524 void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
525 {
526     RECORD_GPU_RESOURCE_DRAWABLE_CALLER(GetId())
527     SetDrawSkipType(DrawSkipType::NONE);
528     // canvas will generate in every request frame
529     (void)canvas;
530 
531     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
532     if (UNLIKELY(!renderParams_ || !uniParam)) {
533         SetDrawSkipType(DrawSkipType::RENDER_PARAMS_OR_UNI_PARAMS_NULL);
534         RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw renderParams/uniParam is null!");
535         return;
536     }
537     auto params = static_cast<RSDisplayRenderParams*>(renderParams_.get());
538 
539     // [Attention] do not return before layer created set false, otherwise will result in buffer not released
540     auto& hardwareDrawables = uniParam->GetHardwareEnabledTypeDrawables();
541     for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
542         if (UNLIKELY(!drawable || !drawable->GetRenderParams()) ||
543             displayNodeId != params->GetId()) {
544             continue;
545         }
546         drawable->GetRenderParams()->SetLayerCreated(false);
547     }
548     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
549     if (!hardCursorDrawables.empty()) {
550         auto iter = hardCursorDrawables.find(GetId());
551         if (iter != hardCursorDrawables.end() && iter->second && iter->second->GetRenderParams()) {
552             iter->second->GetRenderParams()->SetLayerCreated(false);
553         }
554     }
555     // if screen power off, skip on draw, needs to draw one more frame.
556     isRenderSkipIfScreenOff_ = RSUniRenderUtil::CheckRenderSkipIfScreenOff(true, params->GetScreenId());
557     if (isRenderSkipIfScreenOff_) {
558         SetDrawSkipType(DrawSkipType::RENDER_SKIP_IF_SCREEN_OFF);
559         return;
560     }
561 
562     PostClearMemoryTask();
563 
564     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
565     if (!screenManager) {
566         SetDrawSkipType(DrawSkipType::SCREEN_MANAGER_NULL);
567         RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw ScreenManager is nullptr");
568         return;
569     }
570 
571     if (RSSystemProperties::IsFoldScreenFlag() && screenManager->IsScreenSwitching()) {
572         SetDrawSkipType(DrawSkipType::RENDER_SKIP_IF_SCREEN_SWITCHING);
573         RS_LOGI("RSDisplayRenderNodeDrawable::OnDraw FoldScreenNodeSwitching is true, do not drawframe");
574         RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable FoldScreenNodeSwitching is true");
575         return;
576     }
577 
578     // dfx
579     RSRenderNodeDrawable::InitDfxForCacheInfo();
580     // init translate for wallpaper
581     InitTranslateForWallpaper();
582     // set for cache and draw cross node in extended screen model
583     uniParam->SetIsMirrorScreen(params->IsMirrorScreen());
584     uniParam->SetCurrentVisitDisplayDrawableId(GetId());
585     uniParam->SetIsFirstVisitCrossNodeDisplay(params->IsFirstVisitCrossNodeDisplay());
586     uniParam->SetCompositeType(params->GetCompositeType());
587     params->SetDirtyAlignEnabled(uniParam->IsDirtyAlignEnabled());
588     ScreenId paramScreenId = params->GetScreenId();
589     offsetX_ = params->IsMirrorScreen() ? 0 : params->GetDisplayOffsetX();
590     offsetY_ = params->IsMirrorScreen() ? 0 : params->GetDisplayOffsetY();
591     curDisplayScreenId_ = paramScreenId;
592     RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw curScreenId=[%{public}" PRIu64 "], "
593         "offsetX=%{public}d, offsetY=%{public}d", paramScreenId, offsetX_, offsetY_);
594     SetScreenRotationForPointLight(*params);
595 
596     const RectI& dirtyRegion = GetSyncDirtyManager()->GetCurrentFrameDirtyRegion();
597     const auto& activeSurfaceRect = GetSyncDirtyManager()->GetActiveSurfaceRect();
598     RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable::OnDraw[%" PRIu64 "][%" PRIu64
599         "] zoomed(%d), dirty(%d, %d, %d, %d), active(%d, %d, %d, %d)",
600         paramScreenId, GetId(), params->GetZoomed(),
601         dirtyRegion.left_, dirtyRegion.top_, dirtyRegion.width_, dirtyRegion.height_,
602         activeSurfaceRect.left_, activeSurfaceRect.top_, activeSurfaceRect.width_, activeSurfaceRect.height_);
603     RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw node: %{public}" PRIu64 "", GetId());
604     ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(paramScreenId);
605     ScreenId activeScreenId = HgmCore::Instance().GetActiveScreenId();
606     uint32_t activeScreenRefreshRate = HgmCore::Instance().GetScreenCurrentRefreshRate(activeScreenId);
607 
608     // when set expectedRefreshRate, the activeScreenRefreshRate maybe change from 60 to 120
609     // so that need change whether equal vsync period and whether use virtual dirty
610     if (curScreenInfo.skipFrameStrategy == SKIP_FRAME_BY_REFRESH_RATE) {
611         bool isEqualVsyncPeriod = (activeScreenRefreshRate == curScreenInfo.expectedRefreshRate);
612         if (isEqualVsyncPeriod != curScreenInfo.isEqualVsyncPeriod) {
613             curScreenInfo.isEqualVsyncPeriod = isEqualVsyncPeriod;
614             screenManager->SetEqualVsyncPeriod(paramScreenId, isEqualVsyncPeriod);
615         }
616     }
617     screenManager->RemoveForceRefreshTask();
618     if (SkipFrame(activeScreenRefreshRate, curScreenInfo)) {
619         SetDrawSkipType(DrawSkipType::SKIP_FRAME);
620         RS_TRACE_NAME_FMT("SkipFrame, screenId:%lu, strategy:%d, interval:%u, refreshrate:%u", paramScreenId,
621             curScreenInfo.skipFrameStrategy, curScreenInfo.skipFrameInterval, curScreenInfo.expectedRefreshRate);
622         screenManager->PostForceRefreshTask();
623         return;
624     }
625     if (!curScreenInfo.isEqualVsyncPeriod) {
626         virtualDirtyRefresh_ = true;
627     }
628 
629     auto screenInfo = params->GetScreenInfo();
630     auto processor = RSProcessorFactory::CreateProcessor(params->GetCompositeType());
631     if (!processor) {
632         SetDrawSkipType(DrawSkipType::CREATE_PROCESSOR_FAIL);
633         RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw RSProcessor is null!");
634         return;
635     }
636 
637     auto mirroredDrawable = params->GetMirrorSourceDrawable().lock();
638     auto mirroredRenderParams = mirroredDrawable ? mirroredDrawable->GetRenderParams().get() : nullptr;
639     if (mirroredRenderParams ||
640         params->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE) {
641         if (!processor->InitForRenderThread(*this,
642             mirroredRenderParams ? mirroredRenderParams->GetScreenId() : INVALID_SCREEN_ID,
643             RSUniRenderThread::Instance().GetRenderEngine())) {
644             SetDrawSkipType(DrawSkipType::RENDER_ENGINE_NULL);
645             syncDirtyManager_->ResetDirtyAsSurfaceSize();
646             syncDirtyManager_->UpdateDirty(false);
647             RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw processor init failed!");
648             return;
649         }
650         if (mirroredRenderParams) {
651             enableVisibleRect_ = screenInfo.enableVisibleRect;
652             if (enableVisibleRect_) {
653                 const auto& rect = screenManager->GetMirrorScreenVisibleRect(paramScreenId);
654                 RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable::OnDraw VisibleRect[%d, %d, %d, %d] to [%d, %d, %d, %d]",
655                     curVisibleRect_.GetLeft(), curVisibleRect_.GetTop(),
656                     curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight(), rect.x, rect.y, rect.w, rect.h);
657                 curVisibleRect_ = Drawing::RectI(rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
658                 RSUniRenderThread::Instance().SetVisibleRect(curVisibleRect_);
659                 RSUniRenderThread::Instance().SetEnableVisiableRect(enableVisibleRect_);
660             }
661             currentBlackList_ = screenManager->GetVirtualScreenBlackList(paramScreenId);
662             RSUniRenderThread::Instance().SetBlackList(currentBlackList_);
663             if (params->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
664                 SetDrawSkipType(DrawSkipType::WIRED_SCREEN_PROJECTION);
665                 WiredScreenProjection(*params, processor);
666                 lastVisibleRect_ = curVisibleRect_;
667                 lastBlackList_ = currentBlackList_;
668                 RSUniRenderThread::Instance().SetVisibleRect(Drawing::RectI());
669                 return;
670             }
671             RSUniRenderThread::Instance().SetWhiteList(screenInfo.whiteList);
672             curSecExemption_ = params->GetSecurityExemption();
673             uniParam->SetSecExemption(curSecExemption_);
674             DrawMirrorScreen(*params, processor);
675             lastBlackList_ = currentBlackList_;
676             lastSecExemption_ = curSecExemption_;
677             lastVisibleRect_ = curVisibleRect_;
678             RSUniRenderThread::Instance().SetVisibleRect(Drawing::RectI());
679             RSUniRenderThread::Instance().SetEnableVisiableRect(false);
680         } else {
681             bool isOpDropped = uniParam->IsOpDropped();
682             uniParam->SetOpDropped(false);
683             auto expandProcessor = RSProcessor::ReinterpretCast<RSUniRenderVirtualProcessor>(processor);
684             if (!expandProcessor) {
685                 SetDrawSkipType(DrawSkipType::EXPAND_PROCESSOR_NULL);
686                 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw expandProcessor is null!");
687                 return;
688             }
689             RSDirtyRectsDfx rsDirtyRectsDfx(*this);
690             std::vector<RectI> damageRegionRects;
691             // disable expand screen dirty when isEqualVsyncPeriod is false, because the dirty history is incorrect
692             if (uniParam->IsExpandScreenDirtyEnabled() && uniParam->IsVirtualDirtyEnabled() &&
693                 curScreenInfo.isEqualVsyncPeriod) {
694                 int32_t bufferAge = expandProcessor->GetBufferAge();
695                 damageRegionRects = RSUniRenderUtil::MergeDirtyHistory(
696                     *this, bufferAge, screenInfo, rsDirtyRectsDfx, *params);
697                 uniParam->Reset();
698                 if (!uniParam->IsVirtualDirtyDfxEnabled()) {
699                     expandProcessor->SetDirtyInfo(damageRegionRects);
700                 }
701             } else {
702                 std::vector<RectI> emptyRects = {};
703                 expandProcessor->SetRoiRegionToCodec(emptyRects);
704             }
705             rsDirtyRectsDfx.SetVirtualDirtyRects(damageRegionRects, screenInfo);
706             DrawExpandScreen(*params, *expandProcessor);
707             if (curCanvas_) {
708                 rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
709             }
710             uniParam->SetOpDropped(isOpDropped);
711         }
712         DrawCurtainScreen();
713         processor->PostProcess();
714         SetDrawSkipType(DrawSkipType::MIRROR_DRAWABLE_SKIP);
715         return;
716     }
717 
718     bool isHdrOn = params->GetHDRPresent();
719     // 0 means defalut hdrBrightnessRatio
720     float hdrBrightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(paramScreenId, 0);
721     if (!isHdrOn) {
722         params->SetBrightnessRatio(hdrBrightnessRatio);
723         hdrBrightnessRatio = 1.0f;
724     }
725     RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw HDRDraw isHdrOn: %{public}d, BrightnessRatio: %{public}f",
726         isHdrOn, hdrBrightnessRatio);
727 
728     // checkDisplayNodeSkip need to be judged at the end
729     if (RSAncoManager::Instance()->GetAncoHebcStatus() == AncoHebcStatus::INITIAL &&
730         uniParam->IsOpDropped() && CheckDisplayNodeSkip(*params, processor)) {
731         SetDrawSkipType(DrawSkipType::DISPLAY_NODE_SKIP);
732         RSMainThread::Instance()->SetFrameIsRender(false);
733         SetDisplayNodeSkipFlag(*uniParam, true);
734         return;
735     }
736     SetDisplayNodeSkipFlag(*uniParam, false);
737     RSMainThread::Instance()->SetFrameIsRender(true);
738 
739     CheckAndUpdateFilterCacheOcclusion(*params, curScreenInfo);
740     if (isHdrOn) {
741         params->SetNewPixelFormat(GRAPHIC_PIXEL_FMT_RGBA_1010102);
742     }
743     RSUniRenderThread::Instance().WaitUntilDisplayNodeBufferReleased(*this);
744     // displayNodeSp to get  rsSurface witch only used in renderThread
745     auto renderFrame = RequestFrame(*params, processor);
746     if (!renderFrame) {
747         SetDrawSkipType(DrawSkipType::REQUEST_FRAME_FAIL);
748         RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw failed to request frame");
749         return;
750     }
751 
752     UpdateSlrScale(screenInfo);
753     RSDirtyRectsDfx rsDirtyRectsDfx(*this);
754     std::vector<RectI> damageRegionrects;
755     std::vector<RectI> curFrameVisibleRegionRects;
756     Drawing::Region clipRegion;
757     if (uniParam->IsPartialRenderEnabled()) {
758         damageRegionrects = RSUniRenderUtil::MergeDirtyHistory(
759             *this, renderFrame->GetBufferAge(), screenInfo, rsDirtyRectsDfx, *params);
760         curFrameVisibleRegionRects = RSUniRenderUtil::GetCurrentFrameVisibleDirty(*this, screenInfo, *params);
761         uniParam->Reset();
762         clipRegion = GetFlippedRegion(damageRegionrects, screenInfo);
763         RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
764             damageRegionrects.size(), RectVectorToString(damageRegionrects).c_str());
765         if (!uniParam->IsRegionDebugEnabled()) {
766             renderFrame->SetDamageRegion(damageRegionrects);
767         }
768     }
769 
770     auto drSurface = renderFrame->GetFrame()->GetSurface();
771     if (!drSurface) {
772         SetDrawSkipType(DrawSkipType::SURFACE_NULL);
773         RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw DrawingSurface is null");
774         return;
775     }
776 
777     curCanvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
778     if (!curCanvas_) {
779         SetDrawSkipType(DrawSkipType::CANVAS_NULL);
780         RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw failed to create canvas");
781         return;
782     }
783 
784     curCanvas_->SetTargetColorGamut(params->GetNewColorSpace());
785     curCanvas_->SetScreenId(paramScreenId);
786     curCanvas_->SetHdrOn(isHdrOn);
787     curCanvas_->SetDisableFilterCache(params->GetZoomed());
788 
789 #ifdef DDGR_ENABLE_FEATURE_OPINC
790     if (autoCacheEnable_) {
791         screenRectInfo_ = {0, 0, screenInfo.width, screenInfo.height};
792     }
793 #endif
794 
795     // canvas draw
796     {
797         {
798             RSSkpCaptureDfx capture(curCanvas_);
799             Drawing::AutoCanvasRestore acr(*curCanvas_, true);
800 
801             bool isOpDropped = uniParam->IsOpDropped();
802             bool isScRGBEnable = EnablescRGBForP3AndUiFirst(params->GetNewColorSpace());
803             bool needOffscreen = params->GetNeedOffscreen() || isHdrOn || isScRGBEnable || screenInfo.isSamplingOn;
804             if (params->IsRotationFinished()) {
805                 CalculateTranslationForWallpaper();
806             }
807             if (params->GetNeedOffscreen()) {
808                 uniParam->SetOpDropped(false);
809             }
810 
811             if (uniParam->IsOpDropped()) {
812                 if (uniParam->IsDirtyAlignEnabled()) {
813                     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
814                 } else {
815                     uniParam->SetClipRegion(clipRegion);
816                     ClipRegion(*curCanvas_, clipRegion);
817                 }
818             } else if (params->GetNeedOffscreen()) {
819                 // draw black background in rotation for camera
820                 curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
821             } else {
822                 curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
823             }
824 
825             if (needOffscreen) {
826                 ScaleCanvasIfNeeded(screenInfo);
827                 PrepareOffscreenRender(*this, !screenInfo.isSamplingOn, !screenInfo.isSamplingOn);
828                 curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
829             }
830 
831             if (!params->GetNeedOffscreen()) {
832                 curCanvas_->ConcatMatrix(params->GetMatrix());
833             }
834 
835             curCanvas_->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
836             ClearCanvasStencil(*curCanvas_, *params, *uniParam);
837             // cpu boost feature start
838             ffrt_cpu_boost_start(CPUBOOST_START_POINT + 1);
839             RSRenderNodeDrawable::OnDraw(*curCanvas_);
840             // cpu boost feature end
841             ffrt_cpu_boost_end(CPUBOOST_START_POINT + 1);
842             curCanvas_->Save();
843             curCanvas_->ResetMatrix();
844             Drawing::Matrix invertMatrix;
845             if (params->GetNeedOffscreen() && params->GetMatrix().Invert(invertMatrix)) {
846                 curCanvas_->ConcatMatrix(invertMatrix);
847             }
848             rsDirtyRectsDfx.OnDraw(*curCanvas_);
849             curCanvas_->Restore();
850             DrawCurtainScreen();
851             bool displayP3Enable = (params->GetNewColorSpace() == GRAPHIC_COLOR_GAMUT_DISPLAY_P3);
852             if (screenInfo.isSamplingOn) {
853                 // In expand screen down-sampling situation, process watermark and color filter during offscreen render.
854                 DrawWatermarkIfNeed(*params, *curCanvas_);
855                 SwitchColorFilter(*curCanvas_, hdrBrightnessRatio, displayP3Enable);
856             }
857             if (needOffscreen && canvasBackup_) {
858                 Drawing::AutoCanvasRestore acr(*canvasBackup_, true);
859                 if (params->GetNeedOffscreen()) {
860                     canvasBackup_->ConcatMatrix(params->GetMatrix());
861                 }
862                 ClearTransparentBeforeSaveLayer();
863                 FinishOffscreenRender(Drawing::SamplingOptions(Drawing::FilterMode::NEAREST,
864                     Drawing::MipmapMode::NONE), screenInfo.isSamplingOn, hdrBrightnessRatio);
865                 uniParam->SetOpDropped(isOpDropped);
866             }
867             if (!screenInfo.isSamplingOn) {
868                 // In normal situation, process watermark and color filter after offscreen render.
869                 DrawWatermarkIfNeed(*params, *curCanvas_);
870                 SwitchColorFilter(*curCanvas_, hdrBrightnessRatio, displayP3Enable);
871             }
872 #ifdef RS_ENABLE_OVERLAY_DISPLAY
873             RSOverlayDisplayManager::Instance().PostProcFilter(*curCanvas_);
874 #endif
875             auto dirtyManager = GetSyncDirtyManager();
876             const auto& activeRect = dirtyManager->GetActiveSurfaceRect();
877             if (!activeRect.IsEmpty() && (!dirtyManager->GetDirtyRegion().IsInsideOf(activeRect) ||
878                 !uniParam->IsPartialRenderEnabled() || uniParam->IsRegionDebugEnabled())) {
879                 RS_TRACE_NAME_FMT("global dirty region:[%s] is not inside of active surface rect:[%s], "
880                     "clear extra area to black", dirtyManager->GetDirtyRegion().ToString().c_str(),
881                     activeRect.ToString().c_str());
882                 curCanvas_->Save();
883                 auto activeRegion = RSUniRenderUtil::ScreenIntersectDirtyRects(
884                     Occlusion::Region(activeRect), screenInfo);
885                 curCanvas_->ClipRegion(GetFlippedRegion(activeRegion, screenInfo), Drawing::ClipOp::DIFFERENCE);
886                 curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
887                 curCanvas_->Restore();
888             }
889         }
890 
891         if (RotateOffScreenParam::GetRotateOffScreenDisplayNodeEnable() && !params->IsRotationChanged()) {
892             offscreenSurface_ = nullptr;
893         }
894 
895         specialLayerType_ = GetSpecialLayerType(*params);
896         if (RSSystemProperties::GetDrawMirrorCacheImageEnabled() && uniParam->HasMirrorDisplay() &&
897             curCanvas_->GetSurface() != nullptr && (specialLayerType_ != HAS_SPECIAL_LAYER ||
898             RSMainThread::Instance()->HasWiredMirrorDisplay())) {
899             cacheImgForCapture_ = curCanvas_->GetSurface()->GetImageSnapshot();
900         } else {
901             SetCacheImgForCapture(nullptr);
902         }
903     }
904     RenderOverDraw();
905     RSMainThread::Instance()->SetDirtyFlag(false);
906 
907     if (Drawing::PerformanceCaculate::GetDrawingFlushPrint()) {
908         RS_LOGI("Drawing Performance Flush start %{public}lld", Drawing::PerformanceCaculate::GetUpTime(false));
909     }
910     RS_TRACE_BEGIN("RSDisplayRenderNodeDrawable Flush");
911     RECORD_GPU_RESOURCE_DRAWABLE_CALLER(GetId())
912     RsFrameReport::GetInstance().BeginFlush();
913     renderFrame->Flush();
914     RS_TRACE_END();
915     if (Drawing::PerformanceCaculate::GetDrawingFlushPrint()) {
916         RS_LOGI("Drawing Performance Flush end %{public}lld", Drawing::PerformanceCaculate::GetUpTime(false));
917         Drawing::PerformanceCaculate::ResetCaculateTimeCount();
918     }
919 
920     // process round corner display
921     DoScreenRcdTask(*params, processor);
922 
923     if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
924         RS_LOGW("RSDisplayRenderNodeDrawable::ondraw: hardwareThread task has too many to Execute"
925                 " TaskNum:[%{public}d]", RSHardwareThread::Instance().GetunExecuteTaskNum());
926         RSHardwareThread::Instance().DumpEventQueue();
927     }
928 
929     RS_TRACE_BEGIN("RSDisplayRenderNodeDrawable CommitLayer");
930     for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
931         if (UNLIKELY(!drawable || !drawable->GetRenderParams())) {
932             continue;
933         }
934         auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
935         if (!surfaceDrawable || displayNodeId != params->GetId()) {
936             continue;
937         }
938         if (drawable->GetRenderParams()->GetHardwareEnabled()) {
939             processor->CreateLayerForRenderThread(*surfaceDrawable);
940         }
941     }
942     HardCursorCreateLayer(processor);
943     if (screenInfo.activeRect.IsEmpty() ||
944         screenInfo.activeRect == RectI(0, 0, screenInfo.width, screenInfo.height)) {
945         if (uniParam->IsRegionDebugEnabled()) {
946             std::vector<RectI> emptyRegionRects = {};
947             SetDirtyRects(emptyRegionRects);
948         } else {
949             SetDirtyRects(RSSystemProperties::GetOptimizeHwcComposeAreaEnabled() ?
950                 curFrameVisibleRegionRects : damageRegionrects);
951         }
952     } else {
953         SetDirtyRects({GetSyncDirtyManager()->GetRectFlipWithinSurface(screenInfo.activeRect)});
954     }
955     processor->ProcessDisplaySurfaceForRenderThread(*this);
956     processor->PostProcess();
957     RS_TRACE_END();
958 
959 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
960     if (!mirrorDrawable) {
961         RSMagicPointerRenderManager::GetInstance().ProcessColorPicker(processor, curCanvas_->GetGPUContext());
962         RSMagicPointerRenderManager::GetInstance().SetCacheImgForPointer(nullptr);
963     }
964 #endif
965 }
966 
ClearCanvasStencil(RSPaintFilterCanvas & canvas,RSDisplayRenderParams & params,RSRenderThreadParams & uniParam)967 void RSDisplayRenderNodeDrawable::ClearCanvasStencil(RSPaintFilterCanvas& canvas,
968     RSDisplayRenderParams& params, RSRenderThreadParams& uniParam)
969 {
970     if (!uniParam.IsStencilPixelOcclusionCullingEnabled()) {
971         return;
972     }
973     auto topSurfaceOpaqueRects = params.GetTopSurfaceOpaqueRects();
974     if (topSurfaceOpaqueRects.empty()) {
975         return;
976     }
977     auto screenInfo = params.GetScreenInfo();
978     RS_OPTIONAL_TRACE_NAME_FMT("ClearStencil, rect(0, 0, %d, %d), stencilVal: 0",
979         screenInfo.width, screenInfo.height);
980     canvas.ClearStencil({0, 0, screenInfo.width, screenInfo.height}, 0);
981     std::reverse(topSurfaceOpaqueRects.begin(), topSurfaceOpaqueRects.end());
982     auto maxStencilVal = TOP_OCCLUSION_SURFACES_NUM * OCCLUSION_ENABLE_SCENE_NUM;
983     canvas.SetMaxStencilVal(maxStencilVal);
984     for (size_t i = 0; i < topSurfaceOpaqueRects.size(); i++) {
985         Drawing::RectI rect {topSurfaceOpaqueRects[i].left_,
986             topSurfaceOpaqueRects[i].top_,
987             topSurfaceOpaqueRects[i].right_,
988             topSurfaceOpaqueRects[i].bottom_};
989         auto stencilVal = OCCLUSION_ENABLE_SCENE_NUM *
990             (TOP_OCCLUSION_SURFACES_NUM - topSurfaceOpaqueRects.size() + i + 1);
991         RS_OPTIONAL_TRACE_NAME_FMT("ClearStencil, rect(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 "), "
992             "stencilVal: %zu", rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight(), stencilVal);
993         canvas.ClearStencil(rect, static_cast<uint32_t>(stencilVal));
994     }
995 }
996 
DrawMirrorScreen(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)997 void RSDisplayRenderNodeDrawable::DrawMirrorScreen(
998     RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
999 {
1000     RS_TRACE_FUNC();
1001     // uniParam/drawable/mirroredParams/renderParams_ not null in caller
1002     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1003     auto mirroredDrawable =
1004         std::static_pointer_cast<RSDisplayRenderNodeDrawable>(params.GetMirrorSourceDrawable().lock());
1005     auto& mirroredParams = mirroredDrawable->GetRenderParams();
1006 
1007     specialLayerType_ = GetSpecialLayerType(static_cast<RSDisplayRenderParams&>(*mirroredParams),
1008         enableVisibleRect_ ? params.HasSecLayerInVisibleRect() : true);
1009     auto virtualProcesser = RSProcessor::ReinterpretCast<RSUniRenderVirtualProcessor>(processor);
1010     if (!virtualProcesser) {
1011         RS_LOGE("RSDisplayRenderNodeDrawable::DrawMirrorScreen virtualProcesser is null");
1012         return;
1013     }
1014 
1015     const auto screenInfo = uniParam->GetScreenInfo(); // record screenInfo
1016     uniParam->SetScreenInfo(params.GetScreenInfo());
1017     auto hardwareDrawables = uniParam->GetHardwareEnabledTypeDrawables();
1018     //if specialLayer is visible and no CacheImg
1019     if ((mirroredParams->GetSecurityDisplay() != params.GetSecurityDisplay() &&
1020         specialLayerType_ == HAS_SPECIAL_LAYER) || !mirroredDrawable->GetCacheImgForCapture() ||
1021         params.GetVirtualScreenMuteStatus()) {
1022         virtualProcesser->SetDrawVirtualMirrorCopy(false);
1023         DrawMirror(params, virtualProcesser, &RSDisplayRenderNodeDrawable::OnCapture, *uniParam);
1024     } else {
1025         virtualProcesser->SetDrawVirtualMirrorCopy(true);
1026         DrawMirrorCopy(*mirroredDrawable, params, virtualProcesser, *uniParam);
1027     }
1028     uniParam->SetScreenInfo(screenInfo); // reset screenInfo
1029 }
1030 
SetScreenRotationForPointLight(RSDisplayRenderParams & params)1031 void RSDisplayRenderNodeDrawable::SetScreenRotationForPointLight(RSDisplayRenderParams &params)
1032 {
1033     auto screenManager = CreateOrGetScreenManager();
1034     auto mirrorDrawable = params.GetMirrorSourceDrawable().lock();
1035     auto mirrorParams = mirrorDrawable ? mirrorDrawable->GetRenderParams().get() : nullptr;
1036     ScreenId screenId = params.GetScreenId();
1037     ScreenRotation screenRotation = params.GetScreenRotation();
1038     if (mirrorParams) {
1039         screenId = mirrorParams->GetScreenId();
1040         screenRotation = mirrorParams->GetScreenRotation();
1041     }
1042     auto screenCorrection = screenManager->GetScreenCorrection(screenId);
1043     screenRotation = static_cast<ScreenRotation>(
1044         (static_cast<int>(screenRotation) + SCREEN_ROTATION_NUM - static_cast<int>(screenCorrection)) %
1045         SCREEN_ROTATION_NUM);
1046     RSPointLightManager::Instance()->SetScreenRotation(screenRotation);
1047 }
1048 
UpdateDisplayDirtyManager(int32_t bufferage,bool useAlignedDirtyRegion)1049 void RSDisplayRenderNodeDrawable::UpdateDisplayDirtyManager(int32_t bufferage, bool useAlignedDirtyRegion)
1050 {
1051     // syncDirtyManager_ not null in caller
1052     syncDirtyManager_->SetBufferAge(bufferage);
1053     syncDirtyManager_->UpdateDirty(useAlignedDirtyRegion);
1054 }
1055 
GetSpecialLayerType(RSDisplayRenderParams & params,bool isSecLayerInVisibleRect)1056 int32_t RSDisplayRenderNodeDrawable::GetSpecialLayerType(RSDisplayRenderParams& params, bool isSecLayerInVisibleRect)
1057 {
1058     auto& uniRenderThread = RSUniRenderThread::Instance();
1059     const auto& specialLayerManager = params.GetSpecialLayerMgr();
1060     bool hasGeneralSpecialLayer = (specialLayerManager.Find(SpecialLayerType::HAS_SECURITY) &&
1061         isSecLayerInVisibleRect) || specialLayerManager.Find(SpecialLayerType::HAS_SKIP) ||
1062         specialLayerManager.Find(SpecialLayerType::HAS_PROTECTED) ||
1063         params.GetHDRPresent() || uniRenderThread.IsColorFilterModeOn();
1064     RS_LOGD("RSDisplayRenderNodeDrawable::SpecialLayer:%{public}" PRIu32 ", CurtainScreen:%{public}d, "
1065         "HDRPresent:%{public}d, ColorFilter:%{public}d", specialLayerManager.Get(),
1066         uniRenderThread.IsCurtainScreenOn(), params.GetHDRPresent(), uniRenderThread.IsColorFilterModeOn());
1067     if (RSUniRenderThread::GetCaptureParam().isSnapshot_) {
1068         hasGeneralSpecialLayer |= (specialLayerManager.Find(SpecialLayerType::HAS_SNAPSHOT_SKIP) ||
1069             uniRenderThread.IsCurtainScreenOn());
1070         return hasGeneralSpecialLayer ? HAS_SPECIAL_LAYER :
1071             (params.HasCaptureWindow() ? CAPTURE_WINDOW : NO_SPECIAL_LAYER);
1072     }
1073     if (hasGeneralSpecialLayer || !uniRenderThread.GetWhiteList().empty() || !currentBlackList_.empty()) {
1074         return HAS_SPECIAL_LAYER;
1075     } else if (params.HasCaptureWindow()) {
1076         return CAPTURE_WINDOW;
1077     }
1078     return NO_SPECIAL_LAYER;
1079 }
1080 
CalculateVirtualDirty(std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,RSDisplayRenderParams & params,Drawing::Matrix canvasMatrix)1081 std::vector<RectI> RSDisplayRenderNodeDrawable::CalculateVirtualDirty(
1082     std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, RSDisplayRenderParams& params,
1083     Drawing::Matrix canvasMatrix)
1084 {
1085     // uniParam/drawable/mirroredParams not null in caller
1086     std::vector<RectI> mappedDamageRegionRects;
1087     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1088     auto drawable = params.GetMirrorSourceDrawable().lock();
1089     auto mirroredDrawable = std::static_pointer_cast<RSDisplayRenderNodeDrawable>(drawable);
1090     auto mirrorParams = static_cast<RSDisplayRenderParams*>(mirroredDrawable->GetRenderParams().get());
1091     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
1092     if (!screenManager) {
1093         RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirty ScreenManager is nullptr");
1094         virtualProcesser->SetRoiRegionToCodec(mappedDamageRegionRects);
1095         return mappedDamageRegionRects;
1096     }
1097     ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(params.GetScreenId());
1098     if (!curScreenInfo.isEqualVsyncPeriod) {
1099         RS_LOGD("RSDisplayRenderNodeDrawable::CalculateVirtualDirty frame rate is irregular");
1100         virtualProcesser->SetRoiRegionToCodec(mappedDamageRegionRects);
1101         return mappedDamageRegionRects;
1102     }
1103     ScreenInfo mainScreenInfo = screenManager->QueryScreenInfo(mirrorParams->GetScreenId());
1104     int32_t bufferAge = virtualProcesser->GetBufferAge();
1105     std::vector<RectI> damageRegionRects = RSUniRenderUtil::MergeDirtyHistoryInVirtual(
1106         *mirroredDrawable, bufferAge, mainScreenInfo);
1107     std::shared_ptr<RSObjAbsGeometry> tmpGeo = std::make_shared<RSObjAbsGeometry>();
1108     for (auto& rect : damageRegionRects) {
1109         RectI mappedRect = tmpGeo->MapRect(rect.ConvertTo<float>(), canvasMatrix);
1110         mappedDamageRegionRects.emplace_back(mappedRect);
1111     }
1112     if (!(lastMatrix_ == canvasMatrix) || !(lastMirrorMatrix_ == mirrorParams->GetMatrix()) ||
1113         uniParam->GetForceMirrorScreenDirty() || lastBlackList_ != currentBlackList_ ||
1114         mirrorParams->IsSpecialLayerChanged() || lastSecExemption_ != curSecExemption_ || virtualDirtyRefresh_ ||
1115         (enableVisibleRect_ && (lastVisibleRect_ != curVisibleRect_ || params.HasSecLayerInVisibleRectChanged()))) {
1116         GetSyncDirtyManager()->ResetDirtyAsSurfaceSize();
1117         virtualDirtyRefresh_ = false;
1118         lastMatrix_ = canvasMatrix;
1119         lastMirrorMatrix_ = mirrorParams->GetMatrix();
1120     }
1121     RectI hwcRect = mirroredDrawable->GetSyncDirtyManager()->GetHwcDirtyRegion();
1122     if (!hwcRect.IsEmpty()) {
1123         if (mainScreenInfo.isSamplingOn && mainScreenInfo.samplingScale > 0) {
1124             Drawing::Matrix scaleMatrix;
1125             scaleMatrix.SetScaleTranslate(mainScreenInfo.samplingScale, mainScreenInfo.samplingScale,
1126                 mainScreenInfo.samplingTranslateX, mainScreenInfo.samplingTranslateY);
1127             hwcRect = RSObjAbsGeometry::MapRect(hwcRect.ConvertTo<float>(), scaleMatrix);
1128             const Vector4<int> expandSize{mainScreenInfo.samplingDistance, mainScreenInfo.samplingDistance,
1129                 mainScreenInfo.samplingDistance, mainScreenInfo.samplingDistance};
1130             hwcRect = hwcRect.MakeOutset(expandSize);
1131         }
1132         RectI mappedHwcRect = tmpGeo->MapRect(hwcRect.ConvertTo<float>(), canvasMatrix);
1133         GetSyncDirtyManager()->MergeDirtyRect(mappedHwcRect);
1134     }
1135     UpdateDisplayDirtyManager(bufferAge, false);
1136     auto extraDirty = GetSyncDirtyManager()->GetDirtyRegion();
1137     if (!extraDirty.IsEmpty()) {
1138         mappedDamageRegionRects.emplace_back(extraDirty);
1139     }
1140     if (!uniParam->IsVirtualDirtyDfxEnabled()) {
1141         virtualProcesser->SetDirtyInfo(mappedDamageRegionRects);
1142         RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
1143             mappedDamageRegionRects.size(), RectVectorToString(mappedDamageRegionRects).c_str());
1144     }
1145     return mappedDamageRegionRects;
1146 }
1147 
DrawMirror(RSDisplayRenderParams & params,std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,DrawFuncPtr drawFunc,RSRenderThreadParams & uniParam)1148 void RSDisplayRenderNodeDrawable::DrawMirror(RSDisplayRenderParams& params,
1149     std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, DrawFuncPtr drawFunc, RSRenderThreadParams& uniParam)
1150 {
1151     RS_TRACE_FUNC();
1152     // uniParam/drawable/mirroredParams not null in caller
1153     auto drawable = params.GetMirrorSourceDrawable().lock();
1154     auto mirroredDrawable = std::static_pointer_cast<RSDisplayRenderNodeDrawable>(drawable);
1155     auto& mirroredParams = mirroredDrawable->GetRenderParams();
1156 
1157     curCanvas_ = virtualProcesser->GetCanvas();
1158     if (curCanvas_ == nullptr) {
1159         RS_LOGE("RSDisplayRenderNodeDrawable::DrawMirror failed to get canvas.");
1160         return;
1161     }
1162     // for HDR
1163     curCanvas_->SetOnMultipleScreen(true);
1164     curCanvas_->SetDisableFilterCache(true);
1165     auto hasSecSurface = static_cast<RSDisplayRenderParams*>
1166         (mirroredParams.get())->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_SECURITY);
1167     if ((((!enableVisibleRect_ && hasSecSurface) || (enableVisibleRect_ && params.HasSecLayerInVisibleRect())) &&
1168         !uniParam.GetSecExemption()) || params.GetVirtualScreenMuteStatus()) {
1169         std::vector<RectI> emptyRects = {};
1170         virtualProcesser->SetRoiRegionToCodec(emptyRects);
1171         auto screenManager = CreateOrGetScreenManager();
1172         if (screenManager->GetScreenSecurityMask(params.GetScreenId())) {
1173             SetSecurityMask(*virtualProcesser);
1174         } else {
1175             SetCanvasBlack(*virtualProcesser);
1176         }
1177         virtualDirtyRefresh_ = true;
1178         curCanvas_->RestoreToCount(0);
1179         return;
1180     }
1181     curCanvas_->Save();
1182     virtualProcesser->ScaleMirrorIfNeed(GetOriginScreenRotation(), *curCanvas_);
1183     auto mirroredScreenInfo = mirroredParams->GetScreenInfo();
1184     UpdateSlrScale(mirroredScreenInfo);
1185     ScaleCanvasIfNeeded(mirroredScreenInfo);
1186 
1187     RSDirtyRectsDfx rsDirtyRectsDfx(*this);
1188     if (uniParam.IsVirtualDirtyEnabled() && !enableVisibleRect_) {
1189         Drawing::Matrix matrix = curCanvas_->GetTotalMatrix();
1190         std::vector<RectI> dirtyRects = CalculateVirtualDirty(virtualProcesser, params, matrix);
1191         rsDirtyRectsDfx.SetVirtualDirtyRects(dirtyRects, params.GetScreenInfo());
1192     } else {
1193         std::vector<RectI> emptyRects = {};
1194         virtualProcesser->SetRoiRegionToCodec(emptyRects);
1195     }
1196     // Clean up the content of the previous frame
1197     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1198     virtualProcesser->CanvasClipRegionForUniscaleMode();
1199     curCanvas_->ConcatMatrix(mirroredParams->GetMatrix());
1200     PrepareOffscreenRender(*mirroredDrawable, false, false);
1201 
1202     // set mirror screen capture param
1203     // Don't need to scale here since the canvas has been switched from mirror frame to offscreen
1204     // surface in PrepareOffscreenRender() above. The offscreen surface has the same size as
1205     // the main display that's why no need additional scale.
1206     RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true));
1207     RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
1208     bool isOpDropped = uniParam.IsOpDropped();
1209     uniParam.SetOpDropped(false); // disable partial render
1210     (mirroredDrawable.get()->*drawFunc)(*curCanvas_);
1211     uniParam.SetOpDropped(isOpDropped);
1212     RSUniRenderThread::ResetCaptureParam();
1213     FinishOffscreenRender(Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NEAREST),
1214         mirroredScreenInfo.isSamplingOn);
1215     // Restore the initial state of the canvas to avoid state accumulation
1216     curCanvas_->RestoreToCount(0);
1217     rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
1218     RSUniRenderThread::Instance().SetBlackList({});
1219     RSUniRenderThread::Instance().SetWhiteList({});
1220     uniParam.SetSecExemption(false);
1221 }
1222 
DrawMirrorCopy(RSDisplayRenderNodeDrawable & mirrorDrawable,RSDisplayRenderParams & params,std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,RSRenderThreadParams & uniParam)1223 void RSDisplayRenderNodeDrawable::DrawMirrorCopy(
1224     RSDisplayRenderNodeDrawable& mirrorDrawable, RSDisplayRenderParams& params,
1225     std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, RSRenderThreadParams& uniParam)
1226 {
1227     RS_TRACE_FUNC();
1228     // mirroredParams not null in caller
1229     const auto& mirroredParams = mirrorDrawable.GetRenderParams();
1230     auto cacheImage = mirrorDrawable.GetCacheImgForCapture();
1231     bool isOpDropped = uniParam.IsOpDropped();
1232     uniParam.SetOpDropped(false);
1233     mirrorDrawable.SetOriginScreenRotation(GetOriginScreenRotation());
1234     virtualProcesser->CalculateTransform(mirrorDrawable);
1235     RSDirtyRectsDfx rsDirtyRectsDfx(*this);
1236     std::shared_ptr<RSSLRScaleFunction> slrManager = enableVisibleRect_ ? nullptr : virtualProcesser->GetSlrManager();
1237     if (!uniParam.IsVirtualDirtyEnabled() || (enableVisibleRect_ && curVisibleRect_.GetTop() > 0)) {
1238         std::vector<RectI> emptyRects = {};
1239         virtualProcesser->SetRoiRegionToCodec(emptyRects);
1240     } else {
1241         auto dirtyRects = CalculateVirtualDirty(
1242             virtualProcesser, params, slrManager ? slrManager->GetScaleMatrix() : virtualProcesser->GetCanvasMatrix());
1243         rsDirtyRectsDfx.SetVirtualDirtyRects(dirtyRects, params.GetScreenInfo());
1244     }
1245     curCanvas_ = virtualProcesser->GetCanvas();
1246     if (!curCanvas_) {
1247         RS_LOGE("RSDisplayRenderNodeDrawable::DrawMirrorCopy failed to get canvas.");
1248         return;
1249     }
1250     // Clean up the content of the previous frame
1251     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1252     virtualProcesser->CanvasClipRegionForUniscaleMode();
1253     RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true));
1254     if (slrManager) {
1255         curCanvas_->Save();
1256         auto scaleNum = slrManager->GetScaleNum();
1257         curCanvas_->Scale(scaleNum, scaleNum);
1258         mirrorDrawable.DrawHardwareEnabledNodesMissedInCacheImage(*curCanvas_);
1259         curCanvas_->Restore();
1260     } else {
1261         mirrorDrawable.DrawHardwareEnabledNodesMissedInCacheImage(*curCanvas_);
1262     }
1263     if (cacheImage && RSSystemProperties::GetDrawMirrorCacheImageEnabled()) {
1264         RS_TRACE_NAME("DrawMirrorCopy with cacheImage");
1265         if (!enableVisibleRect_) {
1266             virtualProcesser->ProcessCacheImage(*cacheImage);
1267         } else {
1268             RSUniRenderUtil::ProcessCacheImageRect(*curCanvas_, *cacheImage, curVisibleRect_,
1269                 Drawing::Rect(0, 0, curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight()));
1270         }
1271     } else {
1272         RS_TRACE_NAME("DrawMirrorCopy with displaySurface");
1273         virtualProcesser->ProcessDisplaySurfaceForRenderThread(mirrorDrawable);
1274     }
1275     if (slrManager) {
1276         curCanvas_->Save();
1277         auto scaleNum = slrManager->GetScaleNum();
1278         curCanvas_->Scale(scaleNum, scaleNum);
1279         mirrorDrawable.DrawHardwareEnabledTopNodesMissedInCacheImage(*curCanvas_);
1280         curCanvas_->Restore();
1281     } else if (mirroredParams->GetScreenInfo().isSamplingOn) {
1282         curCanvas_->Save();
1283         auto scaleNum = mirroredParams->GetScreenInfo().samplingScale;
1284         curCanvas_->Scale(scaleNum, scaleNum);
1285         mirrorDrawable.DrawHardwareEnabledTopNodesMissedInCacheImage(*curCanvas_);
1286         curCanvas_->Restore();
1287     } else {
1288         mirrorDrawable.DrawHardwareEnabledTopNodesMissedInCacheImage(*curCanvas_);
1289     }
1290     RSUniRenderThread::ResetCaptureParam();
1291     uniParam.SetOpDropped(isOpDropped);
1292     // Restore the initial state of the canvas to avoid state accumulation
1293     curCanvas_->RestoreToCount(0);
1294     rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
1295 }
1296 
DrawExpandScreen(RSDisplayRenderParams & params,RSUniRenderVirtualProcessor & processor)1297 void RSDisplayRenderNodeDrawable::DrawExpandScreen(
1298     RSDisplayRenderParams& params, RSUniRenderVirtualProcessor& processor)
1299 {
1300     RS_TRACE_FUNC();
1301     curCanvas_ = processor.GetCanvas();
1302     if (curCanvas_ == nullptr) {
1303         RS_LOGE("RSDisplayRenderNodeDrawable::DrawExpandScreen failed to get canvas.");
1304         return;
1305     }
1306     // Clean up the content of the previous frame
1307     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1308     auto targetSurfaceRenderNodeDrawable =
1309         std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(params.GetTargetSurfaceRenderNodeDrawable().lock());
1310     if (targetSurfaceRenderNodeDrawable && curCanvas_->GetSurface()) {
1311         RS_TRACE_NAME("DrawExpandScreen cacheImgForMultiScreenView");
1312         cacheImgForMultiScreenView_ = curCanvas_->GetSurface()->GetImageSnapshot();
1313     } else {
1314         cacheImgForMultiScreenView_ = nullptr;
1315     }
1316     RSRenderNodeDrawable::OnCapture(*curCanvas_);
1317     RSUniRenderThread::ResetCaptureParam();
1318     // for HDR
1319     curCanvas_->SetOnMultipleScreen(true);
1320     // Restore the initial state of the canvas to avoid state accumulation
1321     curCanvas_->RestoreToCount(0);
1322 }
1323 
WiredScreenProjection(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)1324 void RSDisplayRenderNodeDrawable::WiredScreenProjection(
1325     RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
1326 {
1327     RS_TRACE_FUNC();
1328     RSUniRenderThread::Instance().WaitUntilDisplayNodeBufferReleased(*this);
1329     auto renderFrame = RequestFrame(params, processor);
1330     if (!renderFrame) {
1331         RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection failed to request frame");
1332         return;
1333     }
1334     auto drSurface = renderFrame->GetFrame()->GetSurface();
1335     if (!drSurface) {
1336         RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection DrawingSurface is null");
1337         return;
1338     }
1339     curCanvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
1340     if (!curCanvas_) {
1341         RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection failed to create canvas");
1342         return;
1343     }
1344     auto mirroredDrawable =
1345         std::static_pointer_cast<RSDisplayRenderNodeDrawable>(params.GetMirrorSourceDrawable().lock());
1346     if (!mirroredDrawable) {
1347         RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection mirroredDrawable is null");
1348         return;
1349     }
1350     if (!mirroredDrawable->GetRenderParams()) {
1351         RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection mirroredDrawable GetRenderParams is null");
1352         return;
1353     }
1354     auto& mirroredParams = static_cast<RSDisplayRenderParams&>(*mirroredDrawable->GetRenderParams());
1355     auto multiScreenFeatureParam = std::static_pointer_cast<MultiScreenParam>(
1356         GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[MULTISCREEN]));
1357     if (!multiScreenFeatureParam) {
1358         RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection multiScreenFeatureParam is null");
1359         return;
1360     }
1361     bool isProcessSecLayer = !multiScreenFeatureParam->IsExternalScreenSecure() &&
1362         mirroredParams.GetSpecialLayerMgr().Find(SpecialLayerType::HAS_SECURITY);
1363     auto isRedraw = RSSystemParameters::GetDebugMirrorOndrawEnabled() ||
1364         (RSSystemParameters::GetWiredScreenOndrawEnabled() && !enableVisibleRect_ &&
1365             (mirroredParams.GetHDRPresent() || !currentBlackList_.empty() || isProcessSecLayer));
1366     if (isRedraw) {
1367         isMirrorSLRCopy_ = false;
1368     } else {
1369         auto cacheImage = mirroredDrawable->GetCacheImgForCapture();
1370         isMirrorSLRCopy_ = cacheImage && RSSystemProperties::GetDrawMirrorCacheImageEnabled() &&
1371                            !enableVisibleRect_ && RSSystemProperties::GetSLRScaleEnabled();
1372     }
1373 
1374     curCanvas_->Save();
1375     ScaleAndRotateMirrorForWiredScreen(*mirroredDrawable);
1376     RSDirtyRectsDfx rsDirtyRectsDfx(*mirroredDrawable);
1377     // HDR does not support wired screen
1378     if (isRedraw) {
1379         DrawWiredMirrorOnDraw(*mirroredDrawable, params);
1380         RSUniRenderThread::Instance().SetBlackList({});
1381     } else {
1382         std::vector<RectI> damageRegionRects = CalculateVirtualDirtyForWiredScreen(renderFrame, params,
1383             isMirrorSLRCopy_ ? scaleManager_->GetScaleMatrix() : curCanvas_->GetTotalMatrix());
1384         rsDirtyRectsDfx.SetVirtualDirtyRects(damageRegionRects, params.GetScreenInfo());
1385         DrawWiredMirrorCopy(*mirroredDrawable);
1386     }
1387     curCanvas_->Restore();
1388     rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
1389     renderFrame->Flush();
1390     processor->ProcessDisplaySurfaceForRenderThread(*this);
1391     if (params.GetHardCursorStatus()) {
1392         HardCursorCreateLayer(processor);
1393     }
1394     processor->PostProcess();
1395 }
1396 
DrawWiredMirrorCopy(RSDisplayRenderNodeDrawable & mirroredDrawable)1397 void RSDisplayRenderNodeDrawable::DrawWiredMirrorCopy(RSDisplayRenderNodeDrawable& mirroredDrawable)
1398 {
1399     RS_TRACE_FUNC();
1400     auto cacheImage = mirroredDrawable.GetCacheImgForCapture();
1401     if (cacheImage && RSSystemProperties::GetDrawMirrorCacheImageEnabled()) {
1402         RS_TRACE_NAME("DrawWiredMirrorCopy with cacheImage");
1403         if (isMirrorSLRCopy_) {
1404             RS_TRACE_NAME("DrawWiredMirrorCopy with SLRScale");
1405             scaleManager_->ProcessCacheImage(*curCanvas_, *cacheImage);
1406         } else if (!enableVisibleRect_) {
1407             RS_TRACE_NAME("DrawWiredMirrorCopy with SkiaScale");
1408             RSUniRenderUtil::ProcessCacheImage(*curCanvas_, *cacheImage);
1409         } else {
1410             RS_TRACE_NAME_FMT("DrawWiredMirrorCopy with VisibleRect[%d, %d, %d, %d]",
1411                 curVisibleRect_.GetLeft(), curVisibleRect_.GetTop(),
1412                 curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight());
1413             RSUniRenderUtil::ProcessCacheImageRect(*curCanvas_, *cacheImage, curVisibleRect_,
1414                 Drawing::Rect(0, 0, curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight()));
1415         }
1416     } else {
1417         RS_TRACE_NAME("DrawWiredMirrorCopy with displaySurface");
1418         auto drawParams = RSUniRenderUtil::CreateBufferDrawParam(
1419             *mirroredDrawable.GetRSSurfaceHandlerOnDraw(), false); // false: draw with gpu
1420         auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1421         if (enableVisibleRect_) {
1422             drawParams.srcRect = curVisibleRect_;
1423             drawParams.dstRect = Drawing::Rect(0, 0, curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight());
1424         }
1425         drawParams.isMirror = true;
1426         renderEngine->DrawDisplayNodeWithParams(*curCanvas_,
1427             *mirroredDrawable.GetRSSurfaceHandlerOnDraw(), drawParams);
1428         RSMainThread::Instance()->RequestNextVSync();
1429     }
1430 }
1431 
DrawWiredMirrorOnDraw(RSDisplayRenderNodeDrawable & mirroredDrawable,RSDisplayRenderParams & params)1432 void RSDisplayRenderNodeDrawable::DrawWiredMirrorOnDraw(
1433     RSDisplayRenderNodeDrawable& mirroredDrawable, RSDisplayRenderParams& params)
1434 {
1435     RS_TRACE_FUNC();
1436     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1437     if (uniParam == nullptr) {
1438         return;
1439     }
1440     const auto mirroredParams = static_cast<RSDisplayRenderParams*>(mirroredDrawable.GetRenderParams().get());
1441     if (mirroredParams == nullptr) {
1442         return;
1443     }
1444     RS_TRACE_NAME("DrawWiredMirror with Redraw");
1445     // for HDR
1446     curCanvas_->SetOnMultipleScreen(true);
1447     curCanvas_->SetDisableFilterCache(true);
1448     auto multiScreenFeatureParam = std::static_pointer_cast<MultiScreenParam>(
1449         GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[MULTISCREEN]));
1450     if (!multiScreenFeatureParam) {
1451         RS_LOGE("RSDisplayRenderNodeDrawable::DrawWiredMirrorOnDraw multiScreenFeatureParam is null");
1452         return;
1453     }
1454     if (!multiScreenFeatureParam->IsExternalScreenSecure()) {
1455         auto hasSecSurface = mirroredParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_SECURITY);
1456         if (hasSecSurface) {
1457             curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
1458             virtualDirtyRefresh_ = true;
1459             RS_LOGI("RSDisplayRenderNodeDrawable::DrawWiredMirrorOnDraw, "
1460                 "set canvas to black because of security layer.");
1461             return;
1462         }
1463     }
1464     curCanvas_->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
1465     bool isOpDropped = uniParam->IsOpDropped();
1466     uniParam->SetOpDropped(false);
1467 
1468     auto screenInfo = mirroredParams->GetScreenInfo();
1469     uniParam->SetScreenInfo(screenInfo);
1470     Drawing::Rect rect(0, 0, screenInfo.width, screenInfo.height);
1471     RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true));
1472     curCanvas_->ClipRect(rect, Drawing::ClipOp::INTERSECT, false);
1473     curCanvas_->ConcatMatrix(mirroredParams->GetMatrix());
1474     RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
1475     mirroredDrawable.RSRenderNodeDrawable::OnDraw(*curCanvas_);
1476     DrawCurtainScreen();
1477     DrawWatermarkIfNeed(*mirroredParams, *curCanvas_);
1478     bool displayP3Enable = (params.GetNewColorSpace() == GRAPHIC_COLOR_GAMUT_DISPLAY_P3);
1479     SwitchColorFilter(*curCanvas_, 1.f, displayP3Enable); // 1.f: wired screen not use hdr, use default value 1.f
1480     RSUniRenderThread::ResetCaptureParam();
1481 
1482     uniParam->SetOpDropped(isOpDropped);
1483 }
1484 
CalculateVirtualDirtyForWiredScreen(std::unique_ptr<RSRenderFrame> & renderFrame,RSDisplayRenderParams & params,Drawing::Matrix canvasMatrix)1485 std::vector<RectI> RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen(
1486     std::unique_ptr<RSRenderFrame>& renderFrame, RSDisplayRenderParams& params, Drawing::Matrix canvasMatrix)
1487 {
1488     std::vector<RectI> damageRegionRects;
1489     auto mirroredDrawable =
1490         std::static_pointer_cast<RSDisplayRenderNodeDrawable>(params.GetMirrorSourceDrawable().lock());
1491     if (!mirroredDrawable || !mirroredDrawable->GetRenderParams()) {
1492         RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen mirroredNode is null");
1493         return damageRegionRects;
1494     }
1495     const auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1496     if (uniParam == nullptr || !uniParam->IsVirtualDirtyEnabled() ||
1497         (enableVisibleRect_ && curVisibleRect_.GetTop() > 0)) {
1498         RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen invalid uniparam");
1499         return damageRegionRects;
1500     }
1501     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
1502     if (screenManager == nullptr) {
1503         RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen screenManager is null");
1504         return damageRegionRects;
1505     }
1506     auto curScreenInfo = params.GetScreenInfo();
1507     if (!curScreenInfo.isEqualVsyncPeriod) {
1508         RS_LOGD("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen frame rate is irregular");
1509         return damageRegionRects;
1510     }
1511     int32_t bufferAge = renderFrame->GetBufferAge();
1512     const auto& mirroredParams = mirroredDrawable->GetRenderParams();
1513     ScreenInfo mainScreenInfo = screenManager->QueryScreenInfo(mirroredParams->GetScreenId());
1514     std::shared_ptr<RSObjAbsGeometry> tmpGeo = std::make_shared<RSObjAbsGeometry>();
1515     // merge history dirty and map to mirrored wired screen by matrix
1516     auto tempDamageRegionRects = RSUniRenderUtil::MergeDirtyHistoryInVirtual(
1517         *mirroredDrawable, bufferAge, mainScreenInfo);
1518     for (auto& rect : tempDamageRegionRects) {
1519         RectI mappedRect = tmpGeo->MapRect(rect.ConvertTo<float>(), canvasMatrix);
1520         damageRegionRects.emplace_back(mappedRect);
1521     }
1522 
1523     auto syncDirtyManager = GetSyncDirtyManager();
1524     // reset dirty rect as mirrored wired screen size when first time connection or matrix changed
1525     if (!(lastMatrix_ == canvasMatrix) || !(lastMirrorMatrix_ == mirroredParams->GetMatrix()) ||
1526         uniParam->GetForceMirrorScreenDirty() || (enableVisibleRect_ && lastVisibleRect_ != curVisibleRect_) ||
1527         virtualDirtyRefresh_) {
1528         GetSyncDirtyManager()->ResetDirtyAsSurfaceSize();
1529         virtualDirtyRefresh_ = false;
1530         lastMatrix_ = canvasMatrix;
1531         lastMirrorMatrix_ = mirroredParams->GetMatrix();
1532     }
1533     UpdateDisplayDirtyManager(bufferAge, false);
1534     auto extraDirty = syncDirtyManager->GetDirtyRegion();
1535     if (!extraDirty.IsEmpty()) {
1536         damageRegionRects.emplace_back(extraDirty);
1537     }
1538     if (!uniParam->IsVirtualDirtyDfxEnabled()) {
1539         renderFrame->SetDamageRegion(damageRegionRects);
1540         RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
1541             damageRegionRects.size(), RectVectorToString(damageRegionRects).c_str());
1542     }
1543     return damageRegionRects;
1544 }
1545 
ScaleAndRotateMirrorForWiredScreen(RSDisplayRenderNodeDrawable & mirroredDrawable)1546 void RSDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen(RSDisplayRenderNodeDrawable& mirroredDrawable)
1547 {
1548     const auto& mirroredParams = mirroredDrawable.GetRenderParams();
1549     if (!mirroredParams) {
1550         RS_LOGE("RSDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen mirroredParams is null");
1551         return;
1552     }
1553     const auto& nodeParams = GetRenderParams();
1554     if (!nodeParams) {
1555         RS_LOGE("RSDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen nodeParams is null");
1556         return;
1557     }
1558     auto mainScreenInfo = mirroredParams->GetScreenInfo();
1559     auto mainWidth = enableVisibleRect_ ? curVisibleRect_.GetWidth() : static_cast<float>(mainScreenInfo.width);
1560     auto mainHeight = enableVisibleRect_ ? curVisibleRect_.GetHeight() : static_cast<float>(mainScreenInfo.height);
1561     auto mirrorScreenInfo = nodeParams->GetScreenInfo();
1562     auto mirrorWidth = static_cast<float>(mirrorScreenInfo.width);
1563     auto mirrorHeight = static_cast<float>(mirrorScreenInfo.height);
1564 
1565     auto rotation = mirroredParams->GetScreenRotation();
1566     auto screenManager = CreateOrGetScreenManager();
1567     RS_TRACE_NAME_FMT("ScaleAndRotateMirrorForWiredScreen[%" PRIu64 "](%f, %f), [%" PRIu64 "](%f, %f), rotation: %d",
1568         mirroredParams->GetScreenId(), mainWidth, mainHeight, nodeParams->GetScreenId(),
1569         mirrorWidth, mirrorHeight, rotation);
1570     if (screenManager) {
1571         auto screenCorrection = screenManager->GetScreenCorrection(mirroredParams->GetScreenId());
1572         if (screenCorrection != ScreenRotation::INVALID_SCREEN_ROTATION &&
1573             screenCorrection != ScreenRotation::ROTATION_0) {
1574             // Recaculate rotation if mirrored screen has additional rotation angle
1575             rotation = static_cast<ScreenRotation>((static_cast<int>(rotation) + SCREEN_ROTATION_NUM
1576                 - static_cast<int>(screenCorrection)) % SCREEN_ROTATION_NUM);
1577         }
1578     }
1579     // Rotate
1580     RotateMirrorCanvas(rotation, mirrorWidth, mirrorHeight);
1581     // not support rotation for MirrorScreen enableVisibleRect
1582     rotation = enableVisibleRect_ ? ScreenRotation::ROTATION_0 : rotation;
1583     if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
1584         std::swap(mirrorWidth, mirrorHeight);
1585     }
1586     curCanvas_->Clear(SK_ColorBLACK);
1587     // must after rotate and swap width/height
1588     if (isMirrorSLRCopy_) {
1589         if (scaleManager_ == nullptr) {
1590             scaleManager_ = std::make_shared<RSSLRScaleFunction>(
1591                 mirrorWidth, mirrorHeight, mainWidth, mainHeight);
1592         } else {
1593             scaleManager_->CheckOrRefreshScreen(mirrorWidth, mirrorHeight, mainWidth, mainHeight);
1594         }
1595         isMirrorSLRCopy_ = scaleManager_->GetIsSLRCopy();
1596     }
1597     // Scale
1598     if (mainWidth > 0 && mainHeight > 0) {
1599         if (isMirrorSLRCopy_) {
1600             scaleManager_->CanvasScale(*curCanvas_);
1601         } else {
1602             auto scaleNum = std::min(mirrorWidth / mainWidth, mirrorHeight / mainHeight);
1603             // 2 for calc X and Y
1604             curCanvas_->Translate((mirrorWidth - (scaleNum * mainWidth)) / 2,
1605                 (mirrorHeight - (scaleNum * mainHeight)) / 2);
1606             curCanvas_->Scale(scaleNum, scaleNum);
1607             curCanvas_->ClipRect(Drawing::Rect(0, 0, mainWidth, mainHeight), Drawing::ClipOp::INTERSECT, false);
1608         }
1609     }
1610 }
1611 
SetCanvasBlack(RSProcessor & processor)1612 void RSDisplayRenderNodeDrawable::SetCanvasBlack(RSProcessor& processor)
1613 {
1614     curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
1615     processor.PostProcess();
1616     RS_LOGI("RSDisplayRenderNodeDrawable::SetCanvasBlack, set canvas to black because of security layer/mute status.");
1617     curCanvas_->SetDisableFilterCache(false);
1618 }
1619 
SetSecurityMask(RSProcessor & processor)1620 void RSDisplayRenderNodeDrawable::SetSecurityMask(RSProcessor& processor)
1621 {
1622     RS_TRACE_FUNC();
1623     auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1624     if (auto screenManager = CreateOrGetScreenManager()) {
1625         auto imagePtr = screenManager->GetScreenSecurityMask(params->GetScreenId());
1626         auto image = RSPixelMapUtil::ExtractDrawingImage(imagePtr);
1627         if (!image || image->GetWidth() == 0 || image->GetHeight() == 0) {
1628             return;
1629         }
1630 
1631         auto watermark = RSUniRenderThread::Instance().GetWatermarkImg();
1632         auto screenInfo = screenManager->QueryScreenInfo(params->GetScreenId());
1633         float realImageWidth = static_cast<float>(image->GetWidth());
1634         float realImageHeight = static_cast<float>(image->GetHeight());
1635 
1636         curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1637         auto srcRect = Drawing::Rect(0, 0, image->GetWidth(), image->GetHeight());
1638         float screenWidth = static_cast<float>(screenInfo.width);
1639         float screenHeight = static_cast<float>(screenInfo.height);
1640         // Area to be drawn in the actual image
1641         auto dstRect = RSUniRenderUtil::GetImageRegions(screenWidth, screenHeight, realImageWidth, realImageHeight);
1642         // Make sure the canvas is oriented accurately.
1643         curCanvas_->ResetMatrix();
1644 
1645         Drawing::Brush brush;
1646         curCanvas_->AttachBrush(brush);
1647         curCanvas_->DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions(),
1648             Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
1649         if (watermark) {
1650             curCanvas_->DrawImageRect(*watermark, srcRect, dstRect, Drawing::SamplingOptions(),
1651                 Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
1652         }
1653         curCanvas_->DetachBrush();
1654 
1655         processor.PostProcess();
1656         RS_LOGI("RSDisplayRenderNodeDrawable::SetSecurityMask, this interface is invoked"
1657             "when the security layer is used and mask resources are set.");
1658         curCanvas_->SetDisableFilterCache(false);
1659     }
1660 }
1661 
RotateMirrorCanvas(ScreenRotation & rotation,float width,float height)1662 void RSDisplayRenderNodeDrawable::RotateMirrorCanvas(ScreenRotation& rotation, float width, float height)
1663 {
1664     switch (rotation) {
1665         case ScreenRotation::ROTATION_0:
1666             break;
1667         case ScreenRotation::ROTATION_90:
1668             curCanvas_->Translate(width / 2.0f, height / 2.0f);
1669             curCanvas_->Rotate(90, 0, 0); // 90 is the rotate angle
1670             curCanvas_->Translate(-(height / 2.0f), -(width / 2.0f));
1671             break;
1672         case ScreenRotation::ROTATION_180:
1673             // 180 is the rotate angle, calculate half width and half height requires divide by 2
1674             curCanvas_->Rotate(180, width / 2.0f, height / 2.0f);
1675             break;
1676         case ScreenRotation::ROTATION_270:
1677             curCanvas_->Translate(width / 2.0f, height / 2.0f);
1678             curCanvas_->Rotate(270, 0, 0); // 270 is the rotate angle
1679             curCanvas_->Translate(-(height / 2.0f), -(width / 2.0f));
1680             break;
1681         default:
1682             break;
1683     }
1684 }
1685 
OnCapture(Drawing::Canvas & canvas)1686 void RSDisplayRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
1687 {
1688     auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1689     if (!params) {
1690         RS_LOGE("RSDisplayRenderNodeDrawable::OnCapture params is null!");
1691         return;
1692     }
1693 
1694     auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
1695     if (!rscanvas) {
1696         RS_LOGE("RSDisplayRenderNodeDrawable::OnCapture, rscanvas us nullptr");
1697         return;
1698     }
1699 
1700     Drawing::AutoCanvasRestore acr(canvas, true);
1701 
1702     bool noBuffer = RSUniRenderThread::GetCaptureParam().isSnapshot_ &&
1703         GetRSSurfaceHandlerOnDraw()->GetBuffer() == nullptr;
1704     if (noBuffer) {
1705         RS_LOGW("RSDisplayRenderNodeDrawable::OnCapture: buffer is null!");
1706     }
1707 
1708     specialLayerType_ = GetSpecialLayerType(*params);
1709     if (specialLayerType_ != NO_SPECIAL_LAYER || UNLIKELY(noBuffer) || params->GetScreenInfo().isSamplingOn ||
1710         UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_) || isRenderSkipIfScreenOff_) {
1711         RS_LOGD("RSDisplayRenderNodeDrawable::OnCapture: \
1712             process RSDisplayRenderNode(id:[%{public}" PRIu64 "]) Not using UniRender buffer.",
1713             params->GetId());
1714         RS_TRACE_NAME("Process RSDisplayRenderNodeDrawable[" +
1715             std::to_string(params->GetScreenId()) + "] Not using UniRender buffer.");
1716 
1717         // Adding matrix affine transformation logic
1718         if (!UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_)) {
1719             rscanvas->ConcatMatrix(params->GetMatrix());
1720         }
1721 
1722         RSRenderNodeDrawable::OnCapture(canvas);
1723         DrawWatermarkIfNeed(*params, *rscanvas);
1724         RSDirtyRectsDfx rsDirtyRectsDfx(*this);
1725         rsDirtyRectsDfx.OnDraw(*rscanvas);
1726     } else {
1727         DrawHardwareEnabledNodes(canvas, *params);
1728     }
1729 }
1730 
DrawHardwareEnabledNodes(Drawing::Canvas & canvas,RSDisplayRenderParams & params)1731 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes(Drawing::Canvas& canvas, RSDisplayRenderParams& params)
1732 {
1733     auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
1734     if (!rscanvas) {
1735         RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes, rscanvas us nullptr");
1736         return;
1737     }
1738 
1739     FindHardwareEnabledNodes(params);
1740 
1741     uint32_t hwcNodesNum = static_cast<uint32_t>(params.GetHardwareEnabledDrawables().size());
1742     uint32_t hwcTopNodesNum = static_cast<uint32_t>(params.GetHardwareEnabledTopDrawables().size());
1743 
1744     RS_LOGI("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes: \
1745         process RSDisplayRenderNode(id:[%{public}" PRIu64 "]) \
1746         using UniRender buffer with hwcNodes(%{public}u, %{public}u)",
1747         GetId(), hwcNodesNum, hwcTopNodesNum);
1748     RS_TRACE_NAME_FMT("Process RSDisplayRenderNodeDrawable[%" PRIu64 "] \
1749         using UniRender buffer with hwcNodes(%u, %u)",
1750         params.GetScreenId(), hwcNodesNum, hwcTopNodesNum);
1751 
1752     if (hwcNodesNum > 0) {
1753         AdjustZOrderAndDrawSurfaceNode(params.GetHardwareEnabledDrawables(), canvas, params);
1754     }
1755 
1756     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1757     auto drawParams = RSUniRenderUtil::CreateBufferDrawParam(*GetRSSurfaceHandlerOnDraw(), false);
1758 
1759     // To get dump image
1760     // execute "param set rosen.dumpsurfacetype.enabled 4 && setenforce 0 && param set rosen.afbc.enabled 0"
1761     RSBaseRenderUtil::WriteSurfaceBufferToPng(drawParams.buffer);
1762     renderEngine->DrawDisplayNodeWithParams(*rscanvas, *GetRSSurfaceHandlerOnDraw(), drawParams);
1763 
1764     if (hwcTopNodesNum > 0) {
1765         AdjustZOrderAndDrawSurfaceNode(params.GetHardwareEnabledTopDrawables(), canvas, params);
1766     }
1767 }
1768 
DrawHardwareEnabledNodes(Drawing::Canvas & canvas)1769 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes(Drawing::Canvas& canvas)
1770 {
1771     bool noBuffer = (GetRSSurfaceHandlerOnDraw()->GetBuffer() == nullptr);
1772     if (!renderParams_ || noBuffer) {
1773         RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes params or buffer is null!");
1774         return;
1775     }
1776 
1777     auto displayParams = static_cast<RSDisplayRenderParams*>(renderParams_.get());
1778     Drawing::AutoCanvasRestore acr(canvas, true);
1779     DrawHardwareEnabledNodes(canvas, *displayParams);
1780 }
1781 
DrawHardwareEnabledNodesMissedInCacheImage(Drawing::Canvas & canvas)1782 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodesMissedInCacheImage(Drawing::Canvas& canvas)
1783 {
1784     auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1785     if (!params) {
1786         RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodesMissedInCacheImage params is null!");
1787         return;
1788     }
1789 
1790     Drawing::AutoCanvasRestore acr(canvas, true);
1791     FindHardwareEnabledNodes(*params);
1792     if (params->GetHardwareEnabledDrawables().size() != 0) {
1793         AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledDrawables(), canvas, *params);
1794     }
1795 }
1796 
DrawHardwareEnabledTopNodesMissedInCacheImage(Drawing::Canvas & canvas)1797 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledTopNodesMissedInCacheImage(Drawing::Canvas& canvas)
1798 {
1799     auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1800     if (!params) {
1801         RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodesMissedInCacheImage params is null!");
1802         return;
1803     }
1804 
1805     Drawing::AutoCanvasRestore acr(canvas, true);
1806     if (params->GetHardwareEnabledTopDrawables().size() != 0) {
1807         AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledTopDrawables(), canvas, *params);
1808     }
1809 }
1810 
DrawHardCursorNodesMissedInCacheImage(Drawing::Canvas & canvas)1811 void RSDisplayRenderNodeDrawable::DrawHardCursorNodesMissedInCacheImage(Drawing::Canvas& canvas)
1812 {
1813     auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1814     if (!params) {
1815         RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardCursorNodesMissedInCacheImage params is null!");
1816         return;
1817     }
1818 
1819     Drawing::AutoCanvasRestore acr(canvas, true);
1820     FindHardCursorNodes(*params);
1821     if (params->GetHardwareEnabledTopDrawables().size() != 0) {
1822         AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledTopDrawables(), canvas, *params);
1823     }
1824 }
1825 
FindHardCursorNodes(RSDisplayRenderParams & params)1826 void RSDisplayRenderNodeDrawable::FindHardCursorNodes(RSDisplayRenderParams& params)
1827 {
1828     params.GetHardwareEnabledTopDrawables().clear();
1829     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1830     if (!uniParam) {
1831         RS_LOGE("RSDisplayRenderNodeDrawable::FindHardCursorNodes uniParam is null");
1832         return;
1833     }
1834     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
1835     if (hardCursorDrawables.empty()) {
1836         return;
1837     }
1838     auto iter = hardCursorDrawables.find(GetId());
1839     if (iter != hardCursorDrawables.end()) {
1840         auto& hardCursorDrawable = iter->second;
1841         if (!hardCursorDrawable) {
1842             return;
1843         }
1844         auto surfaceParams = static_cast<RSSurfaceRenderParams *>(hardCursorDrawable->GetRenderParams().get());
1845         if (!surfaceParams) {
1846             RS_LOGE("RSDisplayRenderNodeDrawable::FindHardwareEnabledNodes surfaceParams is null");
1847             return;
1848         }
1849         auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable);
1850         if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
1851             params.GetHardwareEnabledTopDrawables().emplace_back(surfaceDrawable);
1852         }
1853     }
1854 }
1855 
SwitchColorFilter(RSPaintFilterCanvas & canvas,float hdrBrightnessRatio,bool displayP3Enable) const1856 void RSDisplayRenderNodeDrawable::SwitchColorFilter(RSPaintFilterCanvas& canvas, float hdrBrightnessRatio,
1857     bool displayP3Enable) const
1858 {
1859     const auto& renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1860     if (!renderEngine) {
1861         RS_LOGE("RSDisplayRenderNodeDrawable::SwitchColorFilter renderEngine is null");
1862         return;
1863     }
1864     ColorFilterMode colorFilterMode = renderEngine->GetColorFilterMode();
1865     if (colorFilterMode == ColorFilterMode::INVERT_COLOR_DISABLE_MODE ||
1866         colorFilterMode >= ColorFilterMode::DALTONIZATION_NORMAL_MODE) {
1867         return;
1868     }
1869 
1870     if (displayP3Enable) {
1871         SwitchColorFilterWithP3(canvas, colorFilterMode, hdrBrightnessRatio);
1872         return;
1873     }
1874 
1875     Drawing::AutoCanvasRestore acr(*curCanvas_, true);
1876     RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable::SetColorFilterModeToPaint mode:%d",
1877         static_cast<int32_t>(colorFilterMode));
1878     Drawing::Brush brush;
1879     RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush, hdrBrightnessRatio);
1880 #if defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)
1881     RSTagTracker tagTracker(
1882         renderEngine->GetRenderContext()->GetDrGPUContext(),
1883         RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
1884 #endif
1885     Drawing::SaveLayerOps slr(nullptr, &brush, Drawing::SaveLayerOps::INIT_WITH_PREVIOUS);
1886     canvas.SaveLayer(slr);
1887 }
1888 
SwitchColorFilterWithP3(RSPaintFilterCanvas & canvas,ColorFilterMode colorFilterMode,float hdrBrightnessRatio) const1889 void RSDisplayRenderNodeDrawable::SwitchColorFilterWithP3(RSPaintFilterCanvas& canvas,
1890     ColorFilterMode colorFilterMode, float hdrBrightnessRatio) const
1891 {
1892     RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable::SwitchColorFilterWithP3 mode:%d",
1893         static_cast<int32_t>(colorFilterMode));
1894 
1895     int32_t offscreenWidth = canvas.GetWidth();
1896     int32_t offscreenHeight = canvas.GetHeight();
1897 
1898     Drawing::ImageInfo info = Drawing::ImageInfo { offscreenWidth, offscreenHeight,
1899         Drawing::COLORTYPE_RGBA_F16, Drawing::ALPHATYPE_PREMUL, Drawing::ColorSpace::CreateSRGB()};
1900     auto offscreenSurface = canvas.GetSurface()->MakeSurface(info);
1901     auto offscreenCanvas = std::make_shared<RSPaintFilterCanvas>(offscreenSurface.get());
1902 
1903     Drawing::Brush brush;
1904     auto originSurfaceImage = canvas.GetSurface()->GetImageSnapshot();
1905     RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush, hdrBrightnessRatio);
1906     offscreenCanvas->AttachBrush(brush);
1907     offscreenCanvas->DrawImage(*originSurfaceImage, 0.f, 0.f, Drawing::SamplingOptions());
1908     offscreenCanvas->DetachBrush();
1909 
1910     auto offscreenImage = offscreenCanvas->GetSurface()->GetImageSnapshot();
1911     canvas.DrawImage(*offscreenImage, 0.f, 0.f, Drawing::SamplingOptions());
1912 }
1913 
FindHardwareEnabledNodes(RSDisplayRenderParams & params)1914 void RSDisplayRenderNodeDrawable::FindHardwareEnabledNodes(RSDisplayRenderParams& params)
1915 {
1916     params.GetHardwareEnabledTopDrawables().clear();
1917     params.GetHardwareEnabledDrawables().clear();
1918     auto& hardwareDrawables =
1919         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
1920     for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
1921         auto surfaceNodeDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
1922         if (!surfaceNodeDrawable || !surfaceNodeDrawable->ShouldPaint() ||
1923             displayNodeId != params.GetId()) {
1924             continue;
1925         }
1926         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
1927         if (surfaceParams == nullptr || !surfaceParams->GetHardwareEnabled()) {
1928             continue;
1929         }
1930         // To get dump image
1931         // execute "param set rosen.dumpsurfacetype.enabled 4 && setenforce 0 && param set rosen.afbc.enabled 0"
1932         auto buffer = surfaceParams->GetBuffer();
1933         RSBaseRenderUtil::WriteSurfaceBufferToPng(buffer, surfaceParams->GetId());
1934         if (surfaceNodeDrawable->IsHardwareEnabledTopSurface() || surfaceParams->IsLayerTop()) {
1935             // surfaceNode which should be drawn above displayNode like pointer window
1936             params.GetHardwareEnabledTopDrawables().emplace_back(drawable);
1937         } else {
1938             // surfaceNode which should be drawn below displayNode
1939             params.GetHardwareEnabledDrawables().emplace_back(drawable);
1940         }
1941     }
1942     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1943     if (!uniParam) {
1944         RS_LOGE("RSDisplayRenderNodeDrawable::FindHardCursorNodes uniParam is null");
1945         return;
1946     }
1947     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
1948     if (hardCursorDrawables.empty()) {
1949         return;
1950     }
1951     auto iter = hardCursorDrawables.find(GetId());
1952     if (iter != hardCursorDrawables.end()) {
1953         auto& hardCursorDrawable = iter->second;
1954         if (!hardCursorDrawable) {
1955             return;
1956         }
1957         auto surfaceNodeDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable);
1958         if (!surfaceNodeDrawable) {
1959             return;
1960         }
1961         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
1962         if (surfaceParams == nullptr) {
1963             return;
1964         }
1965         if (!RSUniRenderThread::GetCaptureParam().isSnapshot_) {
1966             auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable);
1967             if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
1968                 params.GetHardwareEnabledTopDrawables().emplace_back(surfaceDrawable);
1969             }
1970         }
1971     }
1972 }
1973 
AdjustZOrderAndDrawSurfaceNode(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & drawables,Drawing::Canvas & canvas,RSDisplayRenderParams & params) const1974 void RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode(
1975     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& drawables,
1976     Drawing::Canvas& canvas, RSDisplayRenderParams& params) const
1977 {
1978     if (!RSSystemProperties::GetHardwareComposerEnabled()) {
1979         RS_LOGW("RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode: \
1980             HardwareComposer is not enabled.");
1981         return;
1982     }
1983 
1984     // sort the surfaceNodes by ZOrder
1985     std::stable_sort(drawables.begin(), drawables.end(), [](const auto& first, const auto& second) -> bool {
1986         auto firstDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(first);
1987         auto secondDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(second);
1988         if (!firstDrawable || !firstDrawable->GetRenderParams() ||
1989             !secondDrawable || !secondDrawable->GetRenderParams()) {
1990             return false;
1991         }
1992         return firstDrawable->GetRenderParams()->GetLayerInfo().zOrder <
1993                secondDrawable->GetRenderParams()->GetLayerInfo().zOrder;
1994     });
1995 
1996     Drawing::AutoCanvasRestore acr(canvas, true);
1997     auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
1998     if (!rscanvas) {
1999         RS_LOGE("RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode, rscanvas is nullptr");
2000         return;
2001     }
2002     // draw hardware-composition nodes
2003     for (auto& drawable : drawables) {
2004         Drawing::AutoCanvasRestore acr(canvas, true);
2005         if (!drawable || !drawable->GetRenderParams()) {
2006             RS_LOGE("RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode surfaceParams is nullptr");
2007             continue;
2008         }
2009         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
2010         // SelfDrawingNodes need to use LayerMatrix(totalMatrix) when doing capturing
2011         auto matrix = surfaceParams->GetLayerInfo().matrix;
2012         // Use for mirror screen visible rect projection
2013         auto rect = surfaceParams->GetLayerInfo().dstRect;
2014         auto dstRect = Drawing::RectI(rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
2015         const auto &visibleRect = RSUniRenderThread::Instance().GetVisibleRect();
2016         if (dstRect.Intersect(visibleRect)) {
2017             matrix.PostTranslate(-visibleRect.GetLeft(), -visibleRect.GetTop());
2018         }
2019         canvas.ConcatMatrix(matrix);
2020         auto surfaceNodeDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
2021         surfaceNodeDrawable->DealWithSelfDrawingNodeBuffer(*rscanvas, *surfaceParams);
2022     }
2023 }
2024 
DrawWatermarkIfNeed(RSDisplayRenderParams & params,RSPaintFilterCanvas & canvas) const2025 void RSDisplayRenderNodeDrawable::DrawWatermarkIfNeed(RSDisplayRenderParams& params, RSPaintFilterCanvas& canvas) const
2026 {
2027     if (!RSUniRenderThread::Instance().GetWatermarkFlag()) {
2028         return;
2029     }
2030     auto image = RSUniRenderThread::Instance().GetWatermarkImg();
2031     if (image == nullptr) {
2032         RS_LOGE("RSDisplayRenderNodeDrawable::DrawWatermarkIfNeed image is null");
2033         return;
2034     }
2035     if (auto screenManager = CreateOrGetScreenManager()) {
2036         RS_TRACE_FUNC();
2037         auto screenInfo = screenManager->QueryScreenInfo(params.GetScreenId());
2038         auto mainWidth = static_cast<float>(screenInfo.width);
2039         auto mainHeight = static_cast<float>(screenInfo.height);
2040 
2041         // in certain cases (such as fold screen), the width and height must be swapped to fix the screen rotation.
2042         int angle = RSUniRenderUtil::GetRotationFromMatrix(canvas.GetTotalMatrix());
2043         if (angle == RS_ROTATION_90 || angle == RS_ROTATION_270) {
2044             std::swap(mainWidth, mainHeight);
2045         }
2046         auto srcRect = Drawing::Rect(0, 0, image->GetWidth(), image->GetHeight());
2047         auto dstRect = Drawing::Rect(0, 0, mainWidth, mainHeight);
2048         Drawing::Brush rectBrush;
2049         canvas.AttachBrush(rectBrush);
2050         canvas.DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions(),
2051             Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
2052         canvas.DetachBrush();
2053     }
2054 }
2055 
DrawCurtainScreen() const2056 void RSDisplayRenderNodeDrawable::DrawCurtainScreen() const
2057 {
2058     if (!RSUniRenderThread::Instance().IsCurtainScreenOn() || !curCanvas_) {
2059         return;
2060     }
2061     RS_TRACE_FUNC();
2062     curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
2063 }
2064 
UpdateSlrScale(ScreenInfo & screenInfo)2065 void RSDisplayRenderNodeDrawable::UpdateSlrScale(ScreenInfo& screenInfo)
2066 {
2067     if (screenInfo.isSamplingOn && RSSystemProperties::GetSLRScaleEnabled()) {
2068         if (slrScale_ == nullptr) {
2069             slrScale_ = std::make_unique<RSSLRScaleFunction>(
2070                 screenInfo.phyWidth, screenInfo.phyHeight, screenInfo.width, screenInfo.height);
2071         } else {
2072             slrScale_->CheckOrRefreshScreen(
2073                 screenInfo.phyWidth, screenInfo.phyHeight, screenInfo.width, screenInfo.height);
2074         }
2075         screenInfo.samplingDistance = slrScale_->GetKernelSize();
2076     } else {
2077         slrScale_ = nullptr;
2078     }
2079 }
2080 
ScaleCanvasIfNeeded(const ScreenInfo & screenInfo)2081 void RSDisplayRenderNodeDrawable::ScaleCanvasIfNeeded(const ScreenInfo& screenInfo)
2082 {
2083     if (!screenInfo.isSamplingOn) {
2084         slrScale_ = nullptr;
2085         return;
2086     }
2087     if (RSSystemProperties::GetSLRScaleEnabled() && slrScale_ != nullptr) {
2088         slrScale_->CanvasScale(*curCanvas_);
2089         return;
2090     }
2091     slrScale_ = nullptr;
2092     curCanvas_->Translate(screenInfo.samplingTranslateX, screenInfo.samplingTranslateY);
2093     curCanvas_->Scale(screenInfo.samplingScale, screenInfo.samplingScale);
2094 }
2095 
ClearTransparentBeforeSaveLayer()2096 void RSDisplayRenderNodeDrawable::ClearTransparentBeforeSaveLayer()
2097 {
2098     if (!canvasBackup_) {
2099         return;
2100     }
2101     RS_TRACE_NAME("ClearTransparentBeforeSaveLayer");
2102     auto& hardwareDrawables =
2103         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
2104     if (UNLIKELY(!renderParams_)) {
2105         RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw renderParams is null!");
2106         return;
2107     }
2108     auto params = static_cast<RSDisplayRenderParams*>(renderParams_.get());
2109     for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
2110         auto surfaceDrawable = static_cast<RSSurfaceRenderNodeDrawable*>(drawable.get());
2111         if (!surfaceDrawable || displayNodeId != params->GetId()) {
2112             continue;
2113         }
2114         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
2115         if (!surfaceParams || !surfaceParams->GetHardwareEnabled()) {
2116             continue;
2117         }
2118         RSAutoCanvasRestore arc(canvasBackup_.get());
2119         canvasBackup_->SetMatrix(surfaceParams->GetLayerInfo().matrix);
2120         canvasBackup_->ClipRect(surfaceParams->GetBounds());
2121         canvasBackup_->Clear(Drawing::Color::COLOR_TRANSPARENT);
2122     }
2123 }
2124 
PrepareHdrDraw(int32_t offscreenWidth,int32_t offscreenHeight)2125 void RSDisplayRenderNodeDrawable::PrepareHdrDraw(int32_t offscreenWidth, int32_t offscreenHeight)
2126 {
2127     offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(offscreenWidth, offscreenHeight);
2128 }
2129 
FinishHdrDraw(Drawing::Brush & paint,float hdrBrightnessRatio)2130 void RSDisplayRenderNodeDrawable::FinishHdrDraw(Drawing::Brush& paint, float hdrBrightnessRatio)
2131 {
2132     return;
2133 }
2134 
EnablescRGBForP3AndUiFirst(const GraphicColorGamut & currentGamut)2135 bool RSDisplayRenderNodeDrawable::EnablescRGBForP3AndUiFirst(const GraphicColorGamut& currentGamut)
2136 {
2137     return RSSystemParameters::IsNeedScRGBForP3(currentGamut) && RSMainThread::Instance()->IsUIFirstOn();
2138 }
2139 
PrepareOffscreenRender(const RSDisplayRenderNodeDrawable & displayDrawable,bool useFixedSize,bool useCanvasSize)2140 void RSDisplayRenderNodeDrawable::PrepareOffscreenRender(const RSDisplayRenderNodeDrawable& displayDrawable,
2141     bool useFixedSize, bool useCanvasSize)
2142 {
2143     RS_TRACE_NAME_FMT("%s: useFixedSize:%d, useCanvasSize:%d", __func__, useFixedSize, useCanvasSize);
2144     // params not null in caller
2145     auto params = static_cast<RSDisplayRenderParams*>(displayDrawable.GetRenderParams().get());
2146     // cleanup
2147     canvasBackup_ = nullptr;
2148     // check offscreen size and hardware renderer
2149     useFixedOffscreenSurfaceSize_ = false;
2150     const ScreenInfo& screenInfo = params->GetScreenInfo();
2151     int32_t offscreenWidth = static_cast<int32_t>(screenInfo.width);
2152     int32_t offscreenHeight = static_cast<int32_t>(screenInfo.height);
2153     // use fixed surface size in order to reduce create texture
2154     if (useFixedSize && RotateOffScreenParam::GetRotateOffScreenDisplayNodeEnable()
2155         && params->IsRotationChanged()) {
2156         useFixedOffscreenSurfaceSize_ = true;
2157         int32_t maxRenderSize;
2158         if (RSSystemProperties::GetCacheOptimizeRotateEnable()) {
2159             int32_t screenWidth = params->GetScreenInfo().width;
2160             int32_t screenHeight = params->GetScreenInfo().height;
2161             maxRenderSize = std::ceil(std::sqrt(screenWidth * screenWidth + screenHeight * screenHeight));
2162             offscreenTranslateX_ = std::round((maxRenderSize - offscreenWidth) / HALF);
2163             offscreenTranslateY_ = std::round((maxRenderSize - offscreenHeight) / HALF);
2164             RSUniRenderThread::Instance().SetWallpaperTranslate(offscreenTranslateX_, offscreenTranslateY_);
2165         } else {
2166             maxRenderSize =
2167                 static_cast<int32_t>(std::max(params->GetScreenInfo().width, params->GetScreenInfo().height));
2168             if (offscreenSurface_ != nullptr
2169                 && maxRenderSize != std::max(offscreenSurface_->Width(), offscreenSurface_->Height())) {
2170                 RS_TRACE_NAME("offscreen surface's max size has changed");
2171                 offscreenSurface_ = nullptr;
2172             }
2173         }
2174         offscreenWidth = maxRenderSize;
2175         offscreenHeight = maxRenderSize;
2176     } else {
2177         offscreenTranslateX_ = 0;
2178         offscreenTranslateY_ = 0;
2179     }
2180     if (params->IsRotationChanged()) {
2181         if (RSUniRenderThread::Instance().GetVmaOptimizeFlag()) {
2182             Drawing::StaticFactory::SetVmaCacheStatus(true); // render this frame with vma cache on
2183         }
2184     }
2185 
2186     if (offscreenWidth <= 0 || offscreenHeight <= 0) {
2187         RS_LOGE("RSDisplayRenderNodeDrawable::PrepareOffscreenRender, offscreenWidth or offscreenHeight is invalid");
2188         return;
2189     }
2190     if (curCanvas_->GetSurface() == nullptr) {
2191         curCanvas_->ClipRect(Drawing::Rect(0, 0, offscreenWidth, offscreenHeight), Drawing::ClipOp::INTERSECT, false);
2192         RS_LOGE("RSDisplayRenderNodeDrawable::PrepareOffscreenRender, current surface is nullptr");
2193         return;
2194     }
2195     if (!params->GetNeedOffscreen() || !useFixedOffscreenSurfaceSize_ || offscreenSurface_ == nullptr ||
2196         (params->GetHDRPresent() &&
2197         offscreenSurface_->GetImageInfo().GetColorType() != Drawing::ColorType::COLORTYPE_RGBA_F16)) {
2198         RS_TRACE_NAME_FMT("make offscreen surface with fixed size: [%d, %d]", offscreenWidth, offscreenHeight);
2199         bool isScRGBEnable = EnablescRGBForP3AndUiFirst(params->GetNewColorSpace());
2200         if (!params->GetNeedOffscreen() && (params->GetHDRPresent() || isScRGBEnable) && useCanvasSize) {
2201             offscreenWidth = curCanvas_->GetWidth();
2202             offscreenHeight = curCanvas_->GetHeight();
2203         }
2204         if (params->GetHDRPresent() || isScRGBEnable) {
2205             PrepareHdrDraw(offscreenWidth, offscreenHeight);
2206         } else {
2207             offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(offscreenWidth, offscreenHeight);
2208         }
2209     }
2210     // create offscreen surface and canvas
2211     if (useFixedOffscreenSurfaceSize_) {
2212         if (offscreenSurface_ == nullptr) {
2213             RS_TRACE_NAME_FMT("make offscreen surface with fixed size: [%d, %d]", offscreenWidth, offscreenHeight);
2214             offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(offscreenWidth, offscreenHeight);
2215         }
2216     } else {
2217         offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(offscreenWidth, offscreenHeight);
2218     }
2219 
2220     if (offscreenSurface_ == nullptr) {
2221         RS_LOGE("RSDisplayRenderNodeDrawable::PrepareOffscreenRender, offscreenSurface is nullptr");
2222         curCanvas_->ClipRect(Drawing::Rect(0, 0, offscreenWidth, offscreenHeight), Drawing::ClipOp::INTERSECT, false);
2223         return;
2224     }
2225     auto offscreenCanvas = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
2226 
2227     if (RSSystemProperties::GetCacheOptimizeRotateEnable()) {
2228         offscreenCanvas->ResetMatrix();
2229         offscreenCanvas->Translate(offscreenTranslateX_, offscreenTranslateY_);
2230     }
2231 
2232     // copy HDR properties into offscreen canvas
2233     offscreenCanvas->CopyHDRConfiguration(*curCanvas_);
2234     // copy current canvas properties into offscreen canvas
2235     offscreenCanvas->CopyConfigurationToOffscreenCanvas(*curCanvas_);
2236 
2237     // backup current canvas and replace with offscreen canvas
2238     canvasBackup_ = std::exchange(curCanvas_, offscreenCanvas);
2239 }
2240 
MakeBrightnessAdjustmentShader(const std::shared_ptr<Drawing::Image> & image,const Drawing::SamplingOptions & sampling,float hdrBrightnessRatio)2241 std::shared_ptr<Drawing::ShaderEffect> RSDisplayRenderNodeDrawable::MakeBrightnessAdjustmentShader(
2242     const std::shared_ptr<Drawing::Image>& image, const Drawing::SamplingOptions& sampling, float hdrBrightnessRatio)
2243 {
2244     static const std::string shaderString(R"(
2245         uniform shader imageInput;
2246         uniform float ratio;
2247         half4 main(float2 xy) {
2248             half4 c = imageInput.eval(xy);
2249             return half4(c.rgb * ratio, c.a);
2250         }
2251     )");
2252     if (brightnessAdjustmentShaderEffect_ == nullptr) {
2253         brightnessAdjustmentShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(shaderString);
2254         if (brightnessAdjustmentShaderEffect_ == nullptr) {
2255             ROSEN_LOGE("RSDisplayRenderNodeDrawable::MakeBrightnessAdjustmentShaderBuilder effect is null");
2256             return nullptr;
2257         }
2258     }
2259 
2260     auto builder = std::make_shared<Drawing::RuntimeShaderBuilder>(brightnessAdjustmentShaderEffect_);
2261     if (!builder) {
2262         ROSEN_LOGE("RSDisplayRenderNodeDrawable::MakeBrightnessAdjustmentShaderBuilder builder is null");
2263         return nullptr;
2264     }
2265     builder->SetChild("imageInput", Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
2266         Drawing::TileMode::CLAMP, sampling, Drawing::Matrix()));
2267     builder->SetUniform("ratio", hdrBrightnessRatio);
2268     return builder->MakeShader(nullptr, false);
2269 }
2270 
FinishOffscreenRender(const Drawing::SamplingOptions & sampling,bool isSamplingOn,float hdrBrightnessRatio)2271 void RSDisplayRenderNodeDrawable::FinishOffscreenRender(
2272     const Drawing::SamplingOptions& sampling, bool isSamplingOn, float hdrBrightnessRatio)
2273 {
2274     RS_TRACE_NAME_FMT("%s: isSamplingOn:%d, hdrBrightnessRatio:%f", __func__, isSamplingOn, hdrBrightnessRatio);
2275     if (canvasBackup_ == nullptr) {
2276         RS_LOGE("RSDisplayRenderNodeDrawable::FinishOffscreenRender, canvasBackup_ is nullptr");
2277         return;
2278     }
2279     if (offscreenSurface_ == nullptr) {
2280         RS_LOGE("RSDisplayRenderNodeDrawable::FinishOffscreenRender, offscreenSurface_ is nullptr");
2281         return;
2282     }
2283     auto image = offscreenSurface_->GetImageSnapshot();
2284     if (image == nullptr) {
2285         RS_LOGE("RSDisplayRenderNodeDrawable::FinishOffscreenRender, Surface::GetImageSnapshot is nullptr");
2286         return;
2287     }
2288     // draw offscreen surface to current canvas
2289     Drawing::Brush paint;
2290     bool isUseCustomShader = false;
2291     if (ROSEN_LNE(hdrBrightnessRatio, 1.0f)) {
2292         auto shader = MakeBrightnessAdjustmentShader(image, sampling, hdrBrightnessRatio);
2293         if (shader) {
2294             paint.SetShaderEffect(shader);
2295             isUseCustomShader = true;
2296         } else {
2297             FinishHdrDraw(paint, hdrBrightnessRatio);
2298         }
2299     }
2300     paint.SetAntiAlias(true);
2301     canvasBackup_->AttachBrush(paint);
2302     if (isSamplingOn) {
2303         if (RSSystemProperties::GetSLRScaleEnabled() && slrScale_) {
2304             slrScale_->ProcessOffscreenImage(*canvasBackup_, *image);
2305         } else {
2306             canvasBackup_->DrawImage(*image, 0, 0, sampling);
2307         }
2308     } else if (RSSystemProperties::GetCacheOptimizeRotateEnable()) {
2309         if (isUseCustomShader) {
2310             Drawing::Rect imageRect { 0., 0., image->GetImageInfo().GetWidth(), image->GetImageInfo().GetHeight() };
2311             canvasBackup_->Translate(-offscreenTranslateX_, -offscreenTranslateY_);
2312             canvasBackup_->DrawRect(imageRect);
2313         } else {
2314             canvasBackup_->DrawImage(*image, -offscreenTranslateX_, -offscreenTranslateY_, sampling);
2315         }
2316         canvasBackup_->Translate(offscreenTranslateX_, offscreenTranslateY_);
2317     } else {
2318         if (isUseCustomShader) {
2319             canvasBackup_->DrawRect({ 0., 0., image->GetImageInfo().GetWidth(), image->GetImageInfo().GetHeight() });
2320         } else {
2321             canvasBackup_->DrawImage(*image, 0, 0, sampling);
2322         }
2323     }
2324     canvasBackup_->DetachBrush();
2325     // restore current canvas and cleanup
2326     if (!useFixedOffscreenSurfaceSize_) {
2327         offscreenSurface_ = nullptr;
2328     }
2329     curCanvas_ = std::move(canvasBackup_);
2330 }
2331 
2332 #ifndef ROSEN_CROSS_PLATFORM
CreateSurface(sptr<IBufferConsumerListener> listener)2333 bool RSDisplayRenderNodeDrawable::CreateSurface(sptr<IBufferConsumerListener> listener)
2334 {
2335     auto consumer = surfaceHandler_->GetConsumer();
2336     if (consumer != nullptr && surface_ != nullptr) {
2337         RS_LOGI("RSDisplayRenderNode::CreateSurface already created, return");
2338         return true;
2339     }
2340     consumer = IConsumerSurface::Create("DisplayNode");
2341     if (consumer == nullptr) {
2342         RS_LOGE("RSDisplayRenderNode::CreateSurface get consumer surface fail");
2343         return false;
2344     }
2345     SurfaceError ret = consumer->RegisterConsumerListener(listener);
2346     if (ret != SURFACE_ERROR_OK) {
2347         RS_LOGE("RSDisplayRenderNode::CreateSurface RegisterConsumerListener fail");
2348         return false;
2349     }
2350     consumerListener_ = listener;
2351     auto producer = consumer->GetProducer();
2352     sptr<Surface> surface = Surface::CreateSurfaceAsProducer(producer);
2353     if (!surface) {
2354         RS_LOGE("RSDisplayRenderNode::CreateSurface CreateSurfaceAsProducer fail");
2355         return false;
2356     }
2357     surface->SetQueueSize(BUFFER_SIZE);
2358     auto client = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
2359     surface_ = client->CreateRSSurface(surface);
2360     RS_LOGI("RSDisplayRenderNode::CreateSurface end");
2361     surfaceCreated_ = true;
2362     surfaceHandler_->SetConsumer(consumer);
2363     return true;
2364 }
2365 #endif
2366 
SkipFrameByInterval(uint32_t refreshRate,uint32_t skipFrameInterval)2367 bool RSDisplayRenderNodeDrawable::SkipFrameByInterval(uint32_t refreshRate, uint32_t skipFrameInterval)
2368 {
2369     if (refreshRate == 0 || skipFrameInterval <= 1) {
2370         return false;
2371     }
2372     int64_t currentTime = std::chrono::duration_cast<std::chrono::nanoseconds>(
2373         std::chrono::steady_clock::now().time_since_epoch()).count();
2374     // the skipFrameInterval is equal to 60 divide the virtual screen refresh rate
2375     int64_t refreshInterval = currentTime - lastRefreshTime_;
2376     // 1000000000ns == 1s, 110/100 allows 10% over.
2377     bool needSkip = refreshInterval < (1000000000LL / refreshRate) * (skipFrameInterval - 1) * 110 / 100;
2378     if (!needSkip) {
2379         lastRefreshTime_ = currentTime;
2380     }
2381     return needSkip;
2382 }
2383 
SkipFrameByRefreshRate(uint32_t refreshRate,uint32_t expectedRefreshRate)2384 bool RSDisplayRenderNodeDrawable::SkipFrameByRefreshRate(uint32_t refreshRate, uint32_t expectedRefreshRate)
2385 {
2386     if (refreshRate == 0 || expectedRefreshRate == 0 || refreshRate == expectedRefreshRate) {
2387         return false;
2388     }
2389     int64_t currentTime = RSMainThread::Instance()->GetCurrentVsyncTime();
2390     int64_t minFrameInterval = 1000000000LL / expectedRefreshRate;
2391     if (minFrameInterval == 0) {
2392         return false;
2393     }
2394     // lastRefreshTime_ is next frame expected refresh time for virtual display
2395     if (lastRefreshTime_ <= 0) {
2396         lastRefreshTime_ = currentTime + minFrameInterval;
2397         return false;
2398     }
2399     if (currentTime < (lastRefreshTime_ - MAX_JITTER_NS)) {
2400         return true;
2401     }
2402     int64_t intervalNums = (currentTime - lastRefreshTime_ + MAX_JITTER_NS) / minFrameInterval;
2403     lastRefreshTime_ += (intervalNums + 1) * minFrameInterval;
2404     return false;
2405 }
2406 
SkipFrame(uint32_t refreshRate,ScreenInfo screenInfo)2407 bool RSDisplayRenderNodeDrawable::SkipFrame(uint32_t refreshRate, ScreenInfo screenInfo)
2408 {
2409     bool needSkip = false;
2410     switch (screenInfo.skipFrameStrategy) {
2411         case SKIP_FRAME_BY_INTERVAL:
2412             needSkip = SkipFrameByInterval(refreshRate, screenInfo.skipFrameInterval);
2413             break;
2414         case SKIP_FRAME_BY_REFRESH_RATE:
2415             needSkip = SkipFrameByRefreshRate(refreshRate, screenInfo.expectedRefreshRate);
2416             break;
2417         default:
2418             break;
2419     }
2420     return needSkip;
2421 }
2422 } // namespace OHOS::Rosen::DrawableV2
2423