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