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