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