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