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 "luminance/rs_luminance_control.h"
23 #include "rs_trace.h"
24 #include "system/rs_system_parameters.h"
25
26 #include "common/rs_common_def.h"
27 #include "common/rs_optional_trace.h"
28 #include "common/rs_singleton.h"
29 #include "drawable/rs_surface_render_node_drawable.h"
30 #include "hgm_core.h"
31 #include "memory/rs_tag_tracker.h"
32 #include "params/rs_display_render_params.h"
33 #include "params/rs_surface_render_params.h"
34 #include "pipeline/round_corner_display/rs_rcd_render_manager.h"
35 #include "pipeline/round_corner_display/rs_round_corner_display.h"
36 #include "pipeline/round_corner_display/rs_round_corner_display_manager.h"
37 #include "pipeline/rs_base_render_engine.h"
38 #include "pipeline/rs_display_render_node.h"
39 #include "pipeline/rs_main_thread.h"
40 #include "pipeline/rs_paint_filter_canvas.h"
41 #include "pipeline/rs_processor_factory.h"
42 #include "pipeline/rs_surface_handler.h"
43 #include "pipeline/rs_uifirst_manager.h"
44 #include "pipeline/rs_uni_render_listener.h"
45 #include "pipeline/rs_uni_render_thread.h"
46 #include "pipeline/rs_uni_render_util.h"
47 #include "pipeline/rs_uni_render_virtual_processor.h"
48 #include "pipeline/sk_resource_manager.h"
49 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
50 #include "pipeline/pointer_render/rs_pointer_render_manager.h"
51 #endif
52 #include "platform/common/rs_log.h"
53 #include "platform/ohos/rs_jank_stats.h"
54 #include "property/rs_point_light_manager.h"
55 #include "screen_manager/rs_screen_manager.h"
56 #include "static_factory.h"
57 // dfx
58 #include "drawable/dfx/rs_dirty_rects_dfx.h"
59 #include "drawable/dfx/rs_skp_capture_dfx.h"
60 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
61 #include "utils/performanceCaculate.h"
62 namespace OHOS::Rosen::DrawableV2 {
63 namespace {
64 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
65 constexpr const char* DEFAULT_CLEAR_GPU_CACHE = "DefaultClearGpuCache";
66 constexpr int32_t NO_SPECIAL_LAYER = 0;
67 constexpr int32_t HAS_SPECIAL_LAYER = 1;
68 constexpr int32_t CAPTURE_WINDOW = 2; // To be deleted after captureWindow being deleted
69 constexpr int64_t MAX_JITTER_NS = 2000000; // 2ms
70
RectVectorToString(std::vector<RectI> & regionRects)71 std::string RectVectorToString(std::vector<RectI>& regionRects)
72 {
73 std::string results = "";
74 for (auto& rect : regionRects) {
75 results += rect.ToString();
76 }
77 return results;
78 }
79
GetFlippedRegion(std::vector<RectI> & rects,ScreenInfo & screenInfo)80 Drawing::Region GetFlippedRegion(std::vector<RectI>& rects, ScreenInfo& screenInfo)
81 {
82 Drawing::Region region;
83
84 for (const auto& r : rects) {
85 int32_t topAfterFilp = 0;
86 #ifdef RS_ENABLE_VK
87 topAfterFilp = (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
88 RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR)
89 ? r.top_
90 : static_cast<int32_t>(screenInfo.GetRotatedHeight()) - r.GetBottom();
91 #else
92 topAfterFilp = static_cast<int32_t>(screenInfo.GetRotatedHeight()) - r.GetBottom();
93 #endif
94 Drawing::Region tmpRegion;
95 tmpRegion.SetRect(Drawing::RectI(r.left_, topAfterFilp, r.left_ + r.width_, topAfterFilp + r.height_));
96 RS_OPTIONAL_TRACE_NAME_FMT("GetFlippedRegion orig ltrb[%d %d %d %d] to fliped rect ltrb[%d %d %d %d]",
97 r.left_, r.top_, r.left_ + r.width_, r.top_ + r.height_, r.left_, topAfterFilp, r.left_ + r.width_,
98 topAfterFilp + r.height_);
99 region.Op(tmpRegion, Drawing::RegionOp::UNION);
100 }
101 return region;
102 }
103 }
104 class RSOverDrawDfx {
105 public:
RSOverDrawDfx(std::shared_ptr<RSPaintFilterCanvas> curCanvas)106 explicit RSOverDrawDfx(std::shared_ptr<RSPaintFilterCanvas> curCanvas)
107 {
108 bool isEnabled = false;
109 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
110 if (LIKELY(uniParam)) {
111 isEnabled = uniParam->IsOverDrawEnabled();
112 isAceDebugBoundaryEnabled_ = uniParam->IsAceDebugBoundaryEnabled();
113 }
114 enable_ = isEnabled && curCanvas != nullptr;
115 curCanvas_ = curCanvas;
116 StartOverDraw();
117 }
~RSOverDrawDfx()118 ~RSOverDrawDfx()
119 {
120 FinishOverDraw();
121 }
122 private:
StartOverDraw()123 void StartOverDraw()
124 {
125 if (!enable_) {
126 return;
127 }
128
129 auto width = curCanvas_->GetWidth();
130 auto height = curCanvas_->GetHeight();
131 Drawing::ImageInfo info =
132 Drawing::ImageInfo { width, height, Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL };
133 if (!isAceDebugBoundaryEnabled_) {
134 auto gpuContext = curCanvas_->GetGPUContext();
135 if (gpuContext == nullptr) {
136 RS_LOGE("RSOverDrawDfx::StartOverDraw failed: need gpu canvas");
137 return;
138 }
139 overdrawSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext.get(), false, info);
140 } else {
141 overdrawSurface_ = Drawing::Surface::MakeRaster(info);
142 }
143 if (!overdrawSurface_) {
144 RS_LOGE("RSOverDrawDfx::StartOverDraw failed: surface is nullptr");
145 return;
146 }
147 overdrawCanvas_ = std::make_shared<Drawing::OverDrawCanvas>(overdrawSurface_->GetCanvas());
148 curCanvas_->AddCanvas(overdrawCanvas_.get());
149 }
FinishOverDraw()150 void FinishOverDraw()
151 {
152 if (!enable_) {
153 return;
154 }
155 if (!overdrawSurface_) {
156 RS_LOGE("RSOverDrawDfx::FinishOverDraw overdrawSurface is nullptr");
157 return;
158 }
159 auto image = overdrawSurface_->GetImageSnapshot();
160 if (image == nullptr) {
161 RS_LOGE("RSOverDrawDfx::FinishOverDraw image is nullptr");
162 return;
163 }
164 Drawing::Brush brush;
165 auto overdrawColors = RSOverdrawController::GetInstance().GetColorArray();
166 auto colorFilter = Drawing::ColorFilter::CreateOverDrawColorFilter(overdrawColors.data());
167 Drawing::Filter filter;
168 filter.SetColorFilter(colorFilter);
169 brush.SetFilter(filter);
170 curCanvas_->AttachBrush(brush);
171 curCanvas_->DrawImage(*image, 0, 0, Drawing::SamplingOptions());
172 curCanvas_->DetachBrush();
173 }
174
175 bool enable_;
176 bool isAceDebugBoundaryEnabled_ = false;
177 mutable std::shared_ptr<RSPaintFilterCanvas> curCanvas_;
178 std::shared_ptr<Drawing::Surface> overdrawSurface_ = nullptr;
179 std::shared_ptr<Drawing::OverDrawCanvas> overdrawCanvas_ = nullptr;
180 };
181
DoScreenRcdTask(NodeId id,std::shared_ptr<RSProcessor> & processor,std::unique_ptr<RcdInfo> & rcdInfo,const ScreenInfo & screenInfo)182 void DoScreenRcdTask(NodeId id, std::shared_ptr<RSProcessor>& processor, std::unique_ptr<RcdInfo>& rcdInfo,
183 const ScreenInfo& screenInfo)
184 {
185 if (screenInfo.state != ScreenState::HDI_OUTPUT_ENABLE) {
186 RS_LOGD("DoScreenRcdTask is not at HDI_OUPUT mode");
187 return;
188 }
189 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
190 RSSingleton<RoundCornerDisplayManager>::GetInstance().RunHardwareTask(id,
191 [id, &processor, &rcdInfo](void) {
192 auto hardInfo = RSSingleton<RoundCornerDisplayManager>::GetInstance().GetHardwareInfo(id, true);
193 rcdInfo->processInfo = {processor, hardInfo.topLayer, hardInfo.bottomLayer,
194 hardInfo.resourceChanged};
195 RSRcdRenderManager::GetInstance().DoProcessRenderTask(id, rcdInfo->processInfo);
196 });
197 }
198 }
199
200 RSDisplayRenderNodeDrawable::Registrar RSDisplayRenderNodeDrawable::instance_;
201
RSDisplayRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)202 RSDisplayRenderNodeDrawable::RSDisplayRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
203 : RSRenderNodeDrawable(std::move(node)), surfaceHandler_(std::make_shared<RSSurfaceHandler>(nodeId_)),
204 syncDirtyManager_(std::make_shared<RSDirtyRegionManager>(true))
205 {}
206
OnGenerate(std::shared_ptr<const RSRenderNode> node)207 RSRenderNodeDrawable::Ptr RSDisplayRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
208 {
209 return new RSDisplayRenderNodeDrawable(std::move(node));
210 }
211
MergeDirtyHistory(RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,ScreenInfo & screenInfo,RSDirtyRectsDfx & rsDirtyRectsDfx,RSDisplayRenderParams & params)212 static std::vector<RectI> MergeDirtyHistory(RSDisplayRenderNodeDrawable& displayDrawable,
213 int32_t bufferAge, ScreenInfo& screenInfo, RSDirtyRectsDfx& rsDirtyRectsDfx, RSDisplayRenderParams& params)
214 {
215 // renderThreadParams/dirtyManager not null in caller
216 auto dirtyManager = displayDrawable.GetSyncDirtyManager();
217 auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
218 RSUniRenderUtil::MergeDirtyHistoryForDrawable(displayDrawable, bufferAge, params, false);
219 Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleDirtyRegion(
220 curAllSurfaceDrawables, RSUniRenderThread::Instance().GetDrawStatusVec(), false);
221 const auto clipRectThreshold = RSSystemProperties::GetClipRectThreshold();
222 if (clipRectThreshold < 1.f) {
223 Occlusion::Region allDirtyRegion{ Occlusion::Rect{ dirtyManager->GetDirtyRegion() } };
224 allDirtyRegion.OrSelf(dirtyRegion);
225 auto bound = allDirtyRegion.GetBound();
226 if (allDirtyRegion.GetSize() > 1 && !bound.IsEmpty() &&
227 allDirtyRegion.Area() > bound.Area() * clipRectThreshold) {
228 dirtyManager->MergeDirtyRectAfterMergeHistory(bound.ToRectI());
229 RS_OPTIONAL_TRACE_NAME_FMT("dirty expand: %s to %s",
230 allDirtyRegion.GetRegionInfo().c_str(), bound.GetRectInfo().c_str());
231 }
232 }
233 Occlusion::Region globalDirtyRegion{ Occlusion::Rect{ dirtyManager->GetDirtyRegion() } };
234 RSUniRenderUtil::SetAllSurfaceDrawableGlobalDityRegion(curAllSurfaceDrawables,
235 dirtyRegion.Or(globalDirtyRegion));
236
237 // DFX START
238 rsDirtyRectsDfx.SetDirtyRegion(dirtyRegion);
239 // DFX END
240
241 RectI rect = dirtyManager->GetDirtyRegionFlipWithinSurface();
242 auto rects = RSUniRenderUtil::ScreenIntersectDirtyRects(dirtyRegion, screenInfo);
243 if (!rect.IsEmpty()) {
244 rects.emplace_back(rect);
245 RectI screenRectI(0, 0, static_cast<int32_t>(screenInfo.phyWidth), static_cast<int32_t>(screenInfo.phyHeight));
246 GpuDirtyRegionCollection::GetInstance().UpdateGlobalDirtyInfoForDFX(rect.IntersectRect(screenRectI));
247 }
248
249 return rects;
250 }
251
MergeDirtyHistoryInVirtual(RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,ScreenInfo & screenInfo)252 static std::vector<RectI> MergeDirtyHistoryInVirtual(RSDisplayRenderNodeDrawable& displayDrawable,
253 int32_t bufferAge, ScreenInfo& screenInfo)
254 {
255 auto params = static_cast<RSDisplayRenderParams*>(displayDrawable.GetRenderParams().get());
256 auto& renderThreadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
257 if (!renderThreadParams || !params) {
258 return {};
259 }
260 auto& curAllSurfaceDrawables = params->GetAllMainAndLeashSurfaceDrawables();
261 auto dirtyManager = displayDrawable.GetSyncDirtyManager();
262 RSUniRenderUtil::MergeDirtyHistoryInVirtual(displayDrawable, bufferAge);
263 Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleDirtyRegionInVirtual(curAllSurfaceDrawables);
264
265 RectI rect = dirtyManager->GetRectFlipWithinSurface(dirtyManager->GetDirtyRegionInVirtual());
266 auto rects = RSUniRenderUtil::ScreenIntersectDirtyRects(dirtyRegion, screenInfo);
267 if (!rect.IsEmpty()) {
268 rects.emplace_back(rect);
269 }
270
271 return rects;
272 }
273
RequestFrame(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)274 std::unique_ptr<RSRenderFrame> RSDisplayRenderNodeDrawable::RequestFrame(
275 RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
276 {
277 RS_TRACE_NAME("RSDisplayRenderNodeDrawable:RequestFrame");
278 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
279 if (UNLIKELY(!renderEngine)) {
280 RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame RenderEngine is null!");
281 return nullptr;
282 }
283
284 if (!processor->InitForRenderThread(*this, INVALID_SCREEN_ID, renderEngine)) {
285 RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame processor InitForRenderThread failed!");
286 return nullptr;
287 }
288
289 if (!IsSurfaceCreated()) {
290 sptr<IBufferConsumerListener> listener = new RSUniRenderListener(surfaceHandler_);
291 if (!CreateSurface(listener)) {
292 RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame CreateSurface failed");
293 return nullptr;
294 }
295 }
296
297 auto rsSurface = GetRSSurface();
298 if (!rsSurface) {
299 RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame No RSSurface found");
300 return nullptr;
301 }
302 auto bufferConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(params.GetScreenInfo(), true, false,
303 params.GetNewColorSpace(), params.GetNewPixelFormat());
304 RS_LOGD("RequestFrame colorspace is %{public}d, pixelformat is %{public}d", params.GetNewColorSpace(),
305 params.GetNewPixelFormat());
306 auto renderFrame = renderEngine->RequestFrame(std::static_pointer_cast<RSSurfaceOhos>(rsSurface), bufferConfig);
307 if (!renderFrame) {
308 RS_LOGE("RSDisplayRenderNodeDrawable::RequestFrame renderEngine requestFrame is null");
309 return nullptr;
310 }
311
312 return renderFrame;
313 }
314
ClipRegion(Drawing::Canvas & canvas,Drawing::Region & region,bool clear=true)315 static void ClipRegion(Drawing::Canvas& canvas, Drawing::Region& region, bool clear = true)
316 {
317 if (region.IsEmpty()) {
318 // [planning] Remove this after frame buffer can cancel
319 canvas.ClipRect(Drawing::Rect());
320 } else if (region.IsRect()) {
321 canvas.ClipRegion(region);
322 } else {
323 RS_TRACE_NAME("RSDisplayDrawable: clipPath");
324 #ifdef RS_ENABLE_VK
325 if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
326 RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
327 canvas.ClipRegion(region);
328 } else {
329 Drawing::Path dirtyPath;
330 region.GetBoundaryPath(&dirtyPath);
331 canvas.ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
332 }
333 #else
334 Drawing::Path dirtyPath;
335 region.GetBoundaryPath(&dirtyPath);
336 canvas.ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
337 #endif
338 }
339
340 // clear canvas after clip region if need
341 if (clear && !region.IsEmpty()) {
342 canvas.Clear(Drawing::Color::COLOR_TRANSPARENT);
343 }
344 }
345
HardCursorCreateLayer(std::shared_ptr<RSProcessor> processor)346 bool RSDisplayRenderNodeDrawable::HardCursorCreateLayer(std::shared_ptr<RSProcessor> processor)
347 {
348 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
349 if (!uniParam) {
350 RS_LOGE("RSDisplayRenderNodeDrawable::HardCursorCreateLayer uniParam is null");
351 return false;
352 }
353 auto& hardCursorDrawable = uniParam->GetHardCursorDrawables();
354 if (hardCursorDrawable.id != GetId() || !hardCursorDrawable.drawablePtr) {
355 return false;
356 }
357 auto surfaceParams =
358 static_cast<RSSurfaceRenderParams*>(hardCursorDrawable.drawablePtr->GetRenderParams().get());
359 if (!surfaceParams) {
360 RS_LOGE("RSDisplayRenderNodeDrawable::HardCursorCreateLayer surfaceParams is null");
361 return false;
362 }
363 auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable.drawablePtr);
364 if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
365 processor->CreateLayerForRenderThread(*surfaceDrawable);
366 return true;
367 }
368 return false;
369 }
370
CheckDisplayNodeSkip(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)371 bool RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip(
372 RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
373 {
374 if (GetSyncDirtyManager()->IsCurrentFrameDirty() ||
375 (params.GetMainAndLeashSurfaceDirty() || RSUifirstManager::Instance().HasDoneNode()) ||
376 RSMainThread::Instance()->GetDirtyFlag()) {
377 return false;
378 }
379
380 RS_LOGD("DisplayNode skip");
381 RS_TRACE_NAME("DisplayNode skip");
382 GpuDirtyRegionCollection::GetInstance().AddSkipProcessFramesNumberForDFX(RSBaseRenderUtil::GetLastSendingPid());
383 #ifdef OHOS_PLATFORM
384 RSUniRenderThread::Instance().SetSkipJankAnimatorFrame(true);
385 #endif
386 auto pendingDrawables = RSUifirstManager::Instance().GetPendingPostDrawables();
387 auto isHardCursor = HardCursorCreateLayer(processor);
388 if (!RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetForceCommitLayer() &&
389 pendingDrawables.size() == 0 && !isHardCursor) {
390 RS_TRACE_NAME("DisplayNodeSkip skip commit");
391 return true;
392 }
393
394 if (!processor->InitForRenderThread(*this, INVALID_SCREEN_ID, RSUniRenderThread::Instance().GetRenderEngine())) {
395 RS_LOGE("RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip processor init failed");
396 return false;
397 }
398
399 auto& hardwareDrawables =
400 RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
401 for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
402 if (UNLIKELY(!drawable || !drawable->GetRenderParams()) || displayNodeId != params.GetId()) {
403 continue;
404 }
405 if (drawable->GetRenderParams()->GetHardwareEnabled()) {
406 auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
407 processor->CreateLayerForRenderThread(*surfaceDrawable);
408 }
409 }
410 if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
411 RS_LOGW("RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip: hardwareThread task has too many to Execute");
412 }
413 processor->ProcessDisplaySurfaceForRenderThread(*this);
414
415 RSUifirstManager::Instance().CreateUIFirstLayer(processor);
416
417 // commit RCD layers
418 auto rcdInfo = std::make_unique<RcdInfo>();
419 const auto& screenInfo = params.GetScreenInfo();
420 DoScreenRcdTask(params.GetId(), processor, rcdInfo, screenInfo);
421 processor->PostProcess();
422 return true;
423 }
424
PostClearMemoryTask() const425 void RSDisplayRenderNodeDrawable::PostClearMemoryTask() const
426 {
427 auto& unirenderThread = RSUniRenderThread::Instance();
428 if (unirenderThread.IsDefaultClearMemoryFinished()) {
429 unirenderThread.DefaultClearMemoryCache(); //default clean with no rendering in 5s
430 unirenderThread.SetDefaultClearMemoryFinished(false);
431 }
432 }
433
SetDisplayNodeSkipFlag(RSRenderThreadParams & uniParam,bool flag)434 void RSDisplayRenderNodeDrawable::SetDisplayNodeSkipFlag(RSRenderThreadParams& uniParam, bool flag)
435 {
436 isDisplayNodeSkipStatusChanged_ = (isDisplayNodeSkip_ != flag);
437 isDisplayNodeSkip_ = flag;
438 uniParam.SetForceMirrorScreenDirty(isDisplayNodeSkipStatusChanged_ && isDisplayNodeSkip_);
439 }
440
CheckFilterCacheFullyCovered(RSSurfaceRenderParams & surfaceParams,RectI screenRect)441 void RSDisplayRenderNodeDrawable::CheckFilterCacheFullyCovered(RSSurfaceRenderParams& surfaceParams, RectI screenRect)
442 {
443 surfaceParams.SetFilterCacheFullyCovered(false);
444 bool dirtyBelowContainsFilterNode = false;
445 for (auto& filterNodeId : surfaceParams.GetVisibleFilterChild()) {
446 auto drawableAdapter = DrawableV2::RSRenderNodeDrawableAdapter::GetDrawableById(filterNodeId);
447 if (drawableAdapter == nullptr) {
448 continue;
449 }
450 auto filterNodeDrawable = std::static_pointer_cast<DrawableV2::RSRenderNodeDrawable>(drawableAdapter);
451 if (filterNodeDrawable == nullptr) {
452 RS_LOGD("CheckFilterCacheFullyCovered filter node drawable is nullptr, Name[%{public}s],"
453 "NodeId[%" PRIu64 "]", surfaceParams.GetName().c_str(), filterNodeId);
454 continue;
455 }
456 auto filterParams = static_cast<RSRenderParams*>(filterNodeDrawable->GetRenderParams().get());
457 if (filterParams == nullptr || !filterParams->HasBlurFilter()) {
458 RS_LOGD("CheckFilterCacheFullyCovered filter params is nullptr or has no blur, Name[%{public}s],"
459 "NodeId[%" PRIu64 "]", surfaceParams.GetName().c_str(), filterNodeId);
460 continue;
461 }
462 // Filter cache occlusion need satisfy:
463 // 1.The filter node global alpha equals 1;
464 // 2.There is no invalid filter cache node below, which should take snapshot;
465 // 3.The filter node has no global corner;
466 // 4.The surfaceNode is transparent, the opaque surfaceNode can occlude without filter cache;
467 // 5.The node type is not EFFECT_NODE;
468 if (ROSEN_EQ(filterParams->GetGlobalAlpha(), 1.f) && !dirtyBelowContainsFilterNode &&
469 !filterParams->HasGlobalCorner() && surfaceParams.IsTransparent() &&
470 filterParams->GetType() != RSRenderNodeType::EFFECT_NODE) {
471 surfaceParams.CheckValidFilterCacheFullyCoverTarget(
472 filterNodeDrawable->IsFilterCacheValidForOcclusion(),
473 filterNodeDrawable->GetFilterCachedRegion(), screenRect);
474 }
475 RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterCacheFullyCovered NodeId[%" PRIu64 "], globalAlpha: %f,"
476 "hasInvalidFilterCacheBefore: %d, hasNoCorner: %d, isTransparent: %d, isNodeTypeCorrect: %d,"
477 "isCacheValid: %d, cacheRect: %s", filterNodeId, filterParams->GetGlobalAlpha(),
478 !dirtyBelowContainsFilterNode, !filterParams->HasGlobalCorner(), surfaceParams.IsTransparent(),
479 filterParams->GetType() != RSRenderNodeType::EFFECT_NODE,
480 filterNodeDrawable->IsFilterCacheValidForOcclusion(),
481 filterNodeDrawable->GetFilterCachedRegion().ToString().c_str());
482 if (filterParams->GetEffectNodeShouldPaint() && !filterNodeDrawable->IsFilterCacheValidForOcclusion()) {
483 dirtyBelowContainsFilterNode = true;
484 }
485 }
486 }
487
CheckAndUpdateFilterCacheOcclusion(RSDisplayRenderParams & params,ScreenInfo & screenInfo)488 void RSDisplayRenderNodeDrawable::CheckAndUpdateFilterCacheOcclusion(
489 RSDisplayRenderParams& params, ScreenInfo& screenInfo)
490 {
491 if (!RSSystemParameters::GetFilterCacheOcculusionEnabled()) {
492 return;
493 }
494 bool isScreenOccluded = false;
495 RectI screenRect = {0, 0, screenInfo.width, screenInfo.height};
496 // top-down traversal all mainsurface
497 // if upper surface reuse filter cache which fully cover whole screen
498 // mark lower layers for process skip
499 auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
500 for (auto it = curAllSurfaceDrawables.begin(); it != curAllSurfaceDrawables.end(); ++it) {
501 if (*it == nullptr || (*it)->GetNodeType() != RSRenderNodeType::SURFACE_NODE) {
502 RS_LOGD("CheckAndUpdateFilterCacheOcclusion adapter is nullptr or error type");
503 continue;
504 }
505 auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
506 if (surfaceNodeDrawable == nullptr) {
507 RS_LOGD("CheckAndUpdateFilterCacheOcclusion surfaceNodeDrawable is nullptr");
508 continue;
509 }
510 auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
511 if (surfaceParams == nullptr) {
512 RS_LOGD("CheckAndUpdateFilterCacheOcclusion surface params is nullptr");
513 continue;
514 }
515
516 CheckFilterCacheFullyCovered(*surfaceParams, screenRect);
517
518 if (surfaceParams->IsMainWindowType()) {
519 // reset occluded status for all mainwindow
520 surfaceParams->SetOccludedByFilterCache(isScreenOccluded);
521 }
522 isScreenOccluded = isScreenOccluded || surfaceParams->GetFilterCacheFullyCovered();
523 }
524 }
525
OnDraw(Drawing::Canvas & canvas)526 void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
527 {
528 SetDrawSkipType(DrawSkipType::NONE);
529 // canvas will generate in every request frame
530 (void)canvas;
531
532 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
533 if (UNLIKELY(!renderParams_ || !uniParam)) {
534 SetDrawSkipType(DrawSkipType::RENDER_PARAMS_OR_UNI_PARAMS_NULL);
535 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw renderParams/uniParam is null!");
536 return;
537 }
538 auto params = static_cast<RSDisplayRenderParams*>(renderParams_.get());
539
540 // [Attention] do not return before layer created set false, otherwise will result in buffer not released
541 auto& hardwareDrawables = uniParam->GetHardwareEnabledTypeDrawables();
542 for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
543 if (UNLIKELY(!drawable || !drawable->GetRenderParams()) ||
544 displayNodeId != params->GetId()) {
545 continue;
546 }
547 drawable->GetRenderParams()->SetLayerCreated(false);
548 }
549 auto& hardCursorDrawable = uniParam->GetHardCursorDrawables();
550 if (hardCursorDrawable.id == GetId() && hardCursorDrawable.drawablePtr &&
551 hardCursorDrawable.drawablePtr->GetRenderParams()) {
552 hardCursorDrawable.drawablePtr->GetRenderParams()->SetLayerCreated(false);
553 }
554 // if screen power off, skip on draw, needs to draw one more frame.
555 isRenderSkipIfScreenOff_ = RSUniRenderUtil::CheckRenderSkipIfScreenOff(true, params->GetScreenId());
556 if (isRenderSkipIfScreenOff_) {
557 SetDrawSkipType(DrawSkipType::RENDER_SKIP_IF_SCREEN_OFF);
558 return;
559 }
560
561 PostClearMemoryTask();
562 // dfx
563 RSRenderNodeDrawable::InitDfxForCacheInfo();
564 uniParam->SetIsMirrorScreen(params->IsMirrorScreen());
565 uniParam->SetCompositeType(params->GetCompositeType());
566 // check rotation for point light
567 constexpr int ROTATION_NUM = 4;
568 auto screenRotation = GetRenderParams()->GetScreenRotation();
569 ScreenId paramScreenId = params->GetScreenId();
570 if (RSSystemProperties::IsFoldScreenFlag() && paramScreenId == 0) {
571 screenRotation = static_cast<ScreenRotation>((static_cast<int>(screenRotation) + 1) % ROTATION_NUM);
572 }
573 RSPointLightManager::Instance()->SetScreenRotation(screenRotation);
574 const RectI& dirtyRegion = GetSyncDirtyManager()->GetCurrentFrameDirtyRegion();
575 RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable[%" PRIu64 "](%d, %d, %d, %d), zoomed(%d)", paramScreenId,
576 dirtyRegion.left_, dirtyRegion.top_, dirtyRegion.width_, dirtyRegion.height_, params->GetZoomed());
577 RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw node: %{public}" PRIu64 "", GetId());
578 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
579 if (!screenManager) {
580 SetDrawSkipType(DrawSkipType::SCREEN_MANAGER_NULL);
581 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw ScreenManager is nullptr");
582 return;
583 }
584 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(paramScreenId);
585 ScreenId activeScreenId = HgmCore::Instance().GetActiveScreenId();
586 uint32_t activeScreenRefreshRate = HgmCore::Instance().GetScreenCurrentRefreshRate(activeScreenId);
587
588 // when set expectedRefreshRate, the activeScreenRefreshRate maybe change from 60 to 120
589 // so that need change whether equal vsync period and whether use virtual dirty
590 if (curScreenInfo.skipFrameStrategy == SKIP_FRAME_BY_REFRESH_RATE) {
591 bool isEqualVsyncPeriod = (activeScreenRefreshRate == curScreenInfo.expectedRefreshRate);
592 if (isEqualVsyncPeriod ^ curScreenInfo.isEqualVsyncPeriod) {
593 curScreenInfo.isEqualVsyncPeriod = isEqualVsyncPeriod;
594 screenManager->SetEqualVsyncPeriod(paramScreenId, isEqualVsyncPeriod);
595 }
596 }
597 if (SkipFrame(activeScreenRefreshRate, curScreenInfo)) {
598 SetDrawSkipType(DrawSkipType::SKIP_FRAME);
599 RS_TRACE_NAME_FMT("SkipFrame, screenId:%lu, strategy:%d, interval:%u, refreshrate:%u", paramScreenId,
600 curScreenInfo.skipFrameStrategy, curScreenInfo.skipFrameInterval, curScreenInfo.expectedRefreshRate);
601 screenManager->ForceRefreshOneFrameIfNoRNV();
602 return;
603 }
604 if (!curScreenInfo.isEqualVsyncPeriod) {
605 virtualDirtyRefresh_ = true;
606 }
607
608 auto screenInfo = params->GetScreenInfo();
609 auto processor = RSProcessorFactory::CreateProcessor(params->GetCompositeType());
610 if (!processor) {
611 SetDrawSkipType(DrawSkipType::CREATE_PROCESSOR_FAIL);
612 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw RSProcessor is null!");
613 return;
614 }
615
616 auto mirrorDrawable = params->GetMirrorSourceDrawable().lock();
617 auto mirrorParams = mirrorDrawable ? mirrorDrawable->GetRenderParams().get() : nullptr;
618 if (mirrorParams || params->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE) {
619 if (!processor->InitForRenderThread(*this,
620 mirrorParams ? mirrorParams->GetScreenId() : INVALID_SCREEN_ID,
621 RSUniRenderThread::Instance().GetRenderEngine())) {
622 SetDrawSkipType(DrawSkipType::RENDER_ENGINE_NULL);
623 syncDirtyManager_->ResetDirtyAsSurfaceSize();
624 syncDirtyManager_->UpdateDirty(false);
625 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw processor init failed!");
626 return;
627 }
628 if (mirrorParams) {
629 if (params->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
630 SetDrawSkipType(DrawSkipType::WIRED_SCREEN_PROJECTION);
631 RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw wired screen projection.");
632 WiredScreenProjection(*params, processor);
633 return;
634 }
635 castScreenEnableSkipWindow_ = screenManager->GetCastScreenEnableSkipWindow(paramScreenId);
636 if (castScreenEnableSkipWindow_) {
637 RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw, Enable CastScreen SkipWindow.");
638 screenManager->GetCastScreenBlackList(currentBlackList_);
639 } else {
640 RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw, Enable RecordScreen SkipWindow.");
641 currentBlackList_ = screenManager->GetVirtualScreenBlackList(paramScreenId);
642 }
643 RSUniRenderThread::Instance().SetBlackList(currentBlackList_);
644 RSUniRenderThread::Instance().SetWhiteList(screenInfo.whiteList);
645 curSecExemption_ = params->GetSecurityExemption();
646 uniParam->SetSecExemption(curSecExemption_);
647 RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw Mirror screen.");
648 DrawMirrorScreen(*params, processor);
649 lastBlackList_ = currentBlackList_;
650 lastSecExemption_ = curSecExemption_;
651 } else {
652 bool isOpDropped = uniParam->IsOpDropped();
653 uniParam->SetOpDropped(false);
654 auto expandProcessor = RSProcessor::ReinterpretCast<RSUniRenderVirtualProcessor>(processor);
655 if (!expandProcessor) {
656 SetDrawSkipType(DrawSkipType::EXPAND_PROCESSOR_NULL);
657 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw expandProcessor is null!");
658 return;
659 }
660 RSDirtyRectsDfx rsDirtyRectsDfx(*this);
661 std::vector<RectI> damageRegionRects;
662 // disable expand screen dirty when isEqualVsyncPeriod is false, because the dirty history is incorrect
663 if (uniParam->IsExpandScreenDirtyEnabled() && uniParam->IsVirtualDirtyEnabled() &&
664 curScreenInfo.isEqualVsyncPeriod) {
665 int32_t bufferAge = expandProcessor->GetBufferAge();
666 damageRegionRects = MergeDirtyHistory(*this, bufferAge, screenInfo, rsDirtyRectsDfx, *params);
667 uniParam->Reset();
668 if (!uniParam->IsVirtualDirtyDfxEnabled()) {
669 expandProcessor->SetDirtyInfo(damageRegionRects);
670 }
671 } else {
672 std::vector<RectI> emptyRects = {};
673 expandProcessor->SetRoiRegionToCodec(emptyRects);
674 }
675 rsDirtyRectsDfx.SetVirtualDirtyRects(damageRegionRects, screenInfo);
676 DrawExpandScreen(*expandProcessor);
677 if (curCanvas_) {
678 rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
679 }
680 uniParam->SetOpDropped(isOpDropped);
681 }
682 DrawCurtainScreen();
683 processor->PostProcess();
684 SetDrawSkipType(DrawSkipType::MIRROR_DRAWABLE_SKIP);
685 return;
686 }
687
688 bool isHdrOn = params->GetHDRPresent();
689 ScreenId screenId = curScreenInfo.id;
690 // 0 means defalut hdrBrightnessRatio
691 float hdrBrightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
692 if (!isHdrOn) {
693 params->SetBrightnessRatio(hdrBrightnessRatio);
694 hdrBrightnessRatio = 1.0f;
695 }
696 RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw HDR content in UniRender:%{public}d, BrightnessRatio:%{public}f",
697 isHdrOn, hdrBrightnessRatio);
698
699 if (uniParam->IsOpDropped() && CheckDisplayNodeSkip(*params, processor)) {
700 RSMainThread::Instance()->SetFrameIsRender(false);
701 SetDrawSkipType(DrawSkipType::DISPLAY_NODE_SKIP);
702 SetDisplayNodeSkipFlag(*uniParam, true);
703 return;
704 }
705 SetDisplayNodeSkipFlag(*uniParam, false);
706 RSMainThread::Instance()->SetFrameIsRender(true);
707
708 CheckAndUpdateFilterCacheOcclusion(*params, curScreenInfo);
709 RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw HDR isHdrOn: %{public}d", isHdrOn);
710 if (isHdrOn) {
711 params->SetNewPixelFormat(GRAPHIC_PIXEL_FMT_RGBA_1010102);
712 }
713 RSUniRenderThread::Instance().WaitUntilDisplayNodeBufferReleased(*this);
714 // displayNodeSp to get rsSurface witch only used in renderThread
715 auto renderFrame = RequestFrame(*params, processor);
716 if (!renderFrame) {
717 SetDrawSkipType(DrawSkipType::REQUEST_FRAME_FAIL);
718 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw failed to request frame");
719 return;
720 }
721
722 RSDirtyRectsDfx rsDirtyRectsDfx(*this);
723 std::vector<RectI> damageRegionrects;
724 Drawing::Region clipRegion;
725 if (uniParam->IsPartialRenderEnabled()) {
726 damageRegionrects = MergeDirtyHistory(*this, renderFrame->GetBufferAge(), screenInfo, rsDirtyRectsDfx, *params);
727 uniParam->Reset();
728 clipRegion = GetFlippedRegion(damageRegionrects, screenInfo);
729 RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
730 damageRegionrects.size(), RectVectorToString(damageRegionrects).c_str());
731 if (!uniParam->IsRegionDebugEnabled()) {
732 renderFrame->SetDamageRegion(damageRegionrects);
733 }
734 }
735
736 auto drSurface = renderFrame->GetFrame()->GetSurface();
737 if (!drSurface) {
738 SetDrawSkipType(DrawSkipType::SURFACE_NULL);
739 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw DrawingSurface is null");
740 return;
741 }
742
743 curCanvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
744 if (!curCanvas_) {
745 SetDrawSkipType(DrawSkipType::CANVAS_NULL);
746 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw failed to create canvas");
747 return;
748 }
749
750 curCanvas_->SetTargetColorGamut(params->GetNewColorSpace());
751 curCanvas_->SetScreenId(screenId);
752 curCanvas_->SetDisableFilterCache(params->GetZoomed());
753
754 #ifdef DDGR_ENABLE_FEATURE_OPINC
755 if (autoCacheEnable_) {
756 screenRectInfo_ = {0, 0, screenInfo.width, screenInfo.height};
757 }
758 #endif
759
760 // canvas draw
761 {
762 RSOverDrawDfx rsOverDrawDfx(curCanvas_);
763 {
764 RSSkpCaptureDfx capture(curCanvas_);
765 Drawing::AutoCanvasRestore acr(*curCanvas_, true);
766
767 bool isOpDropped = uniParam->IsOpDropped();
768 bool needOffscreen = params->GetNeedOffscreen() || isHdrOn;
769 if (needOffscreen) {
770 uniParam->SetOpDropped(false);
771 // draw black background in rotation for camera
772 curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
773 PrepareOffscreenRender(*this, true);
774 }
775
776 if (uniParam->IsOpDropped()) {
777 uniParam->SetClipRegion(clipRegion);
778 ClipRegion(*curCanvas_, clipRegion);
779 } else {
780 curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
781 }
782
783 if (!params->GetNeedOffscreen()) {
784 curCanvas_->ConcatMatrix(params->GetMatrix());
785 }
786
787 curCanvas_->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
788 RSRenderNodeDrawable::OnDraw(*curCanvas_);
789 DrawCurtainScreen();
790 if (needOffscreen) {
791 if (canvasBackup_ != nullptr) {
792 Drawing::AutoCanvasRestore acr(*canvasBackup_, true);
793 if (params->GetNeedOffscreen()) {
794 canvasBackup_->ConcatMatrix(params->GetMatrix());
795 }
796 ClearTransparentBeforeSaveLayer();
797 FinishOffscreenRender(Drawing::SamplingOptions(Drawing::FilterMode::NEAREST,
798 Drawing::MipmapMode::NONE), hdrBrightnessRatio);
799 uniParam->SetOpDropped(isOpDropped);
800 } else {
801 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw canvasBackup_ is nullptr");
802 }
803 }
804 // watermark and color filter should be applied after offscreen render.
805 DrawWatermarkIfNeed(*params, *curCanvas_);
806 SwitchColorFilter(*curCanvas_, hdrBrightnessRatio);
807 }
808 rsDirtyRectsDfx.OnDraw(*curCanvas_);
809 if ((RSSystemProperties::IsFoldScreenFlag() || RSSystemProperties::IsTabletType())
810 && !params->IsRotationChanged()) {
811 offscreenSurface_ = nullptr;
812 }
813
814 specialLayerType_ = GetSpecialLayerType(*params);
815 if (RSSystemProperties::GetDrawMirrorCacheImageEnabled() && uniParam->HasMirrorDisplay() &&
816 curCanvas_->GetSurface() != nullptr && specialLayerType_ != HAS_SPECIAL_LAYER) {
817 cacheImgForCapture_ = curCanvas_->GetSurface()->GetImageSnapshot();
818 } else {
819 SetCacheImgForCapture(nullptr);
820 }
821 }
822 RSMainThread::Instance()->SetDirtyFlag(false);
823
824 if (Drawing::PerformanceCaculate::GetDrawingFlushPrint()) {
825 RS_LOGI("Drawing Performance Flush start %{public}lld", Drawing::PerformanceCaculate::GetUpTime(false));
826 }
827 RS_TRACE_BEGIN("RSDisplayRenderNodeDrawable Flush");
828 renderFrame->Flush();
829 RS_TRACE_END();
830 if (Drawing::PerformanceCaculate::GetDrawingFlushPrint()) {
831 RS_LOGI("Drawing Performance Flush end %{public}lld", Drawing::PerformanceCaculate::GetUpTime(false));
832 Drawing::PerformanceCaculate::ResetCaculateTimeCount();
833 }
834
835 // process round corner display
836 auto rcdInfo = std::make_unique<RcdInfo>();
837 DoScreenRcdTask(params->GetId(), processor, rcdInfo, screenInfo);
838
839 if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
840 RS_LOGW("RSDisplayRenderNodeDrawable::ondraw: hardwareThread task has too many to Execute");
841 }
842
843 RS_TRACE_BEGIN("RSDisplayRenderNodeDrawable CommitLayer");
844 for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
845 if (UNLIKELY(!drawable || !drawable->GetRenderParams())) {
846 continue;
847 }
848 auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
849 if (!surfaceDrawable || displayNodeId != params->GetId()) {
850 continue;
851 }
852 if (drawable->GetRenderParams()->GetHardwareEnabled()) {
853 processor->CreateLayerForRenderThread(*surfaceDrawable);
854 }
855 }
856 HardCursorCreateLayer(processor);
857 SetDirtyRects(damageRegionrects);
858 processor->ProcessDisplaySurfaceForRenderThread(*this);
859 RSUifirstManager::Instance().CreateUIFirstLayer(processor);
860 processor->PostProcess();
861 RS_TRACE_END();
862
863 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
864 if (!mirrorDrawable) {
865 RSPointerRenderManager::GetInstance().ProcessColorPicker(processor, curCanvas_->GetGPUContext());
866 RSPointerRenderManager::GetInstance().SetCacheImgForPointer(nullptr);
867 }
868 #endif
869 }
870
DrawMirrorScreen(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)871 void RSDisplayRenderNodeDrawable::DrawMirrorScreen(
872 RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
873 {
874 // uniParam/drawable/mirroredParams/renderParams_ not null in caller
875 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
876 auto mirroredDrawable =
877 std::static_pointer_cast<RSDisplayRenderNodeDrawable>(params.GetMirrorSourceDrawable().lock());
878 auto& mirroredParams = mirroredDrawable->GetRenderParams();
879
880 specialLayerType_ = GetSpecialLayerType(static_cast<RSDisplayRenderParams&>(*mirroredParams));
881 auto virtualProcesser = RSProcessor::ReinterpretCast<RSUniRenderVirtualProcessor>(processor);
882 if (!virtualProcesser) {
883 RS_LOGE("RSDisplayRenderNodeDrawable::DrawMirrorScreen virtualProcesser is null");
884 return;
885 }
886
887 auto hardwareDrawables = uniParam->GetHardwareEnabledTypeDrawables();
888 //if specialLayer is visible and no CacheImg
889 if ((mirroredParams->GetSecurityDisplay() != params.GetSecurityDisplay() &&
890 specialLayerType_ == HAS_SPECIAL_LAYER) || !mirroredDrawable->GetCacheImgForCapture()) {
891 DrawMirror(params, virtualProcesser,
892 &RSDisplayRenderNodeDrawable::OnCapture, *uniParam);
893 } else {
894 DrawMirrorCopy(*mirroredDrawable, params, virtualProcesser, *uniParam);
895 }
896 }
897
UpdateDisplayDirtyManager(int32_t bufferage,bool useAlignedDirtyRegion)898 void RSDisplayRenderNodeDrawable::UpdateDisplayDirtyManager(int32_t bufferage, bool useAlignedDirtyRegion)
899 {
900 // syncDirtyManager_ not null in caller
901 syncDirtyManager_->SetBufferAge(bufferage);
902 syncDirtyManager_->UpdateDirty(useAlignedDirtyRegion);
903 }
904
GetSpecialLayerType(RSDisplayRenderParams & params)905 int32_t RSDisplayRenderNodeDrawable::GetSpecialLayerType(RSDisplayRenderParams& params)
906 {
907 auto& uniRenderThread = RSUniRenderThread::Instance();
908 auto hasGeneralSpecialLayer = params.HasSecurityLayer() || params.HasSkipLayer() ||
909 params.HasProtectedLayer() || params.GetHDRPresent() || uniRenderThread.IsColorFilterModeOn();
910 if (RSUniRenderThread::GetCaptureParam().isSnapshot_) {
911 hasGeneralSpecialLayer |= uniRenderThread.IsCurtainScreenOn();
912 return hasGeneralSpecialLayer ? HAS_SPECIAL_LAYER :
913 (params.HasCaptureWindow() ? CAPTURE_WINDOW : NO_SPECIAL_LAYER);
914 }
915 if (hasGeneralSpecialLayer || (!uniRenderThread.GetWhiteList().empty()) || !currentBlackList_.empty()) {
916 return HAS_SPECIAL_LAYER;
917 } else if (params.HasCaptureWindow()) {
918 return CAPTURE_WINDOW;
919 }
920 return NO_SPECIAL_LAYER;
921 }
922
CalculateVirtualDirty(std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,RSDisplayRenderParams & params,Drawing::Matrix canvasMatrix)923 std::vector<RectI> RSDisplayRenderNodeDrawable::CalculateVirtualDirty(
924 std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, RSDisplayRenderParams& params,
925 Drawing::Matrix canvasMatrix)
926 {
927 // uniParam/drawable/mirroredParams not null in caller
928 std::vector<RectI> mappedDamageRegionRects;
929 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
930 auto drawable = params.GetMirrorSourceDrawable().lock();
931 auto mirroredDrawable = std::static_pointer_cast<RSDisplayRenderNodeDrawable>(drawable);
932 auto mirrorParams = static_cast<RSDisplayRenderParams*>(mirroredDrawable->GetRenderParams().get());
933 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
934 if (!screenManager) {
935 RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirty ScreenManager is nullptr");
936 virtualProcesser->SetRoiRegionToCodec(mappedDamageRegionRects);
937 return mappedDamageRegionRects;
938 }
939 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(params.GetScreenId());
940 if (!curScreenInfo.isEqualVsyncPeriod) {
941 RS_LOGD("RSDisplayRenderNodeDrawable::CalculateVirtualDirty frame rate is irregular");
942 virtualProcesser->SetRoiRegionToCodec(mappedDamageRegionRects);
943 return mappedDamageRegionRects;
944 }
945 ScreenInfo mainScreenInfo = screenManager->QueryScreenInfo(mirrorParams->GetScreenId());
946 int32_t bufferAge = virtualProcesser->GetBufferAge();
947 std::vector<RectI> damageRegionRects = MergeDirtyHistoryInVirtual(*mirroredDrawable, bufferAge, mainScreenInfo);
948 std::shared_ptr<RSObjAbsGeometry> tmpGeo = std::make_shared<RSObjAbsGeometry>();
949 for (auto& rect : damageRegionRects) {
950 RectI mappedRect = tmpGeo->MapRect(rect.ConvertTo<float>(), canvasMatrix);
951 mappedDamageRegionRects.emplace_back(mappedRect);
952 }
953 if (!(lastMatrix_ == canvasMatrix) || !(lastMirrorMatrix_ == mirrorParams->GetMatrix()) ||
954 uniParam->GetForceMirrorScreenDirty() || lastBlackList_ != currentBlackList_ ||
955 mirrorParams->IsSpecialLayerChanged() || lastSecExemption_ != curSecExemption_ || virtualDirtyRefresh_) {
956 GetSyncDirtyManager()->ResetDirtyAsSurfaceSize();
957 virtualDirtyRefresh_ = false;
958 lastMatrix_ = canvasMatrix;
959 lastMirrorMatrix_ = mirrorParams->GetMatrix();
960 }
961 RectI hwcRect = mirroredDrawable->GetSyncDirtyManager()->GetHwcDirtyRegion();
962 if (!hwcRect.IsEmpty()) {
963 RectI mappedHwcRect = tmpGeo->MapRect(hwcRect.ConvertTo<float>(), canvasMatrix);
964 GetSyncDirtyManager()->MergeDirtyRect(mappedHwcRect);
965 }
966 UpdateDisplayDirtyManager(bufferAge, false);
967 auto extraDirty = GetSyncDirtyManager()->GetDirtyRegion();
968 if (!extraDirty.IsEmpty()) {
969 mappedDamageRegionRects.emplace_back(extraDirty);
970 }
971 if (!uniParam->IsVirtualDirtyDfxEnabled()) {
972 virtualProcesser->SetDirtyInfo(mappedDamageRegionRects);
973 RS_TRACE_NAME_FMT("SetDamageRegion damageRegionrects num: %zu, info: %s",
974 mappedDamageRegionRects.size(), RectVectorToString(mappedDamageRegionRects).c_str());
975 }
976 return mappedDamageRegionRects;
977 }
978
DrawMirror(RSDisplayRenderParams & params,std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,DrawFuncPtr drawFunc,RSRenderThreadParams & uniParam)979 void RSDisplayRenderNodeDrawable::DrawMirror(RSDisplayRenderParams& params,
980 std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, DrawFuncPtr drawFunc, RSRenderThreadParams& uniParam)
981 {
982 // uniParam/drawable/mirroredParams not null in caller
983 auto drawable = params.GetMirrorSourceDrawable().lock();
984 auto mirroredDrawable = std::static_pointer_cast<RSDisplayRenderNodeDrawable>(drawable);
985 auto& mirroredParams = mirroredDrawable->GetRenderParams();
986
987 curCanvas_ = virtualProcesser->GetCanvas();
988 if (curCanvas_ == nullptr) {
989 RS_LOGE("RSDisplayRenderNodeDrawable::DrawMirror failed to get canvas.");
990 return;
991 }
992 // for HDR
993 curCanvas_->SetCapture(true);
994 curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
995 curCanvas_->SetDisableFilterCache(true);
996 auto mirroedDisplayParams = static_cast<RSDisplayRenderParams*>(mirroredParams.get());
997 auto hasSecSurface = mirroedDisplayParams->GetDisplayHasSecSurface();
998 if (hasSecSurface[mirroredParams->GetScreenId()] && !uniParam.GetSecExemption()) {
999 std::vector<RectI> emptyRects = {};
1000 virtualProcesser->SetRoiRegionToCodec(emptyRects);
1001 SetCanvasBlack(*virtualProcesser);
1002 curCanvas_->RestoreToCount(0);
1003 return;
1004 }
1005 curCanvas_->Save();
1006 virtualProcesser->ScaleMirrorIfNeed(GetOriginScreenRotation(), *curCanvas_);
1007
1008 RSDirtyRectsDfx rsDirtyRectsDfx(*this);
1009 if (uniParam.IsVirtualDirtyEnabled()) {
1010 Drawing::Matrix matrix = curCanvas_->GetTotalMatrix();
1011 std::vector<RectI> dirtyRects = CalculateVirtualDirty(virtualProcesser, params, matrix);
1012 rsDirtyRectsDfx.SetVirtualDirtyRects(dirtyRects, params.GetScreenInfo());
1013 } else {
1014 std::vector<RectI> emptyRects = {};
1015 virtualProcesser->SetRoiRegionToCodec(emptyRects);
1016 }
1017 // Clean up the content of the previous frame
1018 curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1019
1020 // set mirror screen capture param
1021 // Don't need to scale here since the canvas has been switched from mirror frame to offscreen
1022 // surface in PrepareOffscreenRender() above. The offscreen surface has the same size as
1023 // the main display that's why no need additional scale.
1024 RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true, 1.0f, 1.0f));
1025
1026 RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
1027 bool isOpDropped = uniParam.IsOpDropped();
1028 uniParam.SetOpDropped(false); // disable partial render
1029 (mirroredDrawable.get()->*drawFunc)(*curCanvas_);
1030 uniParam.SetOpDropped(isOpDropped);
1031 RSUniRenderThread::ResetCaptureParam();
1032 // Restore the initial state of the canvas to avoid state accumulation
1033 curCanvas_->RestoreToCount(0);
1034 rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
1035 RSUniRenderThread::Instance().SetBlackList({});
1036 RSUniRenderThread::Instance().SetWhiteList({});
1037 uniParam.SetSecExemption(false);
1038 }
1039
DrawMirrorCopy(RSDisplayRenderNodeDrawable & mirrorDrawable,RSDisplayRenderParams & params,std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser,RSRenderThreadParams & uniParam)1040 void RSDisplayRenderNodeDrawable::DrawMirrorCopy(
1041 RSDisplayRenderNodeDrawable& mirrorDrawable, RSDisplayRenderParams& params,
1042 std::shared_ptr<RSUniRenderVirtualProcessor> virtualProcesser, RSRenderThreadParams& uniParam)
1043 {
1044 auto cacheImage = mirrorDrawable.GetCacheImgForCapture();
1045 bool isOpDropped = uniParam.IsOpDropped();
1046 uniParam.SetOpDropped(false);
1047 mirrorDrawable.SetOriginScreenRotation(GetOriginScreenRotation());
1048 virtualProcesser->CalculateTransform(mirrorDrawable);
1049 RSDirtyRectsDfx rsDirtyRectsDfx(*this);
1050 if (uniParam.IsVirtualDirtyEnabled()) {
1051 auto dirtyRects = CalculateVirtualDirty(
1052 virtualProcesser, params, virtualProcesser->GetCanvasMatrix());
1053 rsDirtyRectsDfx.SetVirtualDirtyRects(dirtyRects, params.GetScreenInfo());
1054 } else {
1055 std::vector<RectI> emptyRects = {};
1056 virtualProcesser->SetRoiRegionToCodec(emptyRects);
1057 }
1058 curCanvas_ = virtualProcesser->GetCanvas();
1059 if (!curCanvas_) {
1060 RS_LOGE("RSDisplayRenderNodeDrawable::DrawMirrorCopy failed to get canvas.");
1061 return;
1062 }
1063 // Clean up the content of the previous frame
1064 curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1065 virtualProcesser->CanvasClipRegionForUniscaleMode();
1066 RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true, 1.0f, 1.0f));
1067 mirrorDrawable.DrawHardwareEnabledNodesMissedInCacheImage(*curCanvas_);
1068 if (cacheImage && RSSystemProperties::GetDrawMirrorCacheImageEnabled()) {
1069 RS_TRACE_NAME("DrawMirrorCopy with cacheImage");
1070 RSUniRenderUtil::ProcessCacheImage(*curCanvas_, *cacheImage);
1071 } else {
1072 RS_TRACE_NAME("DrawMirrorCopy with displaySurface");
1073 virtualProcesser->ProcessDisplaySurfaceForRenderThread(mirrorDrawable);
1074 }
1075 mirrorDrawable.DrawHardwareEnabledTopNodesMissedInCacheImage(*curCanvas_);
1076 RSUniRenderThread::ResetCaptureParam();
1077 uniParam.SetOpDropped(isOpDropped);
1078 // Restore the initial state of the canvas to avoid state accumulation
1079 curCanvas_->RestoreToCount(0);
1080 rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
1081 }
1082
DrawExpandScreen(RSUniRenderVirtualProcessor & processor)1083 void RSDisplayRenderNodeDrawable::DrawExpandScreen(RSUniRenderVirtualProcessor& processor)
1084 {
1085 curCanvas_ = processor.GetCanvas();
1086 if (curCanvas_ == nullptr) {
1087 RS_LOGE("RSDisplayRenderNodeDrawable::DrawExpandScreen failed to get canvas.");
1088 return;
1089 }
1090 float scaleX = 1.0f;
1091 float scaleY = 1.0f;
1092 // set expand screen capture param(isSnapshot, isSingleSurface, isMirror)
1093 RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, false, scaleX, scaleY));
1094 RSRenderNodeDrawable::OnCapture(*curCanvas_);
1095 RSUniRenderThread::ResetCaptureParam();
1096 // Restore the initial state of the canvas to avoid state accumulation
1097 curCanvas_->RestoreToCount(0);
1098 }
1099
WiredScreenProjection(RSDisplayRenderParams & params,std::shared_ptr<RSProcessor> processor)1100 void RSDisplayRenderNodeDrawable::WiredScreenProjection(
1101 RSDisplayRenderParams& params, std::shared_ptr<RSProcessor> processor)
1102 {
1103 RSUniRenderThread::Instance().WaitUntilDisplayNodeBufferReleased(*this);
1104 auto renderFrame = RequestFrame(params, processor);
1105 if (!renderFrame) {
1106 RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection failed to request frame");
1107 return;
1108 }
1109 auto drSurface = renderFrame->GetFrame()->GetSurface();
1110 if (!drSurface) {
1111 RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection DrawingSurface is null");
1112 return;
1113 }
1114 curCanvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
1115 if (!curCanvas_) {
1116 RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection failed to create canvas");
1117 return;
1118 }
1119 auto mirroredDrawable =
1120 std::static_pointer_cast<RSDisplayRenderNodeDrawable>(params.GetMirrorSourceDrawable().lock());
1121 if (!mirroredDrawable) {
1122 RS_LOGE("RSDisplayRenderNodeDrawable::WiredScreenProjection mirroredDrawable is null");
1123 return;
1124 }
1125 curCanvas_->Save();
1126 ScaleAndRotateMirrorForWiredScreen(*mirroredDrawable);
1127 RSDirtyRectsDfx rsDirtyRectsDfx(*mirroredDrawable);
1128 std::vector<RectI> damageRegionRects =
1129 CalculateVirtualDirtyForWiredScreen(renderFrame, params, curCanvas_->GetTotalMatrix());
1130 rsDirtyRectsDfx.SetVirtualDirtyRects(damageRegionRects, params.GetScreenInfo());
1131 // HDR does not support wired screen
1132 if (params.GetHDRPresent() && RSSystemParameters::GetWiredScreenOndrawEnabled()) {
1133 DrawWiredMirrorOnDraw(*mirroredDrawable, params);
1134 } else {
1135 DrawWiredMirrorCopy(*mirroredDrawable);
1136 }
1137 RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true, 1.0f, 1.0f));
1138 mirroredDrawable->DrawHardCursorNodesMissedInCacheImage(*curCanvas_);
1139 RSUniRenderThread::ResetCaptureParam();
1140 curCanvas_->Restore();
1141 rsDirtyRectsDfx.OnDrawVirtual(*curCanvas_);
1142 renderFrame->Flush();
1143 processor->ProcessDisplaySurfaceForRenderThread(*this);
1144 processor->PostProcess();
1145 }
1146
DrawWiredMirrorCopy(RSDisplayRenderNodeDrawable & mirroredDrawable)1147 void RSDisplayRenderNodeDrawable::DrawWiredMirrorCopy(RSDisplayRenderNodeDrawable& mirroredDrawable)
1148 {
1149 auto cacheImage = mirroredDrawable.GetCacheImgForCapture();
1150 if (cacheImage && RSSystemProperties::GetDrawMirrorCacheImageEnabled()) {
1151 RS_TRACE_NAME("DrawWiredMirrorCopy with cacheImage");
1152 RSUniRenderUtil::ProcessCacheImage(*curCanvas_, *cacheImage);
1153 } else {
1154 RS_TRACE_NAME("DrawWiredMirrorCopy with displaySurface");
1155 auto drawParams = RSUniRenderUtil::CreateBufferDrawParam(
1156 *mirroredDrawable.GetRSSurfaceHandlerOnDraw(), false); // false: draw with gpu
1157 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1158 drawParams.isMirror = true;
1159 renderEngine->DrawDisplayNodeWithParams(*curCanvas_,
1160 *mirroredDrawable.GetRSSurfaceHandlerOnDraw(), drawParams);
1161 }
1162 }
1163
DrawWiredMirrorOnDraw(RSDisplayRenderNodeDrawable & mirroredDrawable,RSDisplayRenderParams & params)1164 void RSDisplayRenderNodeDrawable::DrawWiredMirrorOnDraw(
1165 RSDisplayRenderNodeDrawable& mirroredDrawable, RSDisplayRenderParams& params)
1166 {
1167 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1168 if (uniParam == nullptr) {
1169 return;
1170 }
1171 curCanvas_->SetCapture(true);
1172 curCanvas_->SetDisableFilterCache(true);
1173 curCanvas_->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
1174 bool isOpDropped = uniParam->IsOpDropped();
1175 uniParam->SetOpDropped(false);
1176 if (const auto& mirrorParams = static_cast<RSDisplayRenderParams*>(mirroredDrawable.GetRenderParams().get())) {
1177 auto screenInfo = mirrorParams->GetScreenInfo();
1178 uniParam->SetScreenInfo(screenInfo);
1179 Drawing::Rect rect(0, 0, screenInfo.width, screenInfo.height);
1180 RSUniRenderThread::SetCaptureParam(CaptureParam(false, false, true, 1.0f, 1.0f));
1181 curCanvas_->ClipRect(rect, Drawing::ClipOp::INTERSECT, false);
1182 curCanvas_->ConcatMatrix(mirrorParams->GetMatrix());
1183 RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
1184 mirroredDrawable.RSRenderNodeDrawable::OnDraw(*curCanvas_);
1185 DrawCurtainScreen();
1186 DrawWatermarkIfNeed(*mirrorParams, *curCanvas_);
1187 SwitchColorFilter(*curCanvas_, 1.f); // 1.f: wired screen not use hdr, use default value 1.f
1188 RSUniRenderThread::ResetCaptureParam();
1189 }
1190 uniParam->SetOpDropped(isOpDropped);
1191 }
1192
CalculateVirtualDirtyForWiredScreen(std::unique_ptr<RSRenderFrame> & renderFrame,RSDisplayRenderParams & params,Drawing::Matrix canvasMatrix)1193 std::vector<RectI> RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen(
1194 std::unique_ptr<RSRenderFrame>& renderFrame, RSDisplayRenderParams& params, Drawing::Matrix canvasMatrix)
1195 {
1196 std::vector<RectI> damageRegionRects;
1197 auto mirroredDrawable =
1198 std::static_pointer_cast<RSDisplayRenderNodeDrawable>(params.GetMirrorSourceDrawable().lock());
1199 if (!mirroredDrawable || !mirroredDrawable->GetRenderParams()) {
1200 RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen mirroredNode is null");
1201 return damageRegionRects;
1202 }
1203 auto uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams().get();
1204 if (uniParam == nullptr || !uniParam->IsVirtualDirtyEnabled()) {
1205 RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen invalid uniparam");
1206 return damageRegionRects;
1207 }
1208 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
1209 if (screenManager == nullptr) {
1210 RS_LOGE("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen screenManager is null");
1211 return damageRegionRects;
1212 }
1213 auto curScreenInfo = params.GetScreenInfo();
1214 if (!curScreenInfo.isEqualVsyncPeriod) {
1215 RS_LOGD("RSDisplayRenderNodeDrawable::CalculateVirtualDirtyForWiredScreen frame rate is irregular");
1216 return damageRegionRects;
1217 }
1218 int32_t bufferAge = renderFrame->GetBufferAge();
1219 auto& mirroredParams = mirroredDrawable->GetRenderParams();
1220 ScreenInfo mainScreenInfo = screenManager->QueryScreenInfo(mirroredParams->GetScreenId());
1221 std::shared_ptr<RSObjAbsGeometry> tmpGeo = std::make_shared<RSObjAbsGeometry>();
1222 // merge history dirty and map to mirrored wired screen by matrix
1223 auto tempDamageRegionRects = MergeDirtyHistoryInVirtual(*mirroredDrawable, bufferAge, mainScreenInfo);
1224 for (auto& rect : tempDamageRegionRects) {
1225 RectI mappedRect = tmpGeo->MapRect(rect.ConvertTo<float>(), canvasMatrix);
1226 damageRegionRects.emplace_back(mappedRect);
1227 }
1228
1229 auto syncDirtyManager = GetSyncDirtyManager();
1230 // reset dirty rect as mirrored wired screen size when first time connection or matrix changed
1231 if (!(lastMatrix_ == canvasMatrix)) {
1232 syncDirtyManager->ResetDirtyAsSurfaceSize();
1233 lastMatrix_ = canvasMatrix;
1234 }
1235 UpdateDisplayDirtyManager(bufferAge, false);
1236 auto extraDirty = syncDirtyManager->GetDirtyRegion();
1237 if (!extraDirty.IsEmpty()) {
1238 damageRegionRects.emplace_back(extraDirty);
1239 }
1240 if (!uniParam->IsVirtualDirtyDfxEnabled()) {
1241 renderFrame->SetDamageRegion(damageRegionRects);
1242 }
1243 return damageRegionRects;
1244 }
1245
ScaleAndRotateMirrorForWiredScreen(RSDisplayRenderNodeDrawable & mirroredDrawable)1246 void RSDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen(RSDisplayRenderNodeDrawable& mirroredDrawable)
1247 {
1248 const auto& mirroredParams = mirroredDrawable.GetRenderParams();
1249 if (!mirroredParams) {
1250 RS_LOGE("RSDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen mirroredParams is null");
1251 return;
1252 }
1253 const auto& nodeParams = GetRenderParams();
1254 if (!nodeParams) {
1255 RS_LOGE("RSDisplayRenderNodeDrawable::ScaleAndRotateMirrorForWiredScreen nodeParams is null");
1256 return;
1257 }
1258 auto mainScreenInfo = mirroredParams->GetScreenInfo();
1259 auto mainWidth = static_cast<float>(mainScreenInfo.width);
1260 auto mainHeight = static_cast<float>(mainScreenInfo.height);
1261 auto mirrorScreenInfo = nodeParams->GetScreenInfo();
1262 auto mirrorWidth = static_cast<float>(mirrorScreenInfo.width);
1263 auto mirrorHeight = static_cast<float>(mirrorScreenInfo.height);
1264 auto rotation = mirroredParams->GetScreenRotation();
1265 auto screenManager = CreateOrGetScreenManager();
1266 if (screenManager) {
1267 auto screenCorrection = screenManager->GetScreenCorrection(mirroredParams->GetScreenId());
1268 if (screenCorrection != ScreenRotation::INVALID_SCREEN_ROTATION &&
1269 screenCorrection != ScreenRotation::ROTATION_0) {
1270 // Recaculate rotation if mirrored screen has additional rotation angle
1271 rotation = static_cast<ScreenRotation>((static_cast<int>(rotation) + SCREEN_ROTATION_NUM
1272 - static_cast<int>(screenCorrection)) % SCREEN_ROTATION_NUM);
1273 }
1274 }
1275 if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
1276 std::swap(mainWidth, mainHeight);
1277 }
1278 curCanvas_->Clear(SK_ColorBLACK);
1279 // Scale
1280 if (mainWidth > 0 && mainHeight > 0) {
1281 auto scaleNum = std::min(mirrorWidth / mainWidth, mirrorHeight / mainHeight);
1282 // 2 for calc X and Y
1283 curCanvas_->Translate((mirrorWidth - (scaleNum * mainWidth)) / 2, (mirrorHeight - (scaleNum * mainHeight)) / 2);
1284 curCanvas_->Scale(scaleNum, scaleNum);
1285 curCanvas_->ClipRect(Drawing::Rect(0, 0, mainWidth, mainHeight), Drawing::ClipOp::INTERSECT, false);
1286 }
1287 // Rotate
1288 RotateMirrorCanvas(rotation, static_cast<float>(mainScreenInfo.width), static_cast<float>(mainScreenInfo.height));
1289 }
1290
SetCanvasBlack(RSProcessor & processor)1291 void RSDisplayRenderNodeDrawable::SetCanvasBlack(RSProcessor& processor)
1292 {
1293 curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
1294 processor.PostProcess();
1295 RS_LOGI("RSDisplayRenderNodeDrawable::SetCanvasBlack, set canvas to black because of security layer.");
1296 curCanvas_->SetDisableFilterCache(false);
1297 }
1298
RotateMirrorCanvas(ScreenRotation & rotation,float mainWidth,float mainHeight)1299 void RSDisplayRenderNodeDrawable::RotateMirrorCanvas(ScreenRotation& rotation, float mainWidth, float mainHeight)
1300 {
1301 switch (rotation) {
1302 case ScreenRotation::ROTATION_0:
1303 break;
1304 case ScreenRotation::ROTATION_90:
1305 curCanvas_->Rotate(90, 0, 0); // 90 is the rotate angle
1306 curCanvas_->Translate(0, -mainHeight);
1307 break;
1308 case ScreenRotation::ROTATION_180:
1309 // 180 is the rotate angle, calculate half width and half height requires divide by 2
1310 curCanvas_->Rotate(180, mainWidth / 2, mainHeight / 2);
1311 break;
1312 case ScreenRotation::ROTATION_270:
1313 curCanvas_->Rotate(270, 0, 0); // 270 is the rotate angle
1314 curCanvas_->Translate(-mainWidth, 0);
1315 break;
1316 default:
1317 break;
1318 }
1319 }
1320
OnCapture(Drawing::Canvas & canvas)1321 void RSDisplayRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
1322 {
1323 auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1324 if (!params) {
1325 RS_LOGE("RSDisplayRenderNodeDrawable::OnCapture params is null!");
1326 return;
1327 }
1328
1329 auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
1330 if (!rscanvas) {
1331 RS_LOGE("RSDisplayRenderNodeDrawable::OnCapture, rscanvas us nullptr");
1332 return;
1333 }
1334
1335 Drawing::AutoCanvasRestore acr(canvas, true);
1336
1337 specialLayerType_ = GetSpecialLayerType(*params);
1338 if (specialLayerType_ != NO_SPECIAL_LAYER || UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_) ||
1339 isRenderSkipIfScreenOff_) {
1340 RS_LOGD("RSDisplayRenderNodeDrawable::OnCapture: \
1341 process RSDisplayRenderNode(id:[%{public}" PRIu64 "]) Not using UniRender buffer.",
1342 params->GetId());
1343 RS_TRACE_NAME("Process RSDisplayRenderNodeDrawable[" +
1344 std::to_string(params->GetScreenId()) + "] Not using UniRender buffer.");
1345
1346 // Adding matrix affine transformation logic
1347 if (!UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_)) {
1348 rscanvas->ConcatMatrix(params->GetMatrix());
1349 }
1350
1351 RSRenderNodeDrawable::OnCapture(canvas);
1352 DrawWatermarkIfNeed(*params, *rscanvas);
1353 RSDirtyRectsDfx rsDirtyRectsDfx(*this);
1354 rsDirtyRectsDfx.OnDraw(*rscanvas);
1355 } else {
1356 DrawHardwareEnabledNodes(canvas, *params);
1357 }
1358 }
1359
DrawHardwareEnabledNodes(Drawing::Canvas & canvas,RSDisplayRenderParams & params)1360 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes(Drawing::Canvas& canvas, RSDisplayRenderParams& params)
1361 {
1362 auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
1363 if (!rscanvas) {
1364 RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes, rscanvas us nullptr");
1365 return;
1366 }
1367
1368 FindHardwareEnabledNodes(params);
1369
1370 if (GetRSSurfaceHandlerOnDraw()->GetBuffer() == nullptr) {
1371 RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes: buffer is null!");
1372 return;
1373 }
1374
1375 uint32_t hwcNodesNum = static_cast<uint32_t>(params.GetHardwareEnabledDrawables().size());
1376 uint32_t hwcTopNodesNum = static_cast<uint32_t>(params.GetHardwareEnabledTopDrawables().size());
1377
1378 RS_LOGI("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes: \
1379 process RSDisplayRenderNode(id:[%{public}" PRIu64 "]) \
1380 using UniRender buffer with hwcNodes(%{public}u, %{public}u)",
1381 GetId(), hwcNodesNum, hwcTopNodesNum);
1382 RS_TRACE_NAME_FMT("Process RSDisplayRenderNodeDrawable[%" PRIu64 "] \
1383 using UniRender buffer with hwcNodes(%u, %u)",
1384 params.GetScreenId(), hwcNodesNum, hwcTopNodesNum);
1385
1386 if (hwcNodesNum > 0) {
1387 AdjustZOrderAndDrawSurfaceNode(params.GetHardwareEnabledDrawables(), canvas, params);
1388 }
1389
1390 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1391 auto drawParams = RSUniRenderUtil::CreateBufferDrawParam(*GetRSSurfaceHandlerOnDraw(), false);
1392
1393 // To get dump image
1394 // execute "param set rosen.dumpsurfacetype.enabled 4 && setenforce 0 && param set rosen.afbc.enabled 0"
1395 RSBaseRenderUtil::WriteSurfaceBufferToPng(drawParams.buffer);
1396 renderEngine->DrawDisplayNodeWithParams(*rscanvas, *GetRSSurfaceHandlerOnDraw(), drawParams);
1397
1398 if (hwcTopNodesNum > 0) {
1399 AdjustZOrderAndDrawSurfaceNode(params.GetHardwareEnabledTopDrawables(), canvas, params);
1400 }
1401 }
1402
DrawHardwareEnabledNodes(Drawing::Canvas & canvas)1403 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes(Drawing::Canvas& canvas)
1404 {
1405 if (!renderParams_) {
1406 RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes params is null!");
1407 return;
1408 }
1409
1410 auto displayParams = static_cast<RSDisplayRenderParams*>(renderParams_.get());
1411 Drawing::AutoCanvasRestore acr(canvas, true);
1412 DrawHardwareEnabledNodes(canvas, *displayParams);
1413 }
1414
DrawHardwareEnabledNodesMissedInCacheImage(Drawing::Canvas & canvas)1415 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodesMissedInCacheImage(Drawing::Canvas& canvas)
1416 {
1417 auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1418 if (!params) {
1419 RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodesMissedInCacheImage params is null!");
1420 return;
1421 }
1422
1423 Drawing::AutoCanvasRestore acr(canvas, true);
1424 FindHardwareEnabledNodes(*params);
1425 if (params->GetHardwareEnabledDrawables().size() != 0) {
1426 AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledDrawables(), canvas, *params);
1427 }
1428 }
1429
DrawHardwareEnabledTopNodesMissedInCacheImage(Drawing::Canvas & canvas)1430 void RSDisplayRenderNodeDrawable::DrawHardwareEnabledTopNodesMissedInCacheImage(Drawing::Canvas& canvas)
1431 {
1432 auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1433 if (!params) {
1434 RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodesMissedInCacheImage params is null!");
1435 return;
1436 }
1437
1438 Drawing::AutoCanvasRestore acr(canvas, true);
1439 if (params->GetHardwareEnabledTopDrawables().size() != 0) {
1440 AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledTopDrawables(), canvas, *params);
1441 }
1442 }
1443
DrawHardCursorNodesMissedInCacheImage(Drawing::Canvas & canvas)1444 void RSDisplayRenderNodeDrawable::DrawHardCursorNodesMissedInCacheImage(Drawing::Canvas& canvas)
1445 {
1446 auto params = static_cast<RSDisplayRenderParams*>(GetRenderParams().get());
1447 if (!params) {
1448 RS_LOGE("RSDisplayRenderNodeDrawable::DrawHardCursorNodesMissedInCacheImage params is null!");
1449 return;
1450 }
1451
1452 Drawing::AutoCanvasRestore acr(canvas, true);
1453 FindHardCursorNodes(*params);
1454 if (params->GetHardwareEnabledTopDrawables().size() != 0) {
1455 AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledTopDrawables(), canvas, *params);
1456 }
1457 }
1458
FindHardCursorNodes(RSDisplayRenderParams & params)1459 void RSDisplayRenderNodeDrawable::FindHardCursorNodes(RSDisplayRenderParams& params)
1460 {
1461 params.GetHardwareEnabledTopDrawables().clear();
1462 auto& hardCursorDrawable = RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardCursorDrawables();
1463 if (!hardCursorDrawable.drawablePtr) {
1464 return;
1465 }
1466 auto surfaceParams =
1467 static_cast<RSSurfaceRenderParams*>(hardCursorDrawable.drawablePtr->GetRenderParams().get());
1468 if (!surfaceParams) {
1469 RS_LOGE("RSDisplayRenderNodeDrawable::FindHardCursorNodes surfaceParams is null");
1470 return;
1471 }
1472 auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable.drawablePtr);
1473 if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
1474 params.GetHardwareEnabledTopDrawables().emplace_back(surfaceDrawable);
1475 }
1476 }
1477
SwitchColorFilter(RSPaintFilterCanvas & canvas,float hdrBrightnessRatio) const1478 void RSDisplayRenderNodeDrawable::SwitchColorFilter(RSPaintFilterCanvas& canvas, float hdrBrightnessRatio) const
1479 {
1480 const auto& renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1481 if (!renderEngine) {
1482 RS_LOGE("RSDisplayRenderNodeDrawable::SwitchColorFilter renderEngine is null");
1483 return;
1484 }
1485 ColorFilterMode colorFilterMode = renderEngine->GetColorFilterMode();
1486 if (colorFilterMode == ColorFilterMode::INVERT_COLOR_DISABLE_MODE ||
1487 colorFilterMode >= ColorFilterMode::DALTONIZATION_NORMAL_MODE) {
1488 return;
1489 }
1490
1491 Drawing::AutoCanvasRestore acr(*curCanvas_, true);
1492 RS_TRACE_NAME_FMT("RSDisplayRenderNodeDrawable::SetColorFilterModeToPaint mode:%d",
1493 static_cast<int32_t>(colorFilterMode));
1494 Drawing::Brush brush;
1495 RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush, hdrBrightnessRatio);
1496 #if defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)
1497 #ifdef NEW_RENDER_CONTEXT
1498 RSTagTracker tagTracker(
1499 renderEngine->GetDrawingContext()->GetDrawingContext(),
1500 RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
1501 #else
1502 RSTagTracker tagTracker(
1503 renderEngine->GetRenderContext()->GetDrGPUContext(),
1504 RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
1505 #endif
1506 #endif
1507 Drawing::SaveLayerOps slr(nullptr, &brush, Drawing::SaveLayerOps::INIT_WITH_PREVIOUS);
1508 canvas.SaveLayer(slr);
1509 }
1510
FindHardwareEnabledNodes(RSDisplayRenderParams & params)1511 void RSDisplayRenderNodeDrawable::FindHardwareEnabledNodes(RSDisplayRenderParams& params)
1512 {
1513 params.GetHardwareEnabledTopDrawables().clear();
1514 params.GetHardwareEnabledDrawables().clear();
1515 auto& hardwareDrawables =
1516 RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
1517 for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
1518 auto surfaceNodeDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
1519 if (!surfaceNodeDrawable || !surfaceNodeDrawable->ShouldPaint() ||
1520 displayNodeId != params.GetId()) {
1521 continue;
1522 }
1523 auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
1524 if (surfaceParams == nullptr || !surfaceParams->GetHardwareEnabled()) {
1525 continue;
1526 }
1527 // To get dump image
1528 // execute "param set rosen.dumpsurfacetype.enabled 4 && setenforce 0 && param set rosen.afbc.enabled 0"
1529 auto buffer = surfaceParams->GetBuffer();
1530 RSBaseRenderUtil::WriteSurfaceBufferToPng(buffer, surfaceParams->GetId());
1531 if (surfaceNodeDrawable->IsHardwareEnabledTopSurface() || surfaceParams->IsLayerTop()) {
1532 // surfaceNode which should be drawn above displayNode like pointer window
1533 params.GetHardwareEnabledTopDrawables().emplace_back(drawable);
1534 } else {
1535 // surfaceNode which should be drawn below displayNode
1536 params.GetHardwareEnabledDrawables().emplace_back(drawable);
1537 }
1538 }
1539 auto& hardCursorDrawable = RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardCursorDrawables();
1540 if (hardCursorDrawable.id != GetId() || !hardCursorDrawable.drawablePtr) {
1541 return;
1542 }
1543 auto surfaceParams =
1544 static_cast<RSSurfaceRenderParams*>(hardCursorDrawable.drawablePtr->GetRenderParams().get());
1545 if (!surfaceParams) {
1546 RS_LOGE("RSDisplayRenderNodeDrawable::FindHardwareEnabledNodes surfaceParams is null");
1547 return;
1548 }
1549 auto surfaceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(hardCursorDrawable.drawablePtr);
1550 if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
1551 params.GetHardwareEnabledTopDrawables().emplace_back(surfaceDrawable);
1552 }
1553 }
1554
1555
AdjustZOrderAndDrawSurfaceNode(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & drawables,Drawing::Canvas & canvas,RSDisplayRenderParams & params) const1556 void RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode(
1557 std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& drawables,
1558 Drawing::Canvas& canvas, RSDisplayRenderParams& params) const
1559 {
1560 if (!RSSystemProperties::GetHardwareComposerEnabled()) {
1561 RS_LOGW("RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode: \
1562 HardwareComposer is not enabled.");
1563 return;
1564 }
1565
1566 // sort the surfaceNodes by ZOrder
1567 std::stable_sort(drawables.begin(), drawables.end(), [](const auto& first, const auto& second) -> bool {
1568 auto firstDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(first);
1569 auto secondDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(second);
1570 if (!firstDrawable || !firstDrawable->GetRenderParams() ||
1571 !secondDrawable || !secondDrawable->GetRenderParams()) {
1572 return false;
1573 }
1574 return firstDrawable->GetRenderParams()->GetLayerInfo().zOrder <
1575 secondDrawable->GetRenderParams()->GetLayerInfo().zOrder;
1576 });
1577
1578 Drawing::AutoCanvasRestore acr(canvas, true);
1579 auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
1580 if (!rscanvas) {
1581 RS_LOGE("RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode, rscanvas is nullptr");
1582 return;
1583 }
1584 // draw hardware-composition nodes
1585 for (auto& drawable : drawables) {
1586 Drawing::AutoCanvasRestore acr(canvas, true);
1587 if (!drawable || !drawable->GetRenderParams()) {
1588 RS_LOGE("RSDisplayRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode surfaceParams is nullptr");
1589 continue;
1590 }
1591 auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
1592 // SelfDrawingNodes need to use LayerMatrix(totalMatrix) when doing capturing
1593 auto matrix = surfaceParams->GetLayerInfo().matrix;
1594 canvas.ConcatMatrix(matrix);
1595 auto surfaceNodeDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
1596 surfaceNodeDrawable->DealWithSelfDrawingNodeBuffer(*rscanvas, *surfaceParams);
1597 }
1598 }
1599
DrawWatermarkIfNeed(RSDisplayRenderParams & params,RSPaintFilterCanvas & canvas) const1600 void RSDisplayRenderNodeDrawable::DrawWatermarkIfNeed(RSDisplayRenderParams& params, RSPaintFilterCanvas& canvas) const
1601 {
1602 if (!RSUniRenderThread::Instance().GetWatermarkFlag()) {
1603 return;
1604 }
1605 auto image = RSUniRenderThread::Instance().GetWatermarkImg();
1606 if (image == nullptr) {
1607 return;
1608 }
1609 if (auto screenManager = CreateOrGetScreenManager()) {
1610 RS_TRACE_FUNC();
1611 auto screenInfo = screenManager->QueryScreenInfo(params.GetScreenId());
1612 auto mainWidth = static_cast<float>(screenInfo.width);
1613 auto mainHeight = static_cast<float>(screenInfo.height);
1614
1615 // in certain cases (such as fold screen), the width and height must be swapped to fix the screen rotation.
1616 int angle = RSUniRenderUtil::GetRotationFromMatrix(canvas.GetTotalMatrix());
1617 if (angle == RS_ROTATION_90 || angle == RS_ROTATION_270) {
1618 std::swap(mainWidth, mainHeight);
1619 }
1620 auto srcRect = Drawing::Rect(0, 0, image->GetWidth(), image->GetHeight());
1621 auto dstRect = Drawing::Rect(0, 0, mainWidth, mainHeight);
1622 Drawing::Brush rectBrush;
1623 canvas.AttachBrush(rectBrush);
1624 canvas.DrawImageRect(*image, srcRect, dstRect, Drawing::SamplingOptions(),
1625 Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
1626 canvas.DetachBrush();
1627 }
1628 }
1629
DrawCurtainScreen() const1630 void RSDisplayRenderNodeDrawable::DrawCurtainScreen() const
1631 {
1632 if (!RSUniRenderThread::Instance().IsCurtainScreenOn() || !curCanvas_) {
1633 return;
1634 }
1635 RS_TRACE_FUNC();
1636 curCanvas_->Clear(Drawing::Color::COLOR_BLACK);
1637 }
1638
ClearTransparentBeforeSaveLayer()1639 void RSDisplayRenderNodeDrawable::ClearTransparentBeforeSaveLayer()
1640 {
1641 if (!canvasBackup_) {
1642 return;
1643 }
1644 RS_TRACE_NAME("ClearTransparentBeforeSaveLayer");
1645 auto& hardwareDrawables =
1646 RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
1647 if (UNLIKELY(!renderParams_)) {
1648 RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw renderParams is null!");
1649 return;
1650 }
1651 auto params = static_cast<RSDisplayRenderParams*>(renderParams_.get());
1652 for (const auto& [displayNodeId, drawable] : hardwareDrawables) {
1653 auto surfaceDrawable = static_cast<RSSurfaceRenderNodeDrawable*>(drawable.get());
1654 if (!surfaceDrawable || displayNodeId != params->GetId()) {
1655 continue;
1656 }
1657 auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
1658 if (!surfaceParams || !surfaceParams->GetHardwareEnabled()) {
1659 continue;
1660 }
1661 RSAutoCanvasRestore arc(canvasBackup_.get());
1662 canvasBackup_->SetMatrix(surfaceParams->GetLayerInfo().matrix);
1663 canvasBackup_->ClipRect(surfaceParams->GetBounds());
1664 canvasBackup_->Clear(Drawing::Color::COLOR_TRANSPARENT);
1665 }
1666 }
1667
PrepareHdrDraw(int32_t offscreenWidth,int32_t offscreenHeight)1668 void RSDisplayRenderNodeDrawable::PrepareHdrDraw(int32_t offscreenWidth, int32_t offscreenHeight)
1669 {
1670 RS_LOGD("HDR PrepareHdrDraw");
1671 offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(offscreenWidth, offscreenHeight);
1672 }
1673
FinishHdrDraw(Drawing::Brush & paint,float hdrBrightnessRatio)1674 void RSDisplayRenderNodeDrawable::FinishHdrDraw(Drawing::Brush& paint, float hdrBrightnessRatio)
1675 {
1676 RS_LOGD("HDR FinishHdrDraw");
1677 Drawing::Filter filter = paint.GetFilter();
1678 Drawing::ColorMatrix luminanceMatrix;
1679 luminanceMatrix.SetScale(hdrBrightnessRatio, hdrBrightnessRatio, hdrBrightnessRatio, 1.0f);
1680 auto luminanceColorFilter = std::make_shared<Drawing::ColorFilter>(Drawing::ColorFilter::FilterType::MATRIX,
1681 luminanceMatrix);
1682 filter.SetColorFilter(luminanceColorFilter);
1683 paint.SetFilter(filter);
1684 }
1685
PrepareOffscreenRender(const RSDisplayRenderNodeDrawable & displayDrawable,bool useFixedSize)1686 void RSDisplayRenderNodeDrawable::PrepareOffscreenRender(const RSDisplayRenderNodeDrawable& displayDrawable,
1687 bool useFixedSize)
1688 {
1689 // params not null in caller
1690 auto params = static_cast<RSDisplayRenderParams*>(displayDrawable.GetRenderParams().get());
1691 // cleanup
1692 canvasBackup_ = nullptr;
1693 // check offscreen size and hardware renderer
1694 useFixedOffscreenSurfaceSize_ = false;
1695 const ScreenInfo& screenInfo = params->GetScreenInfo();
1696 int32_t offscreenWidth = static_cast<int32_t>(screenInfo.width);
1697 int32_t offscreenHeight = static_cast<int32_t>(screenInfo.height);
1698 // use fixed surface size in order to reduce create texture
1699 if (useFixedSize && (RSSystemProperties::IsFoldScreenFlag() || RSSystemProperties::IsTabletType())
1700 && params->IsRotationChanged()) {
1701 useFixedOffscreenSurfaceSize_ = true;
1702 int32_t maxRenderSize =
1703 static_cast<int32_t>(std::max(params->GetScreenInfo().width, params->GetScreenInfo().height));
1704 offscreenWidth = maxRenderSize;
1705 offscreenHeight = maxRenderSize;
1706 }
1707 if (params->IsRotationChanged()) {
1708 if (RSUniRenderThread::Instance().GetVmaOptimizeFlag()) {
1709 Drawing::StaticFactory::SetVmaCacheStatus(true); // render this frame with vma cache on
1710 }
1711 }
1712
1713 if (offscreenWidth <= 0 || offscreenHeight <= 0) {
1714 RS_LOGE("RSDisplayRenderNodeDrawable::PrepareOffscreenRender, offscreenWidth or offscreenHeight is invalid");
1715 return;
1716 }
1717 if (curCanvas_->GetSurface() == nullptr) {
1718 curCanvas_->ClipRect(Drawing::Rect(0, 0, offscreenWidth, offscreenHeight), Drawing::ClipOp::INTERSECT, false);
1719 RS_LOGE("RSDisplayRenderNodeDrawable::PrepareOffscreenRender, current surface is nullptr");
1720 return;
1721 }
1722 if (!(params->GetNeedOffscreen() && useFixedOffscreenSurfaceSize_ && offscreenSurface_ != nullptr)) {
1723 RS_TRACE_NAME_FMT("make offscreen surface with fixed size: [%d, %d]", offscreenWidth, offscreenHeight);
1724 if (!params->GetNeedOffscreen() && params->GetHDRPresent()) {
1725 offscreenWidth = curCanvas_->GetWidth();
1726 offscreenHeight = curCanvas_->GetHeight();
1727 }
1728 if (params->GetHDRPresent()) {
1729 PrepareHdrDraw(offscreenWidth, offscreenHeight);
1730 } else {
1731 offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(offscreenWidth, offscreenHeight);
1732 }
1733 }
1734
1735 if (offscreenSurface_ == nullptr) {
1736 RS_LOGE("RSDisplayRenderNodeDrawable::PrepareOffscreenRender, offscreenSurface is nullptr");
1737 curCanvas_->ClipRect(Drawing::Rect(0, 0, offscreenWidth, offscreenHeight), Drawing::ClipOp::INTERSECT, false);
1738 return;
1739 }
1740 auto offscreenCanvas = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
1741
1742 // copy HDR properties into offscreen canvas
1743 offscreenCanvas->CopyHDRConfiguration(*curCanvas_);
1744 // copy current canvas properties into offscreen canvas
1745 offscreenCanvas->CopyConfigurationToOffscreenCanvas(*curCanvas_);
1746
1747 // backup current canvas and replace with offscreen canvas
1748 canvasBackup_ = std::exchange(curCanvas_, offscreenCanvas);
1749 }
1750
FinishOffscreenRender(const Drawing::SamplingOptions & sampling,float hdrBrightnessRatio)1751 void RSDisplayRenderNodeDrawable::FinishOffscreenRender(const Drawing::SamplingOptions& sampling,
1752 float hdrBrightnessRatio)
1753 {
1754 if (canvasBackup_ == nullptr) {
1755 RS_LOGE("RSDisplayRenderNodeDrawable::FinishOffscreenRender, canvasBackup_ is nullptr");
1756 return;
1757 }
1758 if (offscreenSurface_ == nullptr) {
1759 RS_LOGE("RSDisplayRenderNodeDrawable::FinishOffscreenRender, offscreenSurface_ is nullptr");
1760 return;
1761 }
1762 auto image = offscreenSurface_->GetImageSnapshot();
1763 if (image == nullptr) {
1764 RS_LOGE("RSDisplayRenderNodeDrawable::FinishOffscreenRender, Surface::GetImageSnapshot is nullptr");
1765 return;
1766 }
1767 // draw offscreen surface to current canvas
1768 Drawing::Brush paint;
1769 if (ROSEN_LNE(hdrBrightnessRatio, 1.0f)) {
1770 FinishHdrDraw(paint, hdrBrightnessRatio);
1771 }
1772 paint.SetAntiAlias(true);
1773 canvasBackup_->AttachBrush(paint);
1774 canvasBackup_->DrawImage(*image, 0, 0, sampling);
1775 canvasBackup_->DetachBrush();
1776 // restore current canvas and cleanup
1777 if (!useFixedOffscreenSurfaceSize_) {
1778 offscreenSurface_ = nullptr;
1779 }
1780 curCanvas_ = std::move(canvasBackup_);
1781 }
1782
1783 #ifndef ROSEN_CROSS_PLATFORM
CreateSurface(sptr<IBufferConsumerListener> listener)1784 bool RSDisplayRenderNodeDrawable::CreateSurface(sptr<IBufferConsumerListener> listener)
1785 {
1786 auto consumer = surfaceHandler_->GetConsumer();
1787 if (consumer != nullptr && surface_ != nullptr) {
1788 RS_LOGI("RSDisplayRenderNode::CreateSurface already created, return");
1789 return true;
1790 }
1791 consumer = IConsumerSurface::Create("DisplayNode");
1792 if (consumer == nullptr) {
1793 RS_LOGE("RSDisplayRenderNode::CreateSurface get consumer surface fail");
1794 return false;
1795 }
1796 SurfaceError ret = consumer->RegisterConsumerListener(listener);
1797 if (ret != SURFACE_ERROR_OK) {
1798 RS_LOGE("RSDisplayRenderNode::CreateSurface RegisterConsumerListener fail");
1799 return false;
1800 }
1801 consumerListener_ = listener;
1802 auto producer = consumer->GetProducer();
1803 sptr<Surface> surface = Surface::CreateSurfaceAsProducer(producer);
1804 if (!surface) {
1805 RS_LOGE("RSDisplayRenderNode::CreateSurface CreateSurfaceAsProducer fail");
1806 return false;
1807 }
1808 surface->SetQueueSize(BUFFER_SIZE);
1809 auto client = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
1810 surface_ = client->CreateRSSurface(surface);
1811 RS_LOGI("RSDisplayRenderNode::CreateSurface end");
1812 surfaceCreated_ = true;
1813 surfaceHandler_->SetConsumer(consumer);
1814 return true;
1815 }
1816 #endif
1817
SkipFrameByInterval(uint32_t refreshRate,uint32_t skipFrameInterval)1818 bool RSDisplayRenderNodeDrawable::SkipFrameByInterval(uint32_t refreshRate, uint32_t skipFrameInterval)
1819 {
1820 if (refreshRate == 0 || skipFrameInterval <= 1) {
1821 return false;
1822 }
1823 int64_t currentTime = std::chrono::duration_cast<std::chrono::nanoseconds>(
1824 std::chrono::steady_clock::now().time_since_epoch()).count();
1825 // the skipFrameInterval is equal to 60 divide the virtual screen refresh rate
1826 int64_t refreshInterval = currentTime - lastRefreshTime_;
1827 // 1000000000ns == 1s, 110/100 allows 10% over.
1828 bool needSkip = refreshInterval < (1000000000LL / refreshRate) * (skipFrameInterval - 1) * 110 / 100;
1829 if (!needSkip) {
1830 lastRefreshTime_ = currentTime;
1831 }
1832 return needSkip;
1833 }
1834
SkipFrameByRefreshRate(uint32_t refreshRate,uint32_t expectedRefreshRate)1835 bool RSDisplayRenderNodeDrawable::SkipFrameByRefreshRate(uint32_t refreshRate, uint32_t expectedRefreshRate)
1836 {
1837 if (refreshRate == 0 || expectedRefreshRate == 0 || refreshRate == expectedRefreshRate) {
1838 return false;
1839 }
1840 int64_t currentTime = RSMainThread::Instance()->GetCurrentVsyncTime();
1841 int64_t minFrameInterval = 1000000000LL / expectedRefreshRate;
1842 if (minFrameInterval == 0) {
1843 return false;
1844 }
1845 // lastRefreshTime_ is next frame expected refresh time for virtual display
1846 if (lastRefreshTime_ <= 0) {
1847 lastRefreshTime_ = currentTime + minFrameInterval;
1848 return false;
1849 }
1850 if (currentTime < (lastRefreshTime_ - MAX_JITTER_NS)) {
1851 return true;
1852 }
1853 int64_t intervalNums = (currentTime - lastRefreshTime_ + MAX_JITTER_NS) / minFrameInterval;
1854 lastRefreshTime_ += (intervalNums + 1) * minFrameInterval;
1855 return false;
1856 }
1857
SkipFrame(uint32_t refreshRate,ScreenInfo screenInfo)1858 bool RSDisplayRenderNodeDrawable::SkipFrame(uint32_t refreshRate, ScreenInfo screenInfo)
1859 {
1860 bool needSkip = false;
1861 switch (screenInfo.skipFrameStrategy) {
1862 case SKIP_FRAME_BY_INTERVAL:
1863 needSkip = SkipFrameByInterval(refreshRate, screenInfo.skipFrameInterval);
1864 break;
1865 case SKIP_FRAME_BY_REFRESH_RATE:
1866 needSkip = SkipFrameByRefreshRate(refreshRate, screenInfo.expectedRefreshRate);
1867 break;
1868 default:
1869 break;
1870 }
1871 return needSkip;
1872 }
1873 } // namespace OHOS::Rosen::DrawableV2
1874