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