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*>(¶ms);
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*>(¶ms);
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