• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "drawable/rs_logical_display_render_node_drawable.h"
17 
18 #include "common/rs_optional_trace.h"
19 #include "rs_trace.h"
20 #include "graphic_feature_param_manager.h"
21 #include "feature/dirty/rs_uni_dirty_compute_util.h"
22 #include "feature/drm/rs_drm_util.h"
23 #include "feature/hdr/rs_hdr_util.h"
24 #include "feature/uifirst/rs_uifirst_manager.h"
25 #include "params/rs_logical_display_render_params.h"
26 #include "params/rs_screen_render_params.h"
27 #include "pipeline/render_thread/rs_uni_render_thread.h"
28 #include "pipeline/render_thread/rs_uni_render_util.h"
29 #include "property/rs_point_light_manager.h"
30 #include "render/rs_pixel_map_util.h"
31 #include "static_factory.h"
32 
33 // dfx
34 #include "drawable/dfx/rs_refresh_rate_dfx.h"
35 #include "drawable/dfx/rs_dirty_rects_dfx.h"
36 #ifdef RS_PROFILER_ENABLED
37 #include "rs_profiler_capture_recorder.h"
38 #endif
39 
40 #ifdef SUBTREE_PARALLEL_ENABLE
41 #include "rs_parallel_manager.h"
42 #endif
43 
44 namespace OHOS::Rosen::DrawableV2 {
45 
46 namespace {
RectVectorToString(const std::vector<RectI> & regionRects)47 std::string RectVectorToString(const std::vector<RectI>& regionRects)
48 {
49     std::string results = "";
50     for (auto& rect : regionRects) {
51         results += rect.ToString();
52     }
53     return results;
54 }
55 
EnablescRGBForP3AndUiFirst(const GraphicColorGamut & currentGamut)56 bool EnablescRGBForP3AndUiFirst(const GraphicColorGamut& currentGamut)
57 {
58     return RSSystemParameters::IsNeedScRGBForP3(currentGamut) && RSUifirstManager::Instance().GetUiFirstSwitch();
59 }
60 
FinishHdrDraw(Drawing::Brush & paint,float hdrBrightnessRatio)61 void FinishHdrDraw(Drawing::Brush& paint, float hdrBrightnessRatio)
62 {
63     RS_LOGD("HDR FinishHdrDraw");
64     Drawing::Filter filter = paint.GetFilter();
65     Drawing::ColorMatrix luminanceMatrix;
66     luminanceMatrix.SetScale(hdrBrightnessRatio, hdrBrightnessRatio, hdrBrightnessRatio, 1.0f);
67     auto luminanceColorFilter = std::make_shared<Drawing::ColorFilter>(Drawing::ColorFilter::FilterType::MATRIX,
68         luminanceMatrix);
69     filter.SetColorFilter(luminanceColorFilter);
70     paint.SetFilter(filter);
71 }
72 
73 }
74 RSLogicalDisplayRenderNodeDrawable::Registrar RSLogicalDisplayRenderNodeDrawable::instance_;
75 std::shared_ptr<Drawing::RuntimeEffect> RSLogicalDisplayRenderNodeDrawable::brightnessAdjustmentShaderEffect_ = nullptr;
76 constexpr int32_t CAPTURE_WINDOW = 2; // To be deleted after captureWindow being deleted
RSLogicalDisplayRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)77 RSLogicalDisplayRenderNodeDrawable::RSLogicalDisplayRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
78     : RSRenderNodeDrawable(std::move(node))
79 {
80 }
81 
~RSLogicalDisplayRenderNodeDrawable()82 RSLogicalDisplayRenderNodeDrawable::~RSLogicalDisplayRenderNodeDrawable()
83 {
84     RS_LOGI("%{public}s, NodeId:[%{public}" PRIu64 "]", __func__, GetId());
85 }
86 
OnGenerate(std::shared_ptr<const RSRenderNode> node)87 RSRenderNodeDrawable::Ptr RSLogicalDisplayRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
88 {
89     return new RSLogicalDisplayRenderNodeDrawable(std::move(node));
90 }
91 
ClearCanvasStencil(RSPaintFilterCanvas & canvas,const RSLogicalDisplayRenderParams & params,const RSRenderThreadParams & uniParam,const ScreenInfo & screenInfo)92 void RSLogicalDisplayRenderNodeDrawable::ClearCanvasStencil(RSPaintFilterCanvas& canvas,
93     const RSLogicalDisplayRenderParams& params, const RSRenderThreadParams& uniParam, const ScreenInfo& screenInfo)
94 {
95     if (!uniParam.IsStencilPixelOcclusionCullingEnabled()) {
96         return;
97     }
98     auto topSurfaceOpaqueRects = params.GetTopSurfaceOpaqueRects();
99     if (topSurfaceOpaqueRects.empty()) {
100         return;
101     }
102     RS_OPTIONAL_TRACE_NAME_FMT("ClearStencil, rect(0, 0, %d, %d), stencilVal: 0",
103         screenInfo.width, screenInfo.height);
104     canvas.ClearStencil({0, 0, screenInfo.width, screenInfo.height}, 0);
105     std::reverse(topSurfaceOpaqueRects.begin(), topSurfaceOpaqueRects.end());
106     auto maxStencilVal = TOP_OCCLUSION_SURFACES_NUM * OCCLUSION_ENABLE_SCENE_NUM;
107     canvas.SetMaxStencilVal(maxStencilVal);
108     for (size_t i = 0; i < topSurfaceOpaqueRects.size(); i++) {
109         Drawing::RectI rect {topSurfaceOpaqueRects[i].left_,
110             topSurfaceOpaqueRects[i].top_,
111             topSurfaceOpaqueRects[i].right_,
112             topSurfaceOpaqueRects[i].bottom_};
113         auto stencilVal = OCCLUSION_ENABLE_SCENE_NUM *
114             (TOP_OCCLUSION_SURFACES_NUM - topSurfaceOpaqueRects.size() + i + 1);
115         RS_OPTIONAL_TRACE_NAME_FMT("ClearStencil, rect(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 "), "
116             "stencilVal: %zu", rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight(), stencilVal);
117         canvas.ClearStencil(rect, static_cast<uint32_t>(stencilVal));
118     }
119 }
120 
OnDraw(Drawing::Canvas & canvas)121 void RSLogicalDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
122 {
123     RS_TRACE_NAME("RSLogicalDisplayRenderNodeDrawable::OnDraw");
124     SetDrawSkipType(DrawSkipType::NONE);
125     if (!ShouldPaint()) {
126         SetDrawSkipType(DrawSkipType::SHOULD_NOT_PAINT);
127         return;
128     }
129 
130     Drawing::GPUResourceTag::SetCurrentNodeId(GetId());
131     curCanvas_ = reinterpret_cast<RSPaintFilterCanvas*>(&canvas);
132 
133     if (!curCanvas_) {
134         SetDrawSkipType(DrawSkipType::CANVAS_NULL);
135         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnDraw curCanvas is nullptr!");
136         return;
137     }
138 
139     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
140     if (UNLIKELY(!uniParam)) {
141         SetDrawSkipType(DrawSkipType::RENDER_THREAD_PARAMS_NULL);
142         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnDraw uniParam is nullptr!");
143         return;
144     }
145 
146     auto params = static_cast<RSLogicalDisplayRenderParams*>(GetRenderParams().get());
147     if (!params) {
148         SetDrawSkipType(DrawSkipType::RENDER_PARAMS_NULL);
149         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnDraw params is nullptr!");
150         return;
151     }
152     SetScreenRotationForPointLight(*params);
153     RSAutoCanvasRestore acr(curCanvas_, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
154     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
155     if (!screenManager) {
156         SetDrawSkipType(DrawSkipType::SCREEN_MANAGER_NULL);
157         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnDraw screenManager is nullptr!");
158         return;
159     }
160 
161     auto [_, screenParams] = GetScreenParams(*params);
162     if (!screenParams) {
163         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnDraw screenParams is nullptr!");
164         return;
165     }
166 
167     auto screenInfo = screenParams->GetScreenInfo();
168     const auto& processor = uniParam->GetRSProcessor();
169     auto mirroredDrawable = params->GetMirrorSourceDrawable().lock();
170     ScreenId paramScreenId = params->GetScreenId();
171     auto mirroredRenderParams = mirroredDrawable ? mirroredDrawable->GetRenderParams().get() : nullptr;
172     if (mirroredRenderParams ||
173         params->GetCompositeType() == CompositeType::UNI_RENDER_EXPAND_COMPOSITE) {
174         if (!processor->UpdateMirrorInfo(*this)) {
175             SetDrawSkipType(DrawSkipType::RENDER_ENGINE_NULL);
176             RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnDraw processor init failed!");
177             return;
178         }
179         if (mirroredRenderParams) {
180             currentBlackList_ = screenManager->GetVirtualScreenBlackList(paramScreenId);
181             RSUniRenderThread::Instance().SetBlackList(currentBlackList_);
182             curVisibleRect_ = RSUniRenderThread::Instance().GetVisibleRect();
183             enableVisibleRect_ = RSUniRenderThread::Instance().GetEnableVisibleRect();
184             if (params->GetCompositeType() == CompositeType::UNI_RENDER_COMPOSITE) {
185                 WiredScreenProjection(*params, processor);
186                 lastBlackList_ = currentBlackList_;
187                 return;
188             }
189             currentTypeBlackList_ = screenManager->GetVirtualScreenTypeBlackList(paramScreenId);
190             RSUniRenderThread::Instance().SetTypeBlackList(currentTypeBlackList_);
191             RSUniRenderThread::Instance().SetWhiteList(screenInfo.whiteList);
192             curSecExemption_ = params->GetSecurityExemption();
193             uniParam->SetSecExemption(curSecExemption_);
194             DrawMirrorScreen(*params, processor);
195             lastVisibleRect_ = curVisibleRect_;
196             lastBlackList_ = currentBlackList_;
197             lastTypeBlackList_ = currentTypeBlackList_;
198             lastSecExemption_ = curSecExemption_;
199         } else {
200             DrawExpandDisplay(*params);
201         }
202         return;
203     }
204 
205     auto hdrBrightnessRatio = screenParams->GetHdrBrightnessRatio();
206     bool isHdrOn = screenParams->GetHDRPresent();
207     bool isScRGBEnable = EnablescRGBForP3AndUiFirst(screenParams->GetNewColorSpace());
208     bool isOpDropped = uniParam->IsOpDropped();
209     bool needOffscreen = params->GetNeedOffscreen() || screenInfo.isSamplingOn || isHdrOn || isScRGBEnable;
210 
211     if (params->GetNeedOffscreen()) {
212         uniParam->SetOpDropped(false);
213         curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
214     }
215 
216     if (needOffscreen) {
217         scaleManager_ = uniParam->GetSLRScaleManager();
218         UpdateSlrScale(screenInfo, screenParams);
219         ScaleCanvasIfNeeded(screenInfo);
220         auto rect = curCanvas_->GetDeviceClipBounds();
221         if (screenInfo.isSamplingOn && scaleManager_ != nullptr) {
222             screenParams->SetSlrMatrix(scaleManager_->GetScaleMatrix());
223         }
224         PrepareOffscreenRender(*this, !screenInfo.isSamplingOn, !screenInfo.isSamplingOn);
225 #ifdef RS_PROFILER_ENABLED
226         if (auto canvas =
227                 RSCaptureRecorder::GetInstance().TryInstantCapture(static_cast<float>(curCanvas_->GetWidth()),
228                     static_cast<float>(curCanvas_->GetHeight()), SkpCaptureType::EXTENDED)) {
229             curCanvas_->AddCanvas(canvas);
230         }
231 #endif
232         if (!params->GetNeedOffscreen() && !screenInfo.isSamplingOn) {
233             curCanvas_->ClipRect(rect);
234         } else {
235             curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
236         }
237     }
238 
239     // prepare canvas
240     if (!params->GetNeedOffscreen()) {
241         params->ApplyAlphaAndMatrixToCanvas(*curCanvas_);
242     }
243 
244     ClearCanvasStencil(*curCanvas_, *params, *uniParam, screenInfo);
245 
246     // canvas draw
247 #ifdef SUBTREE_PARALLEL_ENABLE
248     if (!RSParallelManager::Singleton().OnDrawLogicDisplayNodeDrawable(this, curCanvas_)) {
249         RSRenderNodeDrawable::OnDraw(*curCanvas_);
250     }
251 #else
252     RSRenderNodeDrawable::OnDraw(*curCanvas_);
253 #endif
254 
255     DrawAdditionalContent(*curCanvas_);
256     if (needOffscreen && canvasBackup_) {
257         Drawing::AutoCanvasRestore acrBackUp(*canvasBackup_, true);
258         if (params->GetNeedOffscreen()) {
259             params->ApplyAlphaAndMatrixToCanvas(*canvasBackup_);
260         }
261         ClearTransparentBeforeSaveLayer();
262 #ifdef RS_PROFILER_ENABLED
263         RSCaptureRecorder::GetInstance().EndInstantCapture(SkpCaptureType::EXTENDED);
264 #endif
265         FinishOffscreenRender(Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NONE),
266             screenInfo.isSamplingOn, hdrBrightnessRatio);
267         uniParam->SetOpDropped(isOpDropped);
268     }
269 
270     if (RotateOffScreenParam::GetRotateOffScreenScreenNodeEnable() && !params->IsRotationChanged()) {
271         offscreenSurface_ = nullptr;
272         offscreenCanvas_ = nullptr;
273     }
274 }
275 
OnCapture(Drawing::Canvas & canvas)276 void RSLogicalDisplayRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
277 {
278     if (!ShouldPaint()) {
279         return;
280     }
281     const auto& params = static_cast<RSLogicalDisplayRenderParams*>(GetRenderParams().get());
282     if (!params) {
283         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnCapture params is null!");
284         return;
285     }
286     auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
287     if (!paintFilterCanvas) {
288         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnCapture paintFilterCanvas is null!");
289         return;
290     }
291     RSAutoCanvasRestore acr(paintFilterCanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
292     auto screenDrawable = std::static_pointer_cast<RSScreenRenderNodeDrawable>(
293         params->GetAncestorScreenDrawable().lock());
294     if (!screenDrawable) {
295         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnCapture screenDrawable is null!");
296         return;
297     }
298     auto screenParam = static_cast<RSScreenRenderParams*>(screenDrawable->GetRenderParams().get());
299     if (!screenParam) {
300         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::OnCapture screenParams is null!");
301         return;
302     }
303     bool noBuffer = RSUniRenderThread::GetCaptureParam().isSnapshot_ &&
304         screenDrawable->GetRSSurfaceHandlerOnDraw()->GetBuffer() == nullptr;
305     if (noBuffer) {
306         RS_LOGW("RSLogicalDisplayRenderNodeDrawable::OnCapture: buffer is null!");
307     }
308 
309     auto specialLayerType = GetSpecialLayerType(*params);
310     // Screenshot blackList, exclude surfaceNode in blackList while capturing displayNode
311     auto currentBlackList = RSUniRenderThread::Instance().GetBlackList();
312     if (specialLayerType != NO_SPECIAL_LAYER || UNLIKELY(noBuffer) || screenParam->GetScreenInfo().isSamplingOn ||
313         UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_) || screenDrawable->IsRenderSkipIfScreenOff() ||
314         !currentBlackList.empty()) {
315         offsetX_ = screenParam->GetScreenOffsetX();
316         offsetY_ = screenParam->GetScreenOffsetY();
317         RS_LOGD("RSLogicalDisplayRenderNodeDrawable::OnCapture: \
318             process RSLogicalDisplayRenderNode(id:[%{public}" PRIu64 "]) Not using UniRender buffer.",
319             params->GetId());
320         RS_TRACE_NAME_FMT("RSLogicalDisplayRenderNode::%s screenId: [%" PRIu64 "]"
321             " Not using UniRender buffer. specialLayer: %d, noBuffer: %d, "
322             "isSamplingOn: %d, isRenderSkipIfScreenOff: %d, blackList: %lu, "
323             "offsetX: %d, offsetY: %d", __func__, params->GetScreenId(),
324             specialLayerType != NO_SPECIAL_LAYER, noBuffer, screenParam->GetScreenInfo().isSamplingOn,
325             screenDrawable->IsRenderSkipIfScreenOff(), currentBlackList.size(), offsetX_, offsetY_);
326 
327         if (!UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_)) {
328             params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
329         }
330 
331         RSRenderNodeDrawable::OnCapture(canvas);
332         DrawAdditionalContent(*paintFilterCanvas);
333     } else {
334         canvas.Clear(Drawing::Color::COLOR_BLACK);
335         DrawHardwareEnabledNodes(canvas, *params);
336     }
337 }
338 
DrawHardwareEnabledNodes(Drawing::Canvas & canvas,RSLogicalDisplayRenderParams & params)339 void RSLogicalDisplayRenderNodeDrawable::DrawHardwareEnabledNodes(
340     Drawing::Canvas& canvas, RSLogicalDisplayRenderParams& params)
341 {
342     auto rsCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
343     if (!rsCanvas) {
344         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawHardwareEnabledNodes rscanvas is null!");
345         return;
346     }
347     auto screenDrawable = std::static_pointer_cast<RSScreenRenderNodeDrawable>(
348         params.GetAncestorScreenDrawable().lock());
349     auto screenParams = static_cast<RSScreenRenderParams*>(screenDrawable->GetRenderParams().get());
350 
351     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> hwcNodes;
352     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> hwcTopNodes;
353     RSUniRenderUtil::CollectHardwareEnabledNodesByDisplayNodeId(hwcNodes, hwcTopNodes, params.GetId());
354 
355     RS_LOGI("RSLogicalDisplayRenderNodeDrawable::DrawHardwareEnabledNodes: \
356         process RSScreenRenderNode(id:[%{public}" PRIu64 "]) \
357         Using UniRender buffer with hwcNodes(%{public}zu), hwcTopNodes(%{public}zu).",
358         GetId(), hwcNodes.size(), hwcTopNodes.size());
359     RS_TRACE_NAME_FMT("Process ScreenRenderNodeDrawable[%{public}" PRIu64 "] \
360         using UniRender buffer with hwcNodes(%{public}zu), hwcTopNodes(%{public}zu).",
361         params.GetScreenId(), hwcNodes.size(), hwcTopNodes.size());
362 
363     RSUniRenderUtil::AdjustZOrderAndDrawSurfaceNode(hwcNodes, canvas, *screenParams);
364 
365     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
366     auto drawParams = RSUniRenderUtil::CreateBufferDrawParam(*screenDrawable->GetRSSurfaceHandlerOnDraw(), false);
367     RSBaseRenderUtil::WriteSurfaceBufferToPng(drawParams.buffer);
368     renderEngine->DrawScreenNodeWithParams(*rsCanvas, *screenDrawable->GetRSSurfaceHandlerOnDraw(), drawParams);
369     RSUniRenderUtil::AdjustZOrderAndDrawSurfaceNode(hwcTopNodes, canvas, *screenParams);
370 }
371 
DrawExpandDisplay(RSLogicalDisplayRenderParams & params)372 void RSLogicalDisplayRenderNodeDrawable::DrawExpandDisplay(RSLogicalDisplayRenderParams& params)
373 {
374     RS_TRACE_FUNC();
375     auto [_, screenParam] = GetScreenParams(params);
376     if (!screenParam) {
377         RS_LOGE("%{public}s screenParam is nullptr", __func__);
378         return;
379     }
380     const auto& screenInfo = screenParam->GetScreenInfo();
381     if (screenParam->GetHDRPresent()) {
382         RS_LOGD("%{public}s HDRCast isHDREnabledVirtualScreen true", __func__);
383         curCanvas_->SetHDREnabledVirtualScreen(true);
384         curCanvas_->SetHdrOn(true);
385         PrepareOffscreenRender(*this, false, false);
386         RSRenderNodeDrawable::OnDraw(*curCanvas_);
387         FinishOffscreenRender(Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NONE),
388             screenInfo.isSamplingOn);
389     } else {
390         RSRenderNodeDrawable::OnDraw(*curCanvas_);
391         curCanvas_->SetOnMultipleScreen(true); // for HDR
392     }
393 }
394 
DrawAdditionalContent(RSPaintFilterCanvas & canvas)395 void RSLogicalDisplayRenderNodeDrawable::DrawAdditionalContent(RSPaintFilterCanvas& canvas)
396 {
397     RS_TRACE_FUNC();
398     DrawWatermarkIfNeed(canvas);
399     RSRefreshRateDfx(*this).OnDraw(canvas);
400 }
401 
DrawWatermarkIfNeed(RSPaintFilterCanvas & canvas)402 void RSLogicalDisplayRenderNodeDrawable::DrawWatermarkIfNeed(RSPaintFilterCanvas& canvas)
403 {
404     if (!RSUniRenderThread::Instance().GetWatermarkFlag()) {
405         return;
406     }
407     const auto& params = static_cast<RSLogicalDisplayRenderParams*>(GetRenderParams().get());
408     if (UNLIKELY(!params)) {
409         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWatermarkIfNeed params is null");
410         return;
411     }
412     auto screenManager = CreateOrGetScreenManager();
413     if (UNLIKELY(screenManager == nullptr)) {
414         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWatermarkIfNeed screenManager is null");
415         return;
416     }
417     auto image = RSUniRenderThread::Instance().GetWatermarkImg();
418     if (UNLIKELY(image == nullptr)) {
419         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWatermarkIfNeed image is null");
420         return;
421     }
422     RS_TRACE_FUNC();
423     canvas.Save();
424     canvas.ResetMatrix();
425 
426     auto rotation = params->GetScreenRotation();
427     auto screenCorrection = screenManager->GetScreenCorrection(params->GetScreenId());
428     auto mainWidth = params->GetFrameRect().GetWidth();
429     auto mainHeight = params->GetFrameRect().GetHeight();
430 
431     if (screenCorrection != ScreenRotation::INVALID_SCREEN_ROTATION &&
432         screenCorrection != ScreenRotation::ROTATION_0) {
433         // Recaculate rotation if mirrored screen has additional rotation angle
434         rotation = static_cast<ScreenRotation>((static_cast<int>(rotation) + SCREEN_ROTATION_NUM -
435             static_cast<int>(screenCorrection)) % SCREEN_ROTATION_NUM);
436     }
437 
438     if ((static_cast<int32_t>(rotation) - static_cast<int32_t>(params->GetNodeRotation())) % 2) {
439         std::swap(mainWidth, mainHeight);
440     }
441     if (rotation != ScreenRotation::ROTATION_0) {
442         if (rotation == ScreenRotation::ROTATION_90) {
443             canvas.Rotate(-(RS_ROTATION_90), 0, 0); // 90 degree
444             canvas.Translate(-(static_cast<float>(mainWidth)), 0);
445         } else if (rotation == ScreenRotation::ROTATION_180) {
446             canvas.Rotate(-(RS_ROTATION_180), static_cast<float>(mainWidth) / 2, // 2 half of screen width
447                 static_cast<float>(mainHeight) / 2); // 2 half of screen height
448         } else if (rotation == ScreenRotation::ROTATION_270) {
449             canvas.Rotate(-(RS_ROTATION_270), 0, 0); // 270 degree
450             canvas.Translate(0, -(static_cast<float>(mainHeight)));
451         }
452     }
453 
454     auto srcRect = Drawing::Rect(0, 0, image->GetWidth(), image->GetHeight());
455     auto dstRect = Drawing::Rect(0, 0, mainWidth, mainHeight);
456     Drawing::Brush rectBrush;
457     canvas.AttachBrush(rectBrush);
458     canvas.DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions(),
459         Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
460     canvas.DetachBrush();
461     canvas.Restore();
462 }
463 
UpdateDisplayDirtyManager(std::shared_ptr<RSDirtyRegionManager> dirtyManager,int32_t bufferage,bool useAlignedDirtyRegion)464 void RSLogicalDisplayRenderNodeDrawable::UpdateDisplayDirtyManager(std::shared_ptr<RSDirtyRegionManager> dirtyManager,
465     int32_t bufferage, bool useAlignedDirtyRegion)
466 {
467     dirtyManager->SetBufferAge(bufferage);
468     dirtyManager->UpdateDirty(useAlignedDirtyRegion);
469 }
470 
CalculateVirtualDirty(std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,RSScreenRenderNodeDrawable & curScreenDrawable,RSLogicalDisplayRenderParams & params,Drawing::Matrix canvasMatrix)471 std::vector<RectI> RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirty(
472     std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, RSScreenRenderNodeDrawable& curScreenDrawable,
473     RSLogicalDisplayRenderParams& params, Drawing::Matrix canvasMatrix)
474 {
475     // uniParam/drawable/mirroredParams not null in caller
476     Occlusion::Region mappedDamageRegion;
477     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
478     auto curScreenParams = static_cast<RSScreenRenderParams*>(curScreenDrawable.GetRenderParams().get());
479     auto drawable = curScreenParams->GetMirrorSourceDrawable().lock();
480     if (!drawable) {
481         RS_LOGE("%{public}s mirroredDrawable nullptr", __func__);
482         virtualProcesser->SetRoiRegionToCodec(mappedDamageRegion.GetRegionRectIs());
483         return mappedDamageRegion.GetRegionRectIs();
484     }
485     auto mirroredDrawable = std::static_pointer_cast<RSScreenRenderNodeDrawable>(drawable);
486     auto mirrorParams = static_cast<RSScreenRenderParams*>(mirroredDrawable->GetRenderParams().get());
487     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
488     if (!screenManager) {
489         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirty ScreenManager is nullptr");
490         virtualProcesser->SetRoiRegionToCodec(mappedDamageRegion.GetRegionRectIs());
491         return mappedDamageRegion.GetRegionRectIs();
492     }
493     const auto& curScreenInfo = curScreenParams->GetScreenInfo();
494     if (!curScreenInfo.isEqualVsyncPeriod) {
495         RS_LOGD("RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirty frame rate is irregular");
496         virtualProcesser->SetRoiRegionToCodec(mappedDamageRegion.GetRegionRectIs());
497         return mappedDamageRegion.GetRegionRectIs();
498     }
499     const auto& mainScreenInfo = mirrorParams->GetScreenInfo();
500     int32_t bufferAge = virtualProcesser->GetBufferAge();
501     std::vector<RectI> damageRegionRects = RSUniRenderUtil::MergeDirtyHistoryInVirtual(
502         *mirroredDrawable, bufferAge, mainScreenInfo, false);
503     std::shared_ptr<RSObjAbsGeometry> tmpGeo = std::make_shared<RSObjAbsGeometry>();
504     for (auto& rect : damageRegionRects) {
505         RectI mappedRect = tmpGeo->MapRect(rect.ConvertTo<float>(), canvasMatrix);
506         mappedDamageRegion.OrSelf(Occlusion::Region(Occlusion::Rect(mappedRect)));
507     }
508 
509     bool needRefresh = !(lastCanvasMatrix_ == canvasMatrix) || !(lastMirrorMatrix_ == mirrorParams->GetMatrix()) ||
510         uniParam->GetForceMirrorScreenDirty() || lastBlackList_ != currentBlackList_ ||
511         lastTypeBlackList_ != currentTypeBlackList_ || params.IsSpecialLayerChanged() ||
512         lastSecExemption_ != curSecExemption_ || uniParam->GetVirtualDirtyRefresh() || virtualDirtyNeedRefresh_ ||
513         (enableVisibleRect_ && (lastVisibleRect_ != curVisibleRect_ || params.HasSecLayerInVisibleRectChanged()));
514     if (needRefresh) {
515         curScreenDrawable.GetSyncDirtyManager()->ResetDirtyAsSurfaceSize();
516         virtualDirtyNeedRefresh_ = false;
517         lastCanvasMatrix_ = canvasMatrix;
518         lastMirrorMatrix_ = mirrorParams->GetMatrix();
519     }
520     RectI hwcRect = mirroredDrawable->GetSyncDirtyManager()->GetHwcDirtyRegion();
521     if (!hwcRect.IsEmpty()) {
522         if (mainScreenInfo.isSamplingOn && mainScreenInfo.samplingScale > 0) {
523             Drawing::Matrix scaleMatrix;
524             scaleMatrix.SetScaleTranslate(mainScreenInfo.samplingScale, mainScreenInfo.samplingScale,
525                 mainScreenInfo.samplingTranslateX, mainScreenInfo.samplingTranslateY);
526             hwcRect = RSObjAbsGeometry::MapRect(hwcRect.ConvertTo<float>(), scaleMatrix);
527             const Vector4<int> expandSize{mainScreenInfo.samplingDistance, mainScreenInfo.samplingDistance,
528                 mainScreenInfo.samplingDistance, mainScreenInfo.samplingDistance};
529             hwcRect = hwcRect.MakeOutset(expandSize);
530         }
531         RectI mappedHwcRect = tmpGeo->MapRect(hwcRect.ConvertTo<float>(), canvasMatrix);
532         curScreenDrawable.GetSyncDirtyManager()->MergeDirtyRect(mappedHwcRect);
533     }
534     UpdateDisplayDirtyManager(curScreenDrawable.GetSyncDirtyManager(), bufferAge, false);
535     auto extraDirty = curScreenDrawable.GetSyncDirtyManager()->GetDirtyRegion();
536     mappedDamageRegion.OrSelf(Occlusion::Region(Occlusion::Rect(extraDirty)));
537 
538     if (!virtualProcesser->GetDrawVirtualMirrorCopy()) {
539         RSUniFilterDirtyComputeUtil::DealWithFilterDirtyRegion(
540             mappedDamageRegion, mappedDamageRegion, *mirroredDrawable, canvasMatrix, false);
541     }
542     auto mappedDamageRegionRects = mappedDamageRegion.GetRegionRectIs();
543     if (!uniParam->IsVirtualDirtyDfxEnabled()) {
544         virtualProcesser->SetDirtyInfo(mappedDamageRegionRects);
545         RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
546             mappedDamageRegionRects.size(), RectVectorToString(mappedDamageRegionRects).c_str());
547     }
548     return mappedDamageRegionRects;
549 }
550 
CalculateVirtualDirtyForWiredScreen(RSScreenRenderNodeDrawable & curScreenDrawable,Drawing::Matrix canvasMatrix)551 std::vector<RectI> RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen(
552     RSScreenRenderNodeDrawable& curScreenDrawable, Drawing::Matrix canvasMatrix)
553 {
554     std::vector<RectI> damageRegionRects;
555     auto curScreenParams = static_cast<RSScreenRenderParams*>(curScreenDrawable.GetRenderParams().get());
556     auto mirroredDrawable =
557         std::static_pointer_cast<RSScreenRenderNodeDrawable>(curScreenParams->GetMirrorSourceDrawable().lock());
558     if (!mirroredDrawable || !mirroredDrawable->GetRenderParams()) {
559         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen mirroredNode is null");
560         return damageRegionRects;
561     }
562     const auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
563     if (uniParam == nullptr || !uniParam->IsVirtualDirtyEnabled() ||
564         (enableVisibleRect_ && curVisibleRect_.GetTop() > 0)) {
565         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen invalid uniparam");
566         return damageRegionRects;
567     }
568     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
569     if (screenManager == nullptr) {
570         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen screenManager is null");
571         return damageRegionRects;
572     }
573     auto curScreenInfo = curScreenParams->GetScreenInfo();
574     if (!curScreenInfo.isEqualVsyncPeriod) {
575         RS_LOGD("RSLogicalDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen frame rate is irregular");
576         return damageRegionRects;
577     }
578     int32_t bufferAge = curScreenDrawable.GetBufferAge();
579     const auto mirroredParams = static_cast<RSScreenRenderParams*>(mirroredDrawable->GetRenderParams().get());
580     const auto& mainScreenInfo = mirroredParams->GetScreenInfo();
581     std::shared_ptr<RSObjAbsGeometry> tmpGeo = std::make_shared<RSObjAbsGeometry>();
582     // merge history dirty and map to mirrored wired screen by matrix
583     auto tempDamageRegionRects = RSUniRenderUtil::MergeDirtyHistoryInVirtual(
584         *mirroredDrawable, bufferAge, mainScreenInfo, true);
585     for (auto& rect : tempDamageRegionRects) {
586         RectI mappedRect = tmpGeo->MapRect(rect.ConvertTo<float>(), canvasMatrix);
587         damageRegionRects.emplace_back(mappedRect);
588     }
589 
590     auto syncDirtyManager = curScreenDrawable.GetSyncDirtyManager();
591     // reset dirty rect as mirrored wired screen size when first time connection or matrix changed
592     bool needRefresh = !(lastCanvasMatrix_ == canvasMatrix) || !(lastMirrorMatrix_ == mirroredParams->GetMatrix()) ||
593         uniParam->GetForceMirrorScreenDirty() || (enableVisibleRect_ && lastVisibleRect_ != curVisibleRect_) ||
594         lastBlackList_ != currentBlackList_ || uniParam->GetVirtualDirtyRefresh() || virtualDirtyNeedRefresh_;
595     if (needRefresh) {
596         curScreenDrawable.GetSyncDirtyManager()->ResetDirtyAsSurfaceSize();
597         virtualDirtyNeedRefresh_ = false;
598         lastCanvasMatrix_ = canvasMatrix;
599         lastMirrorMatrix_ = mirroredParams->GetMatrix();
600     }
601     RectI hwcRect = mirroredDrawable->GetSyncDirtyManager()->GetHwcDirtyRegion();
602     if (!hwcRect.IsEmpty()) {
603         RectI mappedHwcRect = tmpGeo->MapRect(hwcRect.ConvertTo<float>(), canvasMatrix);
604         syncDirtyManager->MergeDirtyRect(mappedHwcRect);
605     }
606     UpdateDisplayDirtyManager(syncDirtyManager, bufferAge, false);
607     auto extraDirty = syncDirtyManager->GetDirtyRegion();
608     if (!extraDirty.IsEmpty()) {
609         damageRegionRects.emplace_back(extraDirty);
610     }
611     if (!uniParam->IsVirtualDirtyDfxEnabled()) {
612         curScreenDrawable.SetDamageRegion(damageRegionRects);
613         RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
614             damageRegionRects.size(), RectVectorToString(damageRegionRects).c_str());
615     }
616     return damageRegionRects;
617 }
618 
WiredScreenProjection(RSLogicalDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)619 void RSLogicalDisplayRenderNodeDrawable::WiredScreenProjection(
620     RSLogicalDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
621 {
622     RS_TRACE_FUNC();
623     if (!curCanvas_) {
624         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::WiredScreenProjection failed to create canvas");
625         return;
626     }
627     auto [curScreenDrawable, curScreenParams] = GetScreenParams(params);
628     if (!curScreenDrawable || !curScreenParams) {
629         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::WiredScreenProjection curScreen is null");
630         return;
631     }
632     auto [mirroredDrawable, mirroredParams,
633         mirroredScreenDrawable, mirroredScreenParams] = GetMirrorSourceParams(params);
634     if (!mirroredDrawable || !mirroredParams || !mirroredScreenDrawable || !mirroredScreenParams) {
635         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::WiredScreenProjection mirror source is null");
636         return;
637     }
638 
639     auto cacheImage = mirroredScreenDrawable->GetCacheImgForCapture();
640     bool isProcessSecLayer = !MultiScreenParam::IsExternalScreenSecure() &&
641         mirroredParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_SECURITY);
642     auto isRedraw = RSSystemParameters::GetDebugMirrorOndrawEnabled() || !cacheImage ||
643         (RSSystemParameters::GetWiredScreenOndrawEnabled() && !enableVisibleRect_ &&
644             (mirroredScreenParams->GetHDRPresent()  || isProcessSecLayer || !currentBlackList_.empty() ||
645                 mirroredParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_PROTECTED)));
646     if (isRedraw) {
647         isMirrorSLRCopy_ = false;
648     } else {
649         // cacheImage must be valid when isMirrorSLRCopy_ is true
650         isMirrorSLRCopy_ = !enableVisibleRect_ && RSSystemProperties::GetSLRScaleEnabled();
651     }
652 
653     // HDR does not support wired screen
654     if (isRedraw) {
655         MirrorRedrawDFX(true, params.GetScreenId());
656         DrawWiredMirrorOnDraw(*mirroredDrawable, params, processor);
657     } else {
658         MirrorRedrawDFX(false, params.GetScreenId());
659         DrawWiredMirrorCopy(*mirroredDrawable, params);
660     }
661 }
662 
DrawWiredMirrorCopy(RSLogicalDisplayRenderNodeDrawable & mirroredDrawable,RSLogicalDisplayRenderParams & params)663 void RSLogicalDisplayRenderNodeDrawable::DrawWiredMirrorCopy(RSLogicalDisplayRenderNodeDrawable& mirroredDrawable,
664     RSLogicalDisplayRenderParams& params)
665 {
666     RS_TRACE_FUNC();
667     auto mirroredParams = static_cast<RSLogicalDisplayRenderParams*>(mirroredDrawable.GetRenderParams().get());
668     if (!mirroredParams) {
669         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWiredMirrorCopy mirroredParams is null");
670         return;
671     }
672     auto mirroredScreenDrawable = std::static_pointer_cast<RSScreenRenderNodeDrawable>(
673         mirroredParams->GetAncestorScreenDrawable().lock());
674     if (!mirroredScreenDrawable) {
675         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWiredMirrorCopy mirroredScreenDrawable is null");
676         return;
677     }
678     auto [curScreenDrawable, curScreenParams] = GetScreenParams(params);
679     if (!curScreenDrawable || !curScreenParams) {
680         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWiredMirrorCopy curScreenDrawable is null");
681         return;
682     }
683 
684     curCanvas_->Save();
685     ScaleAndRotateMirrorForWiredScreen(mirroredDrawable);
686     RSDirtyRectsDfx rsDirtyRectsDfx(*curScreenDrawable);
687     auto matrix = isMirrorSLRCopy_ ? scaleManager_->GetScaleMatrix() : curCanvas_->GetTotalMatrix();
688     matrix.PreTranslate(-mirroredParams->GetOffsetX(), -mirroredParams->GetOffsetY());
689     std::vector<RectI> damageRegionRects = CalculateVirtualDirtyForWiredScreen(*curScreenDrawable, matrix);
690     rsDirtyRectsDfx.SetVirtualDirtyRects(damageRegionRects, curScreenParams->GetScreenInfo());
691 
692     auto width = mirroredParams->GetBounds().GetWidth();
693     auto height = mirroredParams->GetBounds().GetHeight();
694     if (mirroredParams->GetNodeRotation() == ScreenRotation::ROTATION_90 ||
695         mirroredParams->GetNodeRotation() == ScreenRotation::ROTATION_270) {
696         std::swap(width, height);
697     }
698 
699     auto cacheImage = mirroredScreenDrawable->GetCacheImgForCapture();
700     if (cacheImage && RSSystemProperties::GetDrawMirrorCacheImageEnabled()) {
701         RS_TRACE_NAME("DrawWiredMirrorCopy with cacheImage");
702         if (isMirrorSLRCopy_) {
703             RS_TRACE_NAME("DrawWiredMirrorCopy with SLRScale");
704             scaleManager_->ProcessCacheImage(*curCanvas_, *cacheImage);
705         } else if (!enableVisibleRect_) {
706             RS_TRACE_NAME("DrawWiredMirrorCopy with SkiaScale");
707             Drawing::RectI srcRect = { mirroredParams->GetOffsetX(), mirroredParams->GetOffsetY(),
708                 mirroredParams->GetOffsetX() + width, mirroredParams->GetOffsetY() + height };
709             RSUniRenderUtil::ProcessCacheImageRect(*curCanvas_, *cacheImage, srcRect,
710                 Drawing::Rect(0, 0, width, height));
711         } else {
712             RS_TRACE_NAME_FMT("DrawWiredMirrorCopy with VisibleRect[%d, %d, %d, %d]",
713                 curVisibleRect_.GetLeft(), curVisibleRect_.GetTop(),
714                 curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight());
715             RSUniRenderUtil::ProcessCacheImageRect(*curCanvas_, *cacheImage, curVisibleRect_,
716                 Drawing::Rect(0, 0, curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight()));
717         }
718     } else {
719         RS_TRACE_NAME("DrawWiredMirrorCopy with displaySurface");
720         auto drawParams = RSUniRenderUtil::CreateBufferDrawParam(
721             *mirroredScreenDrawable->GetRSSurfaceHandlerOnDraw(), false); // false: draw with gpu
722         auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
723         if (enableVisibleRect_) {
724             drawParams.srcRect = curVisibleRect_;
725             drawParams.dstRect = Drawing::Rect(0, 0, curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight());
726         } else {
727             drawParams.srcRect = { mirroredParams->GetOffsetX(), mirroredParams->GetOffsetY(),
728                 mirroredParams->GetOffsetX() + width,  mirroredParams->GetOffsetY() + height };
729             drawParams.dstRect = Drawing::Rect(0, 0, width, height);
730         }
731         drawParams.isMirror = true;
732         renderEngine->DrawScreenNodeWithParams(*curCanvas_,
733             *mirroredScreenDrawable->GetRSSurfaceHandlerOnDraw(), drawParams);
734         RSMainThread::Instance()->RequestNextVSync();
735     }
736     curCanvas_->Restore();
737     rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
738 }
739 
CheckDirtyRefresh(CompositeType type,bool hasSecLayerInVisibleRect)740 void RSLogicalDisplayRenderNodeDrawable::CheckDirtyRefresh(CompositeType type, bool hasSecLayerInVisibleRect)
741 {
742     auto params = static_cast<RSLogicalDisplayRenderParams*>(GetRenderParams().get());
743     if (!params) {
744         return;
745     }
746     auto [mirroredDrawable, mirroredParams, _, __] = GetMirrorSourceParams(*params);
747     if (!mirroredDrawable || !mirroredParams) {
748         return;
749     }
750     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
751     if (uniParam == nullptr) {
752         return;
753     }
754     auto hasSecSurface = mirroredParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_SECURITY);
755     if (type == CompositeType::UNI_RENDER_COMPOSITE) {
756         if (hasSecSurface) {
757             uniParam->SetVirtualDirtyRefresh(true);
758         }
759     } else if (type == CompositeType::UNI_RENDER_MIRROR_COMPOSITE) {
760         if ((((!enableVisibleRect_ && hasSecSurface) || (enableVisibleRect_ && hasSecLayerInVisibleRect)) &&
761             !uniParam->GetSecExemption()) || params->GetVirtualScreenMuteStatus()) {
762             uniParam->SetVirtualDirtyRefresh(true);
763         }
764     }
765 }
766 
DrawWiredMirrorOnDraw(RSLogicalDisplayRenderNodeDrawable & mirroredDrawable,RSLogicalDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)767 void RSLogicalDisplayRenderNodeDrawable::DrawWiredMirrorOnDraw(RSLogicalDisplayRenderNodeDrawable& mirroredDrawable,
768     RSLogicalDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
769 {
770     RS_TRACE_FUNC();
771     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
772     if (uniParam == nullptr) {
773         return;
774     }
775     const auto mirroredParams = static_cast<RSLogicalDisplayRenderParams*>(mirroredDrawable.GetRenderParams().get());
776     if (mirroredParams == nullptr) {
777         return;
778     }
779     auto [curScreenDrawable, curScreenParam] = GetScreenParams(params);
780     if (!curScreenDrawable || !curScreenParam) {
781         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWiredMirrorOnDraw curScreenDrawable is null");
782         return;
783     }
784     auto [_, mirroredScreenParams] = GetScreenParams(*mirroredParams);
785     if (!mirroredScreenParams) {
786         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawWiredMirrorOnDraw mirroredScreenParams is null");
787         return;
788     }
789 
790     RS_TRACE_NAME("DrawWiredMirror with Redraw");
791     RSDirtyRectsDfx rsDirtyRectsDfx(*curScreenDrawable);
792 
793     // for HDR
794     curCanvas_->SetOnMultipleScreen(true);
795     curCanvas_->SetDisableFilterCache(true);
796 
797     // Draw security mask if has security surface and external screen is not secure
798     auto hasSecSurface = mirroredParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_SECURITY);
799     if (hasSecSurface && !MultiScreenParam::IsExternalScreenSecure()) {
800         DrawSecurityMask();
801         virtualDirtyNeedRefresh_ = true;
802         rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
803         return;
804     }
805 
806     curCanvas_->Save();
807     ScaleAndRotateMirrorForWiredScreen(mirroredDrawable);
808     Drawing::Matrix canvasMatrix = curCanvas_->GetTotalMatrix();
809     curCanvas_->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
810     bool isOpDropped = uniParam->IsOpDropped();
811     uniParam->SetOpDropped(false);
812     auto screenInfo = mirroredScreenParams->GetScreenInfo();
813     uniParam->SetScreenInfo(screenInfo);
814 
815     auto width = mirroredParams->GetBounds().GetWidth();
816     auto height = mirroredParams->GetBounds().GetHeight();
817     if (mirroredParams->GetNodeRotation() == ScreenRotation::ROTATION_90 ||
818         mirroredParams->GetNodeRotation() == ScreenRotation::ROTATION_270) {
819         std::swap(width, height);
820     }
821     Drawing::Rect rect(0, 0, width, height);
822     curCanvas_->ClipRect(rect, Drawing::ClipOp::INTERSECT, false);
823     curCanvas_->Translate(-mirroredParams->GetOffsetX(), -mirroredParams->GetOffsetY());
824     curCanvas_->ConcatMatrix(mirroredParams->GetMatrix());
825     RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
826     mirroredDrawable.RSRenderNodeDrawable::OnDraw(*curCanvas_);
827 
828     bool displayP3Enable = curScreenParam->GetNewColorSpace() == GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
829     // 1.f: wired screen not use hdr, use default value 1.f
830     RSUniRenderUtil::SwitchColorFilter(*curCanvas_, 1.f, displayP3Enable);
831 
832     uniParam->SetOpDropped(isOpDropped);
833     RSUniRenderThread::Instance().SetBlackList({});
834     curCanvas_->Restore();
835     rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
836     if (mirroredParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_PROTECTED)) {
837         RSDrmUtil::DRMCreateLayer(processor, canvasMatrix);
838         curScreenParam->SetGlobalZOrder(curScreenParam->GetGlobalZOrder() + 1);
839     }
840 }
841 
DrawMirrorScreen(RSLogicalDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)842 void RSLogicalDisplayRenderNodeDrawable::DrawMirrorScreen(
843     RSLogicalDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
844 {
845     RS_TRACE_FUNC();
846     // uniParam/drawable/mirroredParams/renderParams_ not null in caller
847     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
848     auto [mirroredDrawable, mirroredParams,
849         mirroredScreenDrawable, mirroredScreenParams] = GetMirrorSourceParams(params);
850     if (!mirroredDrawable || !mirroredParams) {
851         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirrorScreen mirror source is null");
852         return;
853     }
854     auto specialLayerType = GetSpecialLayerType(*mirroredParams,
855         enableVisibleRect_ ? params.HasSecLayerInVisibleRect() : true);
856     auto virtualProcesser = RSProcessor::ReinterpretCast<RSUniRenderVirtualProcessor>(processor);
857     if (!virtualProcesser) {
858         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirrorScreen virtualProcesser is null");
859         return;
860     }
861     virtualProcesser->CanvasInit(*this);
862 
863     auto cacheImage = mirroredScreenDrawable ? mirroredScreenDrawable->GetCacheImgForCapture() : nullptr;
864 
865     const auto screenInfo = uniParam->GetScreenInfo(); // record screenInfo
866     auto [__, screenParams] = GetScreenParams(params);
867     if (!screenParams) {
868         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirrorScreen screenParams is null");
869         return;
870     }
871 
872     uniParam->SetScreenInfo(screenParams->GetScreenInfo());
873     // When mirrorSource is paused, mirrorScreen needs to redraw to avoid using an expired cacheImage
874     bool mirroredScreenIsPause =
875         CreateOrGetScreenManager()->GetVirtualScreenStatus(mirroredParams->GetScreenId()) == VIRTUAL_SCREEN_PAUSE;
876     // if specialLayer is visible and no CacheImg
877     if ((mirroredParams->IsSecurityDisplay() != params.IsSecurityDisplay() && specialLayerType == HAS_SPECIAL_LAYER)
878         || !cacheImage || params.GetVirtualScreenMuteStatus() || mirroredScreenIsPause) {
879         MirrorRedrawDFX(true, params.GetScreenId());
880         virtualProcesser->SetDrawVirtualMirrorCopy(false);
881         DrawMirror(params, virtualProcesser, *uniParam);
882     } else {
883         MirrorRedrawDFX(false, params.GetScreenId());
884         virtualProcesser->SetDrawVirtualMirrorCopy(true);
885         DrawMirrorCopy(params, virtualProcesser, *uniParam);
886     }
887     uniParam->SetScreenInfo(screenInfo); // reset screenInfo
888 }
889 
DrawMirrorCopy(RSLogicalDisplayRenderParams & params,std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,RSRenderThreadParams & uniParam)890 void RSLogicalDisplayRenderNodeDrawable::DrawMirrorCopy(RSLogicalDisplayRenderParams& params,
891     std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, RSRenderThreadParams& uniParam)
892 {
893     RS_TRACE_FUNC();
894     auto [curScreenDrawable, curScreenParams] = GetScreenParams(params);
895     if (!curScreenDrawable || !curScreenParams) {
896         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirrorCopy curScreenDrawable or curScreenParams is null");
897         return;
898     }
899     auto [mirroredDrawable, mirroredParams,
900         mirroredScreenDrawable, mirroredScreenParams] = GetMirrorSourceParams(params);
901     if (!mirroredDrawable || !mirroredParams || !mirroredScreenDrawable || !mirroredScreenParams) {
902         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirrorCopy mirror source is null");
903         return;
904     }
905     auto cacheImage = mirroredScreenDrawable ? mirroredScreenDrawable->GetCacheImgForCapture() : nullptr;
906     bool isOpDropped = uniParam.IsOpDropped();
907     uniParam.SetOpDropped(false);
908 #ifdef RS_PROFILER_ENABLED
909     if (auto canvas =
910             RSCaptureRecorder::GetInstance().TryInstantCapture(
911                 static_cast<float>(virtualProcesser->GetCanvas()->GetWidth()),
912                 static_cast<float>(virtualProcesser->GetCanvas()->GetHeight()), SkpCaptureType::IMG_CACHED)) {
913         if (virtualProcesser && virtualProcesser->GetCanvas()) {
914             virtualProcesser->GetCanvas()->AddCanvas(canvas);
915         }
916     }
917 #endif
918     virtualProcesser->CalculateTransform(GetOriginScreenRotation());
919     RSDirtyRectsDfx rsDirtyRectsDfx(*curScreenDrawable);
920     std::shared_ptr<RSSLRScaleFunction> slrManager = enableVisibleRect_ ? nullptr : virtualProcesser->GetSlrManager();
921     if (!uniParam.IsVirtualDirtyEnabled() || (enableVisibleRect_ && curVisibleRect_.GetTop() > 0)) {
922         std::vector<RectI> emptyRects = {};
923         virtualProcesser->SetRoiRegionToCodec(emptyRects);
924     } else {
925         auto dirtyRects = CalculateVirtualDirty(virtualProcesser, *curScreenDrawable, params,
926             slrManager ? slrManager->GetScaleMatrix() : virtualProcesser->GetCanvasMatrix());
927         rsDirtyRectsDfx.SetVirtualDirtyRects(dirtyRects, curScreenParams->GetScreenInfo());
928     }
929 
930     curCanvas_ = virtualProcesser->GetCanvas().get();
931     if (!curCanvas_) {
932         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirrorCopy failed to get canvas.");
933         return;
934     }
935     // Clean up the content of the previous frame
936     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
937     virtualProcesser->CanvasClipRegionForUniscaleMode();
938     RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true));
939 
940     curCanvas_->Save();
941     if (slrManager) {
942         auto scaleNum = slrManager->GetScaleNum();
943         curCanvas_->Scale(scaleNum, scaleNum);
944     }
945     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> hwcNodes;
946     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> hwcTopNodes;
947     RSUniRenderUtil::CollectHardwareEnabledNodesByDisplayNodeId(hwcNodes, hwcTopNodes, mirroredDrawable->GetId());
948     RSUniRenderUtil::AdjustZOrderAndDrawSurfaceNode(hwcNodes, *curCanvas_, *mirroredScreenParams);
949     curCanvas_->Restore();
950 
951     if (cacheImage && RSSystemProperties::GetDrawMirrorCacheImageEnabled()) {
952         RS_TRACE_NAME("DrawMirrorCopy with cacheImage");
953         if (!enableVisibleRect_) {
954             virtualProcesser->ProcessCacheImage(*cacheImage);
955         } else {
956             RSUniRenderUtil::ProcessCacheImageRect(*curCanvas_, *cacheImage, curVisibleRect_,
957                 Drawing::Rect(0, 0, curVisibleRect_.GetWidth(), curVisibleRect_.GetHeight()));
958         }
959     } else {
960         RS_TRACE_NAME("DrawMirrorCopy with displaySurface");
961         virtualProcesser->ProcessScreenSurfaceForRenderThread(*mirroredScreenDrawable);
962     }
963     curCanvas_->Save();
964     if (slrManager) {
965         auto scaleNum = slrManager->GetScaleNum();
966         curCanvas_->Scale(scaleNum, scaleNum);
967     } else if (mirroredScreenParams && mirroredScreenParams->GetScreenInfo().isSamplingOn) {
968         auto scaleNum = mirroredScreenParams->GetScreenInfo().samplingScale;
969         curCanvas_->Scale(scaleNum, scaleNum);
970     }
971     RSUniRenderUtil::AdjustZOrderAndDrawSurfaceNode(hwcTopNodes, *curCanvas_, *mirroredScreenParams);
972     curCanvas_->Restore();
973 #ifdef RS_PROFILER_ENABLED
974     RSCaptureRecorder::GetInstance().EndInstantCapture(SkpCaptureType::IMG_CACHED);
975 #endif
976     RSUniRenderThread::ResetCaptureParam();
977     uniParam.SetOpDropped(isOpDropped);
978     // Restore the initial state of the canvas to avoid state accumulation
979     curCanvas_->RestoreToCount(0);
980     rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
981 }
982 
DrawSecurityMask()983 void RSLogicalDisplayRenderNodeDrawable::DrawSecurityMask()
984 {
985     RS_TRACE_FUNC();
986     RSAutoCanvasRestore acr(curCanvas_, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
987 
988     auto params = static_cast<RSLogicalDisplayRenderParams*>(GetRenderParams().get());
989     auto screenManager = CreateOrGetScreenManager();
990     auto imagePtr = screenManager->GetScreenSecurityMask(params->GetScreenId());
991     // Set canvas to black if imagePtr is null
992     auto image = RSPixelMapUtil::ExtractDrawingImage(imagePtr);
993     if (!image || image->GetWidth() == 0 || image->GetHeight() == 0) {
994         curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
995         RS_LOGE("DisplayDrawable::SetCanvasBlack");
996         curCanvas_->SetDisableFilterCache(false);
997         return;
998     }
999 
1000     auto watermark = RSUniRenderThread::Instance().GetWatermarkImg();
1001     auto screenInfo = screenManager->QueryScreenInfo(params->GetScreenId());
1002     float realImageWidth = static_cast<float>(image->GetWidth());
1003     float realImageHeight = static_cast<float>(image->GetHeight());
1004     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1005     auto srcRect = Drawing::Rect(0, 0, image->GetWidth(), image->GetHeight());
1006     float screenWidth = static_cast<float>(screenInfo.width);
1007     float screenHeight = static_cast<float>(screenInfo.height);
1008     // Area to be drawn in the actual image
1009     auto dstRect = RSUniRenderUtil::GetImageRegions(screenWidth, screenHeight, realImageWidth, realImageHeight);
1010     // Make sure the canvas is oriented accurately.
1011     curCanvas_->ResetMatrix();
1012 
1013     Drawing::Brush brush;
1014     curCanvas_->AttachBrush(brush);
1015     curCanvas_->DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions(),
1016         Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
1017     if (watermark) {
1018         curCanvas_->DrawImageRect(*watermark, srcRect, dstRect, Drawing::SamplingOptions(),
1019             Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
1020     }
1021     curCanvas_->DetachBrush();
1022 
1023     RS_LOGI("DisplayDrawable::DrawSecurityMask");
1024     curCanvas_->SetDisableFilterCache(false);
1025 }
1026 
DrawMirror(RSLogicalDisplayRenderParams & params,std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,RSRenderThreadParams & uniParam)1027 void RSLogicalDisplayRenderNodeDrawable::DrawMirror(RSLogicalDisplayRenderParams& params,
1028     std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, RSRenderThreadParams& uniParam)
1029 {
1030     RS_TRACE_FUNC();
1031 
1032     auto [curScreenDrawable, curScreenParams] = GetScreenParams(params);
1033     if (!curScreenDrawable || !curScreenParams) {
1034         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirror curScreenDrawable or curScreenParams is null");
1035         return;
1036     }
1037     // uniParam/drawable/mirroredParams not null in caller
1038     auto [mirroredDrawable, mirroredParams, _, mirroredScreenParams] = GetMirrorSourceParams(params);
1039     if (!mirroredDrawable || !mirroredParams || !mirroredScreenParams) {
1040         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirror mirroredDrawable or mirroredParams is null");
1041         return;
1042     }
1043     curCanvas_ = virtualProcesser->GetCanvas().get();
1044     if (curCanvas_ == nullptr) {
1045         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirror failed to get canvas.");
1046         return;
1047     }
1048     // for HDR
1049     if (curScreenParams->GetHDRPresent()) {
1050         RS_LOGD("RSLogicalDisplayRenderNodeDrawable::DrawMirror HDRCast isHDREnabledVirtualScreen true");
1051         curCanvas_->SetHDREnabledVirtualScreen(true);
1052         curCanvas_->SetHdrOn(true);
1053     } else {
1054         curCanvas_->SetOnMultipleScreen(true);
1055     }
1056     curCanvas_->SetDisableFilterCache(true);
1057     auto hasSecSurface = mirroredParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_SECURITY);
1058     auto screenManager = CreateOrGetScreenManager();
1059     if (!screenManager) {
1060         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::DrawMirror ScreenManager is nullptr");
1061         return;
1062     }
1063     int32_t virtualSecLayerOption = screenManager->GetVirtualScreenSecLayerOption(params.GetScreenId());
1064     bool isSecurity = (!enableVisibleRect_ && hasSecSurface) ||
1065                       (enableVisibleRect_ && params.HasSecLayerInVisibleRect());
1066     bool securitySkip = (isSecurity && !uniParam.GetSecExemption() && !virtualSecLayerOption) ||
1067         params.GetVirtualScreenMuteStatus();
1068     if (securitySkip) {
1069 #ifdef RS_PROFILER_ENABLED
1070         if (auto canvas =
1071                 RSCaptureRecorder::GetInstance().TryInstantCapture(static_cast<float>(curCanvas_->GetWidth()),
1072                     static_cast<float>(curCanvas_->GetHeight()), SkpCaptureType::ON_CAPTURE)) {
1073             curCanvas_->AddCanvas(canvas);
1074         }
1075 #endif
1076         std::vector<RectI> emptyRects = {};
1077         virtualProcesser->SetRoiRegionToCodec(emptyRects);
1078         DrawSecurityMask();
1079 #ifdef RS_PROFILER_ENABLED
1080         RSCaptureRecorder::GetInstance().EndInstantCapture(SkpCaptureType::ON_CAPTURE);
1081 #endif
1082         virtualDirtyNeedRefresh_ = true;
1083         curCanvas_->RestoreToCount(0);
1084         return;
1085     }
1086     curCanvas_->Save();
1087     virtualProcesser->ScaleMirrorIfNeed(GetOriginScreenRotation(), *curCanvas_);
1088     auto mirroredScreenInfo = mirroredScreenParams->GetScreenInfo();
1089     UpdateSlrScale(mirroredScreenInfo);
1090     ScaleCanvasIfNeeded(mirroredScreenInfo);
1091 
1092     RSDirtyRectsDfx rsDirtyRectsDfx(*curScreenDrawable);
1093     if (uniParam.IsVirtualDirtyEnabled() && !enableVisibleRect_) {
1094         Drawing::Matrix matrix = curCanvas_->GetTotalMatrix();
1095         std::vector<RectI> dirtyRects = CalculateVirtualDirty(virtualProcesser, *curScreenDrawable, params, matrix);
1096         rsDirtyRectsDfx.SetVirtualDirtyRects(dirtyRects, curScreenParams->GetScreenInfo());
1097     } else {
1098         std::vector<RectI> emptyRects = {};
1099         virtualProcesser->SetRoiRegionToCodec(emptyRects);
1100     }
1101     // Clean up the content of the previous frame
1102     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1103     virtualProcesser->CanvasClipRegionForUniscaleMode(visibleClipRectMatrix_, mirroredScreenInfo);
1104     curCanvas_->ConcatMatrix(mirroredParams->GetMatrix());
1105     PrepareOffscreenRender(*mirroredDrawable, false, false);
1106 #ifdef RS_PROFILER_ENABLED
1107     if (auto canvas = RSCaptureRecorder::GetInstance().TryInstantCapture(static_cast<float>(curCanvas_->GetWidth()),
1108         static_cast<float>(curCanvas_->GetHeight()), SkpCaptureType::ON_CAPTURE)) {
1109         curCanvas_->AddCanvas(canvas);
1110     }
1111 #endif
1112     // set mirror screen capture param
1113     // Don't need to scale here since the canvas has been switched from mirror frame to offscreen
1114     // surface in PrepareOffscreenRender() above. The offscreen surface has the same size as
1115     // the main display that's why no need additional scale.
1116     RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true));
1117     RSUniRenderThread::GetCaptureParam().virtualScreenId_ = params.GetScreenId();
1118     RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
1119     bool isOpDropped = uniParam.IsOpDropped();
1120     uniParam.SetOpDropped(false); // disable partial render
1121     mirroredDrawable->OnCapture(*curCanvas_);
1122     uniParam.SetOpDropped(isOpDropped);
1123     RSUniRenderThread::ResetCaptureParam();
1124 #ifdef RS_PROFILER_ENABLED
1125     RSCaptureRecorder::GetInstance().EndInstantCapture(SkpCaptureType::ON_CAPTURE);
1126 #endif
1127     FinishOffscreenRender(Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, MultiScreenParam::GetMipmapMode()),
1128         mirroredScreenInfo.isSamplingOn);
1129     // Restore the initial state of the canvas to avoid state accumulation
1130     curCanvas_->RestoreToCount(0);
1131     rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
1132     RSUniRenderThread::Instance().SetBlackList({});
1133     RSUniRenderThread::Instance().SetTypeBlackList({});
1134     RSUniRenderThread::Instance().SetWhiteList({});
1135     uniParam.SetSecExemption(false);
1136 }
1137 
UpdateSlrScale(ScreenInfo & screenInfo,RSScreenRenderParams * params)1138 void RSLogicalDisplayRenderNodeDrawable::UpdateSlrScale(ScreenInfo& screenInfo, RSScreenRenderParams* params)
1139 {
1140     if (screenInfo.isSamplingOn && RSSystemProperties::GetSLRScaleEnabled()) {
1141         if (scaleManager_== nullptr) {
1142             scaleManager_ = std::make_shared<RSSLRScaleFunction>(
1143                 screenInfo.phyWidth, screenInfo.phyHeight, screenInfo.width, screenInfo.height);
1144         } else {
1145             scaleManager_->CheckOrRefreshScreen(
1146                 screenInfo.phyWidth, screenInfo.phyHeight, screenInfo.width, screenInfo.height);
1147         }
1148         if (params != nullptr) {
1149             scaleManager_->CheckOrRefreshColorSpace(params->GetNewColorSpace());
1150         }
1151         screenInfo.samplingDistance = scaleManager_->GetKernelSize();
1152     } else {
1153         scaleManager_ = nullptr;
1154     }
1155 }
1156 
ScaleCanvasIfNeeded(const ScreenInfo & screenInfo)1157 void RSLogicalDisplayRenderNodeDrawable::ScaleCanvasIfNeeded(const ScreenInfo& screenInfo)
1158 {
1159     if (!screenInfo.isSamplingOn) {
1160         scaleManager_ = nullptr;
1161         return;
1162     }
1163     if (RSSystemProperties::GetSLRScaleEnabled() && scaleManager_ != nullptr) {
1164         scaleManager_->CanvasScale(*curCanvas_);
1165         return;
1166     }
1167     scaleManager_ = nullptr;
1168     if (enableVisibleRect_) {
1169         // save canvas matrix to calculate visible clip rect
1170         visibleClipRectMatrix_ = curCanvas_->GetTotalMatrix();
1171     }
1172     curCanvas_->Translate(screenInfo.samplingTranslateX, screenInfo.samplingTranslateY);
1173     curCanvas_->Scale(screenInfo.samplingScale, screenInfo.samplingScale);
1174 }
1175 
ScaleAndRotateMirrorForWiredScreen(RSLogicalDisplayRenderNodeDrawable & mirroredDrawable)1176 void RSLogicalDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen(
1177     RSLogicalDisplayRenderNodeDrawable& mirroredDrawable)
1178 {
1179     auto mirroredParams = static_cast<RSLogicalDisplayRenderParams*>(mirroredDrawable.GetRenderParams().get());
1180     if (!mirroredParams) {
1181         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen mirroredParams is null");
1182         return;
1183     }
1184     auto [_, mirroredScreenParams] = GetScreenParams(*mirroredParams);
1185     auto params = static_cast<RSLogicalDisplayRenderParams*>(GetRenderParams().get());
1186     auto [__, screenParam] = GetScreenParams(*params);
1187     if (!params || !mirroredScreenParams || !screenParam) {
1188         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen nodeParams is null");
1189         return;
1190     }
1191 
1192     auto mainWidth = enableVisibleRect_ ? curVisibleRect_.GetWidth() : mirroredParams->GetBounds().GetWidth();
1193     auto mainHeight = enableVisibleRect_ ? curVisibleRect_.GetHeight() : mirroredParams->GetBounds().GetHeight();
1194     auto mirrorWidth = screenParam->GetBounds().GetWidth();
1195     auto mirrorHeight = screenParam->GetBounds().GetHeight();
1196 
1197     auto nodeRotation = mirroredParams->GetNodeRotation();
1198     bool needRotate = (nodeRotation == ScreenRotation::ROTATION_90 || nodeRotation == ScreenRotation::ROTATION_270) &&
1199         !enableVisibleRect_;
1200     if (needRotate) {
1201         std::swap(mainWidth, mainHeight);
1202     }
1203 
1204     auto rotation = mirroredParams->GetScreenRotation();
1205     auto screenManager = CreateOrGetScreenManager();
1206     RS_TRACE_NAME_FMT("ScaleAndRotateMirrorForWiredScreen[%" PRIu64 "](%f, %f), [%" PRIu64 "](%f, %f), rotation: %d",
1207         mirroredParams->GetScreenId(), mainWidth, mainHeight, params->GetScreenId(),
1208         mirrorWidth, mirrorHeight, rotation);
1209     if (screenManager) {
1210         auto screenCorrection = screenManager->GetScreenCorrection(mirroredScreenParams->GetScreenId());
1211         if (screenCorrection != ScreenRotation::INVALID_SCREEN_ROTATION &&
1212             screenCorrection != ScreenRotation::ROTATION_0) {
1213             // Recaculate rotation if mirrored screen has additional rotation angle
1214             rotation = static_cast<ScreenRotation>((static_cast<int>(rotation) + SCREEN_ROTATION_NUM
1215                 - static_cast<int>(screenCorrection)) % SCREEN_ROTATION_NUM);
1216         }
1217     }
1218     // Rotate
1219     RotateMirrorCanvas(rotation, mirrorWidth, mirrorHeight);
1220     if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
1221         std::swap(mirrorWidth, mirrorHeight);
1222     }
1223     curCanvas_->Clear(SK_ColorBLACK);
1224     // must after rotate and swap width/height
1225     if (isMirrorSLRCopy_) {
1226         if (scaleManager_ == nullptr) {
1227             scaleManager_ = std::make_unique<RSSLRScaleFunction>(mirrorWidth, mirrorHeight, mainWidth, mainHeight);
1228         } else {
1229             scaleManager_->CheckOrRefreshScreen(mirrorWidth, mirrorHeight, mainWidth, mainHeight);
1230         }
1231         scaleManager_->CheckOrRefreshColorSpace(mirroredScreenParams->GetNewColorSpace());
1232         isMirrorSLRCopy_ = scaleManager_->GetIsSLRCopy();
1233     }
1234     // Scale
1235     if (mainWidth > 0 && mainHeight > 0) {
1236         if (isMirrorSLRCopy_) {
1237             scaleManager_->CanvasScale(*curCanvas_);
1238         } else {
1239             auto scaleNum = std::min(mirrorWidth / mainWidth, mirrorHeight / mainHeight);
1240             curCanvas_->Translate((mirrorWidth - scaleNum * mainWidth) * 0.5f,
1241                 (mirrorHeight - scaleNum * mainHeight) * 0.5f);
1242             curCanvas_->Scale(scaleNum, scaleNum);
1243             curCanvas_->ClipRect(Drawing::Rect(0, 0, mainWidth, mainHeight), Drawing::ClipOp::INTERSECT, false);
1244         }
1245     }
1246 }
1247 
RotateMirrorCanvas(ScreenRotation & rotation,float width,float height)1248 void RSLogicalDisplayRenderNodeDrawable::RotateMirrorCanvas(ScreenRotation& rotation, float width, float height)
1249 {
1250     switch (rotation) {
1251         case ScreenRotation::ROTATION_0:
1252             break;
1253         case ScreenRotation::ROTATION_90:
1254             curCanvas_->Translate(width / 2.0f, height / 2.0f);
1255             curCanvas_->Rotate(90, 0, 0); // 90 degrees
1256             curCanvas_->Translate(-(height / 2.0f), -(width / 2.0f));
1257             break;
1258         case ScreenRotation::ROTATION_180:
1259             // 180 is the rotate angle, calculate half width and half height requires divide by 2
1260             curCanvas_->Rotate(180, width / 2.0f, height / 2.0f);
1261             break;
1262         case ScreenRotation::ROTATION_270:
1263             curCanvas_->Translate(width / 2.0f, height / 2.0f);
1264             curCanvas_->Rotate(270, 0, 0); // 270 degrees
1265             curCanvas_->Translate(-(height / 2.0f), -(width / 2.0f));
1266             break;
1267         default:
1268             break;
1269     }
1270 }
1271 
GetSpecialLayerType(RSLogicalDisplayRenderParams & params,bool isSecLayerInVisibleRect)1272 int32_t RSLogicalDisplayRenderNodeDrawable::GetSpecialLayerType(
1273     RSLogicalDisplayRenderParams& params, bool isSecLayerInVisibleRect)
1274 {
1275     auto& uniRenderThread = RSUniRenderThread::Instance();
1276     const auto& specialLayerManager = params.GetSpecialLayerMgr();
1277     bool hasGeneralSpecialLayer = (specialLayerManager.Find(SpecialLayerType::HAS_SECURITY) &&
1278         isSecLayerInVisibleRect) || specialLayerManager.Find(SpecialLayerType::HAS_SKIP) ||
1279         specialLayerManager.Find(SpecialLayerType::HAS_PROTECTED) || uniRenderThread.IsColorFilterModeOn();
1280     auto [_, screenParams] = GetScreenParams(params);
1281     if (screenParams) {
1282         hasGeneralSpecialLayer |= screenParams->GetHDRPresent();
1283     }
1284     RS_LOGD("RSLogicalDisplayRenderNodeDrawable::SpecialLayer:%{public}" PRIu32 ", CurtainScreen:%{public}d, "
1285         "HDRPresent:%{public}d, ColorFilter:%{public}d", specialLayerManager.Get(),
1286         uniRenderThread.IsCurtainScreenOn(), (screenParams && screenParams->GetHDRPresent()),
1287         uniRenderThread.IsColorFilterModeOn());
1288     if (RSUniRenderThread::GetCaptureParam().isSnapshot_) {
1289         hasGeneralSpecialLayer |= (specialLayerManager.Find(SpecialLayerType::HAS_SNAPSHOT_SKIP) ||
1290             uniRenderThread.IsCurtainScreenOn());
1291     } else {
1292         hasGeneralSpecialLayer |= !uniRenderThread.GetWhiteList().empty() || !currentBlackList_.empty() ||
1293             !currentTypeBlackList_.empty();
1294     }
1295     if (hasGeneralSpecialLayer) {
1296         return HAS_SPECIAL_LAYER;
1297     } else if (params.HasCaptureWindow()) {
1298         return CAPTURE_WINDOW;
1299     } else {
1300         return NO_SPECIAL_LAYER;
1301     }
1302 }
1303 
ClearTransparentBeforeSaveLayer()1304 void RSLogicalDisplayRenderNodeDrawable::ClearTransparentBeforeSaveLayer()
1305 {
1306     if (!canvasBackup_) {
1307         return;
1308     }
1309     RS_TRACE_NAME("ClearTransparentBeforeSaveLayer");
1310     auto& hardwareDrawables =
1311         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
1312     if (UNLIKELY(!renderParams_)) {
1313         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::ClearTransparentBeforeSaveLayer renderParams is null!");
1314         return;
1315     }
1316     auto params = static_cast<RSLogicalDisplayRenderParams*>(renderParams_.get());
1317     for (const auto& [_, displayNodeId, drawable] : hardwareDrawables) {
1318         auto surfaceDrawable = static_cast<RSSurfaceRenderNodeDrawable*>(drawable.get());
1319         if (!surfaceDrawable || displayNodeId != params->GetId()) {
1320             continue;
1321         }
1322         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
1323         if (!surfaceParams || !surfaceParams->GetHardwareEnabled()) {
1324             continue;
1325         }
1326         Drawing::AutoCanvasRestore arc(*canvasBackup_, true);
1327         canvasBackup_->SetMatrix(surfaceParams->GetLayerInfo().matrix);
1328         canvasBackup_->ClipRect(surfaceParams->GetBounds());
1329         canvasBackup_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1330     }
1331 }
1332 
PrepareOffscreenRender(const RSLogicalDisplayRenderNodeDrawable & displayDrawable,bool useFixedSize,bool useCanvasSize)1333 void RSLogicalDisplayRenderNodeDrawable::PrepareOffscreenRender(
1334     const RSLogicalDisplayRenderNodeDrawable& displayDrawable, bool useFixedSize, bool useCanvasSize)
1335 {
1336     const auto& params = static_cast<RSLogicalDisplayRenderParams*>(displayDrawable.GetRenderParams().get());
1337     if (UNLIKELY(!params)) {
1338         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::PrepareOffscreenRender params is null!");
1339         return;
1340     }
1341     canvasBackup_ = nullptr;
1342     useFixedOffscreenSurfaceSize_ = false;
1343 
1344     auto frameSize = params->GetFrameRect();
1345     auto offscreenWidth = static_cast<int32_t>(frameSize.GetWidth());
1346     auto offscreenHeight = static_cast<int32_t>(frameSize.GetHeight());
1347 
1348     RS_TRACE_FUNC();
1349     // use fixed surface size in order to reduce create texture
1350     if (useFixedSize && RotateOffScreenParam::GetRotateOffScreenScreenNodeEnable()
1351         && params->IsRotationChanged()) {
1352         useFixedOffscreenSurfaceSize_ = true;
1353         int32_t maxRenderLength = {};
1354         if (RSSystemProperties::GetCacheOptimizeRotateEnable()) {
1355             maxRenderLength = std::ceil(std::hypot(offscreenWidth, offscreenHeight));
1356             offscreenTranslateX_ = std::round((maxRenderLength - offscreenWidth) * 0.5f);
1357             offscreenTranslateY_ = std::round((maxRenderLength - offscreenHeight) * 0.5f);
1358         } else {
1359             maxRenderLength = static_cast<int32_t>(std::max(offscreenWidth, offscreenHeight));
1360             if (offscreenSurface_ != nullptr
1361                 && maxRenderLength != std::max(offscreenSurface_->Width(), offscreenSurface_->Height())) {
1362                 RS_TRACE_NAME("offscreen surface's max size has changed");
1363                 offscreenSurface_ = nullptr;
1364             }
1365         }
1366         offscreenWidth = maxRenderLength;
1367         offscreenHeight = maxRenderLength;
1368     } else {
1369         offscreenTranslateX_ = 0;
1370         offscreenTranslateY_ = 0;
1371     }
1372     if (params->IsRotationChanged()) {
1373         if (RSUniRenderThread::Instance().GetVmaOptimizeFlag()) {
1374             // render this frame with vma cache on
1375             Drawing::StaticFactory::SetVmaCacheStatus(true);
1376         }
1377     }
1378 
1379     if (offscreenWidth <= 0 || offscreenHeight <= 0) {
1380         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::PrepareOffscreenRender, "
1381             "offscreenWidth or offscreenHeight is invalid");
1382         return;
1383     }
1384     if (curCanvas_->GetSurface() == nullptr) {
1385         curCanvas_->ClipRect(Drawing::Rect(0, 0, offscreenWidth, offscreenHeight), Drawing::ClipOp::INTERSECT, false);
1386         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::PrepareOffscreenRender, current surface is nullptr");
1387         return;
1388     }
1389 
1390     auto [_, screenParams] = GetScreenParams(*params);
1391     if (!screenParams) {
1392         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::%{public}s screenParams is nullptr", __func__);
1393         return;
1394     }
1395     bool createOffscreenSurface = !params->GetNeedOffscreen() || !useFixedOffscreenSurfaceSize_ || !offscreenSurface_ ||
1396         (screenParams->GetHDRPresent() &&
1397         offscreenSurface_->GetImageInfo().GetColorType() != Drawing::ColorType::COLORTYPE_RGBA_F16);
1398     if (createOffscreenSurface) {
1399         RS_TRACE_NAME_FMT("make offscreen surface with fixed size: [%d, %d]", offscreenWidth, offscreenHeight);
1400         bool hdrOrScRGB = screenParams->GetHDRPresent() || EnablescRGBForP3AndUiFirst(screenParams->GetNewColorSpace());
1401         if (hdrOrScRGB) {
1402             RS_LOGD("HDR PrepareHdrDraw");
1403             if (!params->GetNeedOffscreen() && useCanvasSize) {
1404                 offscreenWidth = curCanvas_->GetWidth();
1405                 offscreenHeight = curCanvas_->GetHeight();
1406             }
1407             Drawing::ImageInfo info = { offscreenWidth, offscreenHeight, Drawing::COLORTYPE_RGBA_F16,
1408                 Drawing::ALPHATYPE_PREMUL, Drawing::ColorSpace::CreateSRGB() };
1409             offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(info);
1410         } else {
1411             offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(offscreenWidth, offscreenHeight);
1412         }
1413     }
1414 
1415     if (offscreenSurface_ == nullptr) {
1416         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::PrepareOffscreenRender, offscreenSurface is nullptr");
1417         curCanvas_->ClipRect(Drawing::Rect(0, 0, offscreenWidth, offscreenHeight), Drawing::ClipOp::INTERSECT, false);
1418         return;
1419     }
1420 
1421     offscreenCanvas_ = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
1422 
1423     if (RSSystemProperties::GetCacheOptimizeRotateEnable()) {
1424         offscreenCanvas_->ResetMatrix();
1425         offscreenCanvas_->Translate(offscreenTranslateX_, offscreenTranslateY_);
1426     }
1427 
1428     // copy HDR properties into offscreen canvas
1429     offscreenCanvas_->CopyHDRConfiguration(*curCanvas_);
1430     // copy current canvas properties into offscreen canvas
1431     offscreenCanvas_->CopyConfigurationToOffscreenCanvas(*curCanvas_);
1432 
1433     // backup current canvas and replace with offscreen canvas
1434     canvasBackup_ = std::exchange(curCanvas_, offscreenCanvas_.get());
1435 }
1436 
FinishOffscreenRender(const Drawing::SamplingOptions & sampling,bool isSamplingOn,float hdrBrightnessRatio)1437 void RSLogicalDisplayRenderNodeDrawable::FinishOffscreenRender(
1438     const Drawing::SamplingOptions& sampling, bool isSamplingOn, float hdrBrightnessRatio)
1439 {
1440     RS_TRACE_NAME_FMT("%s: isSamplingOn:%d, hdrBrightnessRatio:%f", __func__, isSamplingOn, hdrBrightnessRatio);
1441     if (canvasBackup_ == nullptr) {
1442         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::FinishOffscreenRender, canvasBackup_ is nullptr");
1443         return;
1444     }
1445     if (offscreenSurface_ == nullptr) {
1446         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::FinishOffscreenRender, offscreenSurface_ is nullptr");
1447         return;
1448     }
1449     std::shared_ptr<Drawing::Image> image = nullptr;
1450 
1451     Drawing::Brush paint;
1452     bool isUseCustomShader = false;
1453 #ifdef USE_VIDEO_PROCESSING_ENGINE
1454     if (canvasBackup_->GetHDREnabledVirtualScreen()) {
1455         isUseCustomShader = RSHdrUtil::HDRCastProcess(image, paint, sampling, offscreenSurface_, canvasBackup_);
1456     }
1457 #endif
1458     if (!isUseCustomShader) {
1459         image = offscreenSurface_->GetImageSnapshot();
1460     }
1461     if (image == nullptr) {
1462         RS_LOGE("RSLogicalDisplayRenderNodeDrawable::FinishOffscreenRender, image is nullptr");
1463         return;
1464     }
1465 
1466     if (ROSEN_LNE(hdrBrightnessRatio, 1.0f)) {
1467         auto shader = MakeBrightnessAdjustmentShader(image, sampling, hdrBrightnessRatio);
1468         if (shader) {
1469             paint.SetShaderEffect(shader);
1470             isUseCustomShader = true;
1471         } else {
1472             FinishHdrDraw(paint, hdrBrightnessRatio);
1473         }
1474     }
1475 
1476     paint.SetAntiAlias(true);
1477     canvasBackup_->AttachBrush(paint);
1478 
1479     if (isSamplingOn) {
1480         if (RSSystemProperties::GetSLRScaleEnabled() && scaleManager_) {
1481             scaleManager_->ProcessOffscreenImage(*canvasBackup_, *image);
1482         } else {
1483             canvasBackup_->DrawImage(*image, 0, 0, sampling);
1484         }
1485     } else if (RSSystemProperties::GetCacheOptimizeRotateEnable()) {
1486         if (isUseCustomShader) {
1487             canvasBackup_->Translate(-offscreenTranslateX_, -offscreenTranslateY_);
1488             canvasBackup_->DrawRect({ 0., 0., image->GetImageInfo().GetWidth(), image->GetImageInfo().GetHeight() });
1489         } else {
1490             canvasBackup_->DrawImage(*image, -offscreenTranslateX_, -offscreenTranslateY_, sampling);
1491         }
1492         canvasBackup_->Translate(offscreenTranslateX_, offscreenTranslateY_);
1493     } else {
1494         if (isUseCustomShader) {
1495             canvasBackup_->DrawRect({ 0., 0., image->GetImageInfo().GetWidth(), image->GetImageInfo().GetHeight() });
1496         } else {
1497             canvasBackup_->DrawImage(*image, 0, 0, sampling);
1498         }
1499     }
1500     canvasBackup_->DetachBrush();
1501 
1502     if (!useFixedOffscreenSurfaceSize_) {
1503         offscreenSurface_ = nullptr;
1504         offscreenCanvas_ = nullptr;
1505     }
1506     curCanvas_ = canvasBackup_;
1507     canvasBackup_ = nullptr;
1508 }
1509 
MakeBrightnessAdjustmentShader(const std::shared_ptr<Drawing::Image> & image,const Drawing::SamplingOptions & sampling,float hdrBrightnessRatio)1510 std::shared_ptr<Drawing::ShaderEffect> RSLogicalDisplayRenderNodeDrawable::MakeBrightnessAdjustmentShader(
1511     const std::shared_ptr<Drawing::Image>& image, const Drawing::SamplingOptions& sampling, float hdrBrightnessRatio)
1512 {
1513     static const std::string shaderString(R"(
1514         uniform shader imageInput;
1515         uniform float ratio;
1516         half4 main(float2 xy) {
1517             half4 c = imageInput.eval(xy);
1518             return half4(c.rgb * ratio, c.a);
1519         }
1520     )");
1521     if (brightnessAdjustmentShaderEffect_ == nullptr) {
1522         brightnessAdjustmentShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(shaderString);
1523         if (brightnessAdjustmentShaderEffect_ == nullptr) {
1524             ROSEN_LOGE("RSLogicalDisplayRenderNodeDrawable::MakeBrightnessAdjustmentShaderBuilder effect is null");
1525             return nullptr;
1526         }
1527     }
1528 
1529     auto builder = std::make_shared<Drawing::RuntimeShaderBuilder>(brightnessAdjustmentShaderEffect_);
1530     if (!builder) {
1531         ROSEN_LOGE("RSLogicalDisplayRenderNodeDrawable::MakeBrightnessAdjustmentShaderBuilder builder is null");
1532         return nullptr;
1533     }
1534     builder->SetChild("imageInput", Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
1535         Drawing::TileMode::CLAMP, sampling, Drawing::Matrix()));
1536     builder->SetUniform("ratio", hdrBrightnessRatio);
1537     return builder->MakeShader(nullptr, false);
1538 }
1539 
MirrorRedrawDFX(bool mirrorRedraw,ScreenId screenId)1540 void RSLogicalDisplayRenderNodeDrawable::MirrorRedrawDFX(bool mirrorRedraw, ScreenId screenId)
1541 {
1542     if (!mirrorRedraw_.has_value() || mirrorRedraw_.value() != mirrorRedraw) {
1543         mirrorRedraw_ = mirrorRedraw;
1544         RS_LOGI("RSLogicalDisplayRenderNodeDrawable::%{public}s mirror screenId: %{public}" PRIu64
1545             " drawing path changed, mirrorRedraw_: %{public}d", __func__, screenId, mirrorRedraw);
1546     }
1547 }
1548 
SetScreenRotationForPointLight(RSLogicalDisplayRenderParams & params)1549 void RSLogicalDisplayRenderNodeDrawable::SetScreenRotationForPointLight(RSLogicalDisplayRenderParams& params)
1550 {
1551     auto screenManager = CreateOrGetScreenManager();
1552     auto [mirroredDrawable, mirroredParams, _, __] = GetMirrorSourceParams(params);
1553     ScreenId screenId = params.GetScreenId();
1554     ScreenRotation screenRotation = params.GetScreenRotation();
1555     if (mirroredParams) {
1556         screenId = mirroredParams->GetScreenId();
1557         screenRotation = mirroredParams->GetScreenRotation();
1558     }
1559     auto screenCorrection = screenManager->GetScreenCorrection(screenId);
1560     screenRotation = static_cast<ScreenRotation>(
1561         (static_cast<int>(screenRotation) + SCREEN_ROTATION_NUM - static_cast<int>(screenCorrection)) %
1562         SCREEN_ROTATION_NUM);
1563     RSPointLightManager::Instance()->SetScreenRotation(screenRotation);
1564 }
1565 
GetScreenParams(RSRenderParams & params)1566 RSLogicalDisplayRenderNodeDrawable::AncestorParams RSLogicalDisplayRenderNodeDrawable::GetScreenParams(
1567     RSRenderParams& params)
1568 {
1569     auto displayParams = static_cast<RSLogicalDisplayRenderParams*>(&params);
1570     if (!displayParams) {
1571         return { nullptr, nullptr };
1572     }
1573     auto screenDrawable = std::static_pointer_cast<RSScreenRenderNodeDrawable>(
1574         displayParams->GetAncestorScreenDrawable().lock());
1575     if (!screenDrawable) {
1576         return { nullptr, nullptr };
1577     }
1578     auto screenParams = static_cast<RSScreenRenderParams*>(screenDrawable->GetRenderParams().get());
1579     return {screenDrawable, screenParams};
1580 }
1581 
GetMirrorSourceParams(RSRenderParams & params)1582 RSLogicalDisplayRenderNodeDrawable::MirrorSourceParams RSLogicalDisplayRenderNodeDrawable::GetMirrorSourceParams(
1583     RSRenderParams& params)
1584 {
1585     auto displayParams = static_cast<RSLogicalDisplayRenderParams*>(&params);
1586     if (!displayParams) {
1587         return { nullptr, nullptr, nullptr, nullptr };
1588     }
1589     auto mirroredDrawable = std::static_pointer_cast<RSLogicalDisplayRenderNodeDrawable>(
1590         displayParams->GetMirrorSourceDrawable().lock());
1591     if (!mirroredDrawable) {
1592         return { nullptr, nullptr, nullptr, nullptr };
1593     }
1594     auto mirroredParams = static_cast<RSLogicalDisplayRenderParams*>(mirroredDrawable->GetRenderParams().get());
1595     if (!mirroredParams) {
1596         return { mirroredDrawable, nullptr, nullptr, nullptr };
1597     }
1598 
1599     return std::tuple_cat(std::tuple{mirroredDrawable, mirroredParams}, GetScreenParams(*mirroredParams));
1600 }
1601 } // namespace OHOS::ROSEN::DrawableV2