• 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_surface_render_node_drawable.h"
17 
18 #include "acquire_fence_manager.h"
19 #include "impl_interface/region_impl.h"
20 #include "rs_trace.h"
21 #include "common/rs_color.h"
22 #include "common/rs_common_def.h"
23 #include "common/rs_optional_trace.h"
24 #include "common/rs_obj_abs_geometry.h"
25 #include "common/rs_special_layer_manager.h"
26 #include "display_engine/rs_luminance_control.h"
27 #include "draw/brush.h"
28 #include "drawable/rs_display_render_node_drawable.h"
29 #include "feature/uifirst/rs_sub_thread_manager.h"
30 #include "feature/uifirst/rs_uifirst_manager.h"
31 #include "include/gpu/vk/GrVulkanTrackerInterface.h"
32 #include "memory/rs_tag_tracker.h"
33 #include "params/rs_display_render_params.h"
34 #include "params/rs_surface_render_params.h"
35 #include "pipeline/render_thread/rs_uni_render_thread.h"
36 #include "pipeline/render_thread/rs_uni_render_util.h"
37 #include "pipeline/rs_paint_filter_canvas.h"
38 #include "pipeline/rs_surface_handler.h"
39 #include "pipeline/rs_surface_render_node.h"
40 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
41 #include "pipeline/magic_pointer_render/rs_magic_pointer_render_manager.h"
42 #endif
43 #include "gfx/fps_info/rs_surface_fps_manager.h"
44 
45 #include "platform/common/rs_log.h"
46 #include "platform/ohos/rs_node_stats.h"
47 #include "utils/rect.h"
48 #include "utils/region.h"
49 
50 #include "pipeline/main_thread/rs_main_thread.h"
51 #include "static_factory.h"
52 #ifdef RS_ENABLE_VK
53 #include "include/gpu/GrBackendSurface.h"
54 #include "platform/ohos/backend/native_buffer_utils.h"
55 #include "platform/ohos/backend/rs_vulkan_context.h"
56 #endif
57 #include "render/rs_high_performance_visual_engine.h"
58 #include "render/rs_pixel_map_util.h"
59 #ifdef USE_VIDEO_PROCESSING_ENGINE
60 #include "metadata_helper.h"
61 #endif
62 namespace {
63 constexpr int32_t CORNER_SIZE = 4;
64 constexpr float GAMMA2_2 = 2.2f;
65 constexpr const char* WALLPAPER = "SCBWallpaper";
66 }
67 namespace OHOS::Rosen::DrawableV2 {
68 RSSurfaceRenderNodeDrawable::Registrar RSSurfaceRenderNodeDrawable::instance_;
69 
RSSurfaceRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)70 RSSurfaceRenderNodeDrawable::RSSurfaceRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
71     : RSRenderNodeDrawable(std::move(node)), syncDirtyManager_(std::make_shared<RSDirtyRegionManager>())
72 {
73     auto nodeSp = std::const_pointer_cast<RSRenderNode>(node);
74     auto surfaceNode = std::static_pointer_cast<RSSurfaceRenderNode>(nodeSp);
75     name_ = surfaceNode->GetName();
76     if (name_.find("SCBScreenLock") != std::string::npos) {
77         vmaCacheOff_ = true;
78     }
79     surfaceNodeType_ = surfaceNode->GetSurfaceNodeType();
80 #ifndef ROSEN_CROSS_PLATFORM
81     consumerOnDraw_ = surfaceNode->GetRSSurfaceHandler()->GetConsumer();
82 #endif
83 }
84 
~RSSurfaceRenderNodeDrawable()85 RSSurfaceRenderNodeDrawable::~RSSurfaceRenderNodeDrawable()
86 {
87     ClearCacheSurfaceInThread();
88 }
89 
OnGenerate(std::shared_ptr<const RSRenderNode> node)90 RSRenderNodeDrawable::Ptr RSSurfaceRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
91 {
92     RS_TRACE_NAME("RSRenderNodeDrawable::Ptr RSSurfaceRenderNodeDrawable::OnGenerate");
93     return new RSSurfaceRenderNodeDrawable(std::move(node));
94 }
95 
CheckDrawAndCacheWindowContent(RSSurfaceRenderParams & surfaceParams,RSRenderThreadParams & uniParams) const96 bool RSSurfaceRenderNodeDrawable::CheckDrawAndCacheWindowContent(RSSurfaceRenderParams& surfaceParams,
97     RSRenderThreadParams& uniParams) const
98 {
99     if (!surfaceParams.GetNeedCacheSurface()) {
100         return false;
101     }
102 
103     if (surfaceParams.IsCloneNode() && RSUniRenderThread::GetCaptureParam().isSnapshot_) {
104         return false;
105     }
106 
107     if (!surfaceParams.IsCrossNode()) {
108         return true;
109     }
110     if (uniParams.IsFirstVisitCrossNodeDisplay() &&
111         RSUniRenderThread::IsExpandScreenMode() && !uniParams.HasDisplayHdrOn() &&
112         uniParams.GetCrossNodeOffScreenStatus() != CrossNodeOffScreenRenderDebugType::DISABLED) {
113         RS_TRACE_NAME_FMT("%s cache cross node[%s]", __func__, GetName().c_str());
114         return true;
115     }
116     return false;
117 }
118 
OnGeneralProcess(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams,RSRenderThreadParams & uniParams,bool isSelfDrawingSurface)119 void RSSurfaceRenderNodeDrawable::OnGeneralProcess(RSPaintFilterCanvas& canvas,
120     RSSurfaceRenderParams& surfaceParams, RSRenderThreadParams& uniParams, bool isSelfDrawingSurface)
121 {
122     auto bounds = surfaceParams.GetFrameRect();
123 
124     if (surfaceParams.GetGlobalPositionEnabled()) {
125         auto matrix = surfaceParams.GetTotalMatrix();
126         matrix.Translate(-offsetX_, -offsetY_);
127         canvas.ConcatMatrix(matrix);
128         if (!lastGlobalPositionEnabled_) {
129             lastGlobalPositionEnabled_ = true;
130             RS_LOGI("RSSurfaceRenderNodeDrawable::%{public}s Translate screenId=[%{public}" PRIu64 "] "
131                 "offsetX=%{public}d offsetY=%{public}d", __func__, curDisplayScreenId_, offsetX_, offsetY_);
132         }
133     } else if (lastGlobalPositionEnabled_) {
134         lastGlobalPositionEnabled_ = false;
135     }
136     RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::%s Translate screenId=[%" PRIu64 "] "
137         "offsetX=%d offsetY=%d", __func__, curDisplayScreenId_, offsetX_, offsetY_);
138 
139     // 1. draw background
140     if (surfaceParams.IsLeashWindow()) {
141         DrawLeashWindowBackground(canvas, bounds,
142             uniParams.IsStencilPixelOcclusionCullingEnabled(), surfaceParams.GetStencilVal());
143     } else {
144         DrawBackground(canvas, bounds);
145     }
146 
147     // 2. draw self drawing node
148     if (surfaceParams.GetBuffer() != nullptr) {
149         DealWithSelfDrawingNodeBuffer(canvas, surfaceParams);
150     }
151 
152     if (isSelfDrawingSurface) {
153         canvas.Restore();
154     }
155 
156     if (CheckDrawAndCacheWindowContent(surfaceParams, uniParams)) {
157         // 3/4 Draw content and children of this node by the main canvas, and cache
158         drawWindowCache_.DrawAndCacheWindowContent(this, canvas, bounds);
159     } else {
160         // 3. Draw content of this node by the main canvas.
161         DrawContent(canvas, bounds);
162 
163         // 4. Draw children of this node by the main canvas.
164         DrawChildren(canvas, bounds);
165     }
166 
167     // 5. Draw foreground of this node by the main canvas.
168     DrawForeground(canvas, bounds);
169 
170     DrawWatermark(canvas, surfaceParams);
171 
172     if (surfaceParams.IsCrossNode() &&
173         uniParams.GetCrossNodeOffScreenStatus() == CrossNodeOffScreenRenderDebugType::ENABLE_DFX) {
174         // rgba: Alpha 128, green 128, blue 128
175         Drawing::Color color(0, 128, 128, 128);
176         drawWindowCache_.DrawCrossNodeOffscreenDFX(canvas, surfaceParams, uniParams, color);
177     }
178 }
179 
DrawWatermark(RSPaintFilterCanvas & canvas,const RSSurfaceRenderParams & params)180 void RSSurfaceRenderNodeDrawable::DrawWatermark(RSPaintFilterCanvas& canvas, const RSSurfaceRenderParams& params)
181 {
182     if (params.IsWatermarkEmpty()) {
183         RS_LOGE("SurfaceNodeDrawable DrawWatermark Name:%{public}s Id:%{public}" PRIu64 " water mark count is zero",
184             GetName().c_str(), params.GetId());
185         return;
186     }
187     auto& renderThreadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
188     if (!renderThreadParams) {
189         RS_LOGE("SurfaceNodeDrawable DrawWatermark renderThreadParams is nullptr");
190         return;
191     }
192     auto surfaceRect = params.GetBounds();
193     for (auto& [name, isEnabled] : params.GetWatermarksEnabled()) {
194         if (!isEnabled) {
195             continue;
196         }
197         auto watermark = renderThreadParams->GetWatermark(name);
198         if (!watermark) {
199             continue;
200         }
201         auto imagePtr = RSPixelMapUtil::ExtractDrawingImage(watermark);
202         if (!imagePtr || imagePtr->GetWidth() == 0 || imagePtr->GetHeight() == 0) {
203             continue;
204         }
205         auto imageRect = Drawing::Rect(0, 0, imagePtr->GetWidth(), imagePtr->GetHeight());
206         Drawing::Brush brush;
207         brush.SetShaderEffect(Drawing::ShaderEffect::CreateImageShader(
208             *imagePtr, Drawing::TileMode::REPEAT, Drawing::TileMode::REPEAT,
209             Drawing::SamplingOptions(), Drawing::Matrix()));
210         canvas.AttachBrush(brush);
211         canvas.DrawRect(surfaceRect);
212         canvas.DetachBrush();
213     }
214 }
215 
CalculateVisibleDirtyRegion(RSRenderThreadParams & uniParam,RSSurfaceRenderParams & surfaceParams,RSSurfaceRenderNodeDrawable & surfaceDrawable,bool isOffscreen) const216 Drawing::Region RSSurfaceRenderNodeDrawable::CalculateVisibleDirtyRegion(RSRenderThreadParams& uniParam,
217     RSSurfaceRenderParams& surfaceParams, RSSurfaceRenderNodeDrawable& surfaceDrawable, bool isOffscreen) const
218 {
219     Drawing::Region resultRegion;
220     if (!surfaceParams.IsMainWindowType()) {
221         return resultRegion;
222     }
223 
224     // FUTURE: return real region
225     if (isOffscreen) {
226         resultRegion.SetRect(Drawing::RectI(0, 0,
227         DRAWING_MAX_S32_FITS_IN_FLOAT, DRAWING_MAX_S32_FITS_IN_FLOAT));
228         return resultRegion;
229     }
230 
231     auto visibleRegion = surfaceParams.GetVisibleRegion();
232     if (uniParam.IsOcclusionEnabled() && visibleRegion.IsEmpty() && !surfaceParams.IsFirstLevelCrossNode()) {
233         return resultRegion;
234     }
235     // The region is dirty region of this SurfaceNode.
236     Occlusion::Region dirtyRegion;
237     for (const auto& rect : GetSyncDirtyManager()->GetDirtyRegionForQuickReject()) {
238         Occlusion::Region region = Occlusion::Region(Occlusion::Rect(rect));
239         dirtyRegion.OrSelf(region);
240     }
241     // visibility of cross-display surface (which is generally at the top) is ignored.
242     auto visibleDirtyRegion = surfaceParams.IsFirstLevelCrossNode() ? dirtyRegion : dirtyRegion.And(visibleRegion);
243     if (visibleDirtyRegion.IsEmpty()) {
244         RS_LOGD("RSSurfaceRenderNodeDrawable::OnDraw occlusion skip SurfaceName:%s NodeId:%" PRIu64 "",
245             surfaceDrawable.GetName().c_str(), surfaceParams.GetId());
246         return resultRegion;
247     }
248 
249     for (auto& rect : visibleDirtyRegion.GetRegionRects()) {
250         Drawing::Region tempRegion;
251         tempRegion.SetRect(Drawing::RectI(rect.left_, rect.top_, rect.right_, rect.bottom_));
252         resultRegion.Op(tempRegion, Drawing::RegionOp::UNION);
253     }
254     return resultRegion;
255 }
256 
PrepareOffscreenRender()257 bool RSSurfaceRenderNodeDrawable::PrepareOffscreenRender()
258 {
259     // cleanup
260     canvasBackup_ = nullptr;
261 
262     // check offscreen size
263     if (curCanvas_->GetSurface() == nullptr) {
264         RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, current surface is nullptr");
265         return false;
266     }
267     int offscreenWidth = curCanvas_->GetSurface()->Width();
268     int offscreenHeight = curCanvas_->GetSurface()->Height();
269     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
270     if (uniParam && uniParam->IsMirrorScreen() &&
271         uniParam->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
272         auto screenInfo = uniParam->GetScreenInfo();
273         offscreenWidth = static_cast<int>(screenInfo.width);
274         offscreenHeight = static_cast<int>(screenInfo.height);
275     }
276     if (offscreenWidth <= 0 || offscreenHeight <= 0) {
277         RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, offscreenWidth or offscreenHeight is invalid");
278         return false;
279     }
280 
281     int maxRenderSize = std::max(offscreenWidth, offscreenHeight);
282     // create offscreen surface and canvas
283     if (offscreenSurface_ == nullptr || maxRenderSize_ != maxRenderSize) {
284         RS_LOGD("PrepareOffscreenRender create offscreen surface offscreenSurface_,\
285             new [%{public}d, %{public}d %{public}d]", offscreenWidth, offscreenHeight, maxRenderSize);
286         RS_TRACE_NAME_FMT("PrepareOffscreenRender surface size: [%d, %d]", maxRenderSize, maxRenderSize);
287         maxRenderSize_ = maxRenderSize;
288         offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(maxRenderSize_, maxRenderSize_);
289     }
290     if (offscreenSurface_ == nullptr) {
291         RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, offscreenSurface is nullptr");
292         return false;
293     }
294 
295     offscreenCanvas_ = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
296 
297     // copy HDR properties into offscreen canvas
298     offscreenCanvas_->CopyHDRConfiguration(*curCanvas_);
299     // copy current canvas properties into offscreen canvas
300     offscreenCanvas_->CopyConfigurationToOffscreenCanvas(*curCanvas_);
301 
302     // backup current canvas and replace with offscreen canvas
303     canvasBackup_ = curCanvas_;
304     curCanvas_ = offscreenCanvas_.get();
305     curCanvas_->SetDisableFilterCache(true);
306     arc_ = std::make_unique<RSAutoCanvasRestore>(curCanvas_, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
307     curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
308     return true;
309 }
310 
FinishOffscreenRender(const Drawing::SamplingOptions & sampling)311 void RSSurfaceRenderNodeDrawable::FinishOffscreenRender(const Drawing::SamplingOptions& sampling)
312 {
313     if (canvasBackup_ == nullptr) {
314         RS_LOGE("RSSurfaceRenderNodeDrawable::FinishOffscreenRender, canvasBackup_ is nullptr");
315         return;
316     }
317     if (offscreenSurface_ == nullptr) {
318         RS_LOGE("RSSurfaceRenderNodeDrawable::FinishOffscreenRender, offscreenSurface_ is nullptr");
319         return;
320     }
321     auto image = offscreenSurface_->GetImageSnapshot();
322     if (image == nullptr) {
323         RS_LOGE("RSSurfaceRenderNodeDrawable::FinishOffscreenRender, Surface::GetImageSnapshot is nullptr");
324         return;
325     }
326     // draw offscreen surface to current canvas
327     Drawing::Brush paint;
328     paint.SetAntiAlias(true);
329     canvasBackup_->AttachBrush(paint);
330     canvasBackup_->DrawImage(*image, 0, 0, sampling);
331     canvasBackup_->DetachBrush();
332     arc_ = nullptr;
333     curCanvas_ = canvasBackup_;
334 }
335 
IsHardwareEnabled()336 bool RSSurfaceRenderNodeDrawable::IsHardwareEnabled()
337 {
338     auto& hardwareDrawables =
339         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
340     for (const auto& [_, drawable] : hardwareDrawables) {
341         if (!drawable || !drawable->GetRenderParams()) {
342             continue;
343         }
344         auto params = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
345         if (!params || !params->GetHardwareEnabled()) {
346             continue;
347         }
348         return true;
349     }
350     return false;
351 }
352 
IsHardwareEnabledTopSurface() const353 bool RSSurfaceRenderNodeDrawable::IsHardwareEnabledTopSurface() const
354 {
355     return surfaceNodeType_ == RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE &&
356         GetName() == "pointer window" && RSSystemProperties::GetHardCursorEnabled();
357 }
358 
PreprocessUnobscuredUEC(RSPaintFilterCanvas & canvas)359 void RSSurfaceRenderNodeDrawable::PreprocessUnobscuredUEC(RSPaintFilterCanvas& canvas)
360 {
361     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
362     if (!surfaceParams) {
363         RS_LOGE("RSSurfaceRenderNodeDrawable::PreprocessUnobscuredUEC params is nullptr");
364         return;
365     }
366     if (!surfaceParams->IsUnobscuredUIExtension()) {
367         return;
368     }
369     canvas.ResetMatrix();
370     auto& unobscuredUECMatrixMap = GetUnobscuredUECMatrixMap();
371     if (unobscuredUECMatrixMap.find(GetId()) == unobscuredUECMatrixMap.end()) {
372         RS_LOGE("PreprocessUnobscuredUEC can't find matrix of cached node in unobscuredMatrixMap");
373         return;
374     }
375     canvas.ConcatMatrix(unobscuredUECMatrixMap.at(GetId()));
376 }
377 
DrawCacheImageForMultiScreenView(RSPaintFilterCanvas & canvas,const RSSurfaceRenderParams & surfaceParams)378 bool RSSurfaceRenderNodeDrawable::DrawCacheImageForMultiScreenView(RSPaintFilterCanvas& canvas,
379     const RSSurfaceRenderParams& surfaceParams)
380 {
381     auto sourceDisplayNodeDrawable =
382         std::static_pointer_cast<RSDisplayRenderNodeDrawable>(
383             surfaceParams.GetSourceDisplayRenderNodeDrawable().lock());
384     if (sourceDisplayNodeDrawable) {
385         auto cacheImgForMultiScreenView = sourceDisplayNodeDrawable->GetCacheImgForMultiScreenView();
386         if (cacheImgForMultiScreenView) {
387             RS_TRACE_NAME_FMT("DrawCacheImageForMultiScreenView with cache id:%llu rect:%s",
388                 surfaceParams.GetId(), surfaceParams.GetRRect().rect_.ToString().c_str());
389             RSUniRenderUtil::ProcessCacheImageForMultiScreenView(canvas, *cacheImgForMultiScreenView,
390                 surfaceParams.GetRRect().rect_);
391         } else {
392             RS_TRACE_NAME_FMT("DrawCacheImageForMultiScreenView without cache id:%llu", surfaceParams.GetId());
393         }
394         return true;
395     }
396     return false;
397 }
398 
OnDraw(Drawing::Canvas & canvas)399 void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
400 {
401     SetDrawSkipType(DrawSkipType::NONE);
402     if (!ShouldPaint()) {
403         SetDrawSkipType(DrawSkipType::SHOULD_NOT_PAINT);
404         RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw %s should not paint", name_.c_str());
405         return;
406     }
407 
408     if (vmaCacheOff_) {
409         Drawing::StaticFactory::SetVmaCacheStatus(false); // render this frame with vma cache off
410     }
411     RECORD_GPU_RESOURCE_DRAWABLE_CALLER(GetId())
412     auto rscanvas = reinterpret_cast<RSPaintFilterCanvas*>(&canvas);
413     if (!rscanvas) {
414         SetDrawSkipType(DrawSkipType::CANVAS_NULL);
415         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw, rscanvas us nullptr");
416         return;
417     }
418     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
419     if (UNLIKELY(!uniParam)) {
420         SetDrawSkipType(DrawSkipType::RENDER_THREAD_PARAMS_NULL);
421         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw uniParam is nullptr");
422         return;
423     }
424     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
425     if (!surfaceParams) {
426         SetDrawSkipType(DrawSkipType::RENDER_PARAMS_NULL);
427         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw params is nullptr");
428         return;
429     }
430     if (surfaceParams->IsUnobscuredUIExtension() && !UIExtensionNeedToDraw()) {
431         RS_LOGE("Current Unobsucred UEC[%{public}s,%{public}" PRIu64 "] needn't to draw",
432             name_.c_str(), surfaceParams->GetId());
433         return;
434     }
435     if (DrawCacheImageForMultiScreenView(*rscanvas, *surfaceParams)) {
436         return;
437     }
438     auto cloneSourceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(
439         surfaceParams->GetCloneSourceDrawable().lock());
440     auto cloneSourceParams = cloneSourceDrawable ? cloneSourceDrawable->GetRenderParams().get() : nullptr;
441     if (cloneSourceParams) {
442         cloneSourceDrawable->OnDraw(*rscanvas);
443         return;
444     }
445     if (DrawCloneNode(*rscanvas, *uniParam, *surfaceParams, false)) {
446         return;
447     }
448     if (surfaceParams->GetSkipDraw()) {
449         SetDrawSkipType(DrawSkipType::SURFACE_PARAMS_SKIP_DRAW);
450         RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw SkipDraw [%s] Id:%" PRIu64 "",
451             name_.c_str(), surfaceParams->GetId());
452         return;
453     }
454     if (CheckIfSurfaceSkipInMirror(*surfaceParams)) {
455         SetDrawSkipType(DrawSkipType::SURFACE_SKIP_IN_MIRROR);
456         RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw surface skipped in mirror name:[%s] id:%" PRIu64,
457             name_.c_str(), surfaceParams->GetId());
458         return;
459     }
460     RS_LOGD("RSSurfaceRenderNodeDrawable ondraw name:%{public}s nodeId:[%{public}" PRIu64 "]", name_.c_str(),
461         surfaceParams->GetId());
462 
463     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
464     if (!renderEngine) {
465         SetDrawSkipType(DrawSkipType::RENDER_ENGINE_NULL);
466         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw renderEngine is nullptr");
467         return;
468     }
469     if (autoCacheEnable_) {
470         nodeCacheType_ = NodeStrategyType::CACHE_NONE;
471     }
472     bool isUiFirstNode = rscanvas->GetIsParallelCanvas();
473     bool disableFilterCache = rscanvas->GetDisableFilterCache();
474     if (!disableFilterCache && !isUiFirstNode && surfaceParams->GetOccludedByFilterCache()) {
475         SetDrawSkipType(DrawSkipType::FILTERCACHE_OCCLUSION_SKIP);
476         RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw filterCache occlusion skip [%s] %sAlpha: %f, "
477             "NodeId:%" PRIu64 "", name_.c_str(), surfaceParams->GetAbsDrawRect().ToString().c_str(),
478             surfaceParams->GetGlobalAlpha(), surfaceParams->GetId());
479         return;
480     }
481     auto specialLayerManager = surfaceParams->GetSpecialLayerMgr();
482     hasSkipCacheLayer_ =
483         (specialLayerManager.Find(SpecialLayerType::SECURITY) && !uniParam->GetSecExemption()) ||
484             specialLayerManager.Find(SpecialLayerType::SKIP);
485     if (hasSkipCacheLayer_ && curDrawingCacheRoot_) {
486         curDrawingCacheRoot_->SetSkipCacheLayer(true);
487     }
488     if (surfaceParams->GetHardCursorStatus()) {
489         SetDrawSkipType(DrawSkipType::HARD_CURSOR_ENAbLED);
490         RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw hardcursor skip SurfaceName:%s", name_.c_str());
491         return;
492     }
493 
494     Drawing::Region curSurfaceDrawRegion = CalculateVisibleDirtyRegion(*uniParam, *surfaceParams, *this, isUiFirstNode);
495 
496     if (!isUiFirstNode) {
497         if (uniParam->IsOpDropped() && surfaceParams->IsVisibleDirtyRegionEmpty(curSurfaceDrawRegion)) {
498             SetDrawSkipType(DrawSkipType::OCCLUSION_SKIP);
499             RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw occlusion skip SurfaceName:%s %sAlpha: %f, NodeId:"
500                 "%" PRIu64 "", name_.c_str(), surfaceParams->GetAbsDrawRect().ToString().c_str(),
501                 surfaceParams->GetGlobalAlpha(), surfaceParams->GetId());
502             return;
503         }
504     }
505     const auto &absDrawRect = surfaceParams->GetAbsDrawRect();
506     // syncDirtyManager_ is not null
507     const RectI& currentFrameDirty = syncDirtyManager_->GetCurrentFrameDirtyRegion();
508     const RectI& mergeHistoryDirty = syncDirtyManager_->GetDirtyRegion();
509     // warning : don't delete this trace or change trace level to optional !!!
510     RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw:[%s] (%d, %d, %d, %d)Alpha: %f, preSub:%d, "
511         "currentFrameDirty (%d, %d, %d, %d), mergeHistoryDirty (%d, %d, %d, %d)", name_.c_str(),
512         absDrawRect.left_, absDrawRect.top_, absDrawRect.width_, absDrawRect.height_, surfaceParams->GetGlobalAlpha(),
513         surfaceParams->GetPreSubHighPriorityType(),
514         currentFrameDirty.left_, currentFrameDirty.top_, currentFrameDirty.width_, currentFrameDirty.height_,
515         mergeHistoryDirty.left_, mergeHistoryDirty.top_, mergeHistoryDirty.width_, mergeHistoryDirty.height_);
516 
517     RS_LOGD("RSSurfaceRenderNodeDrawable::OnDraw node:%{public}" PRIu64 ", name:%{public}s,"
518             "OcclusionVisible:%{public}d Bound:%{public}s",
519         surfaceParams->GetId(), name_.c_str(), surfaceParams->GetOcclusionVisible(),
520         surfaceParams->GetBounds().ToString().c_str());
521 
522     if (RSSystemProperties::GetCacheOptimizeRotateEnable() &&
523         (surfaceParams->GetName().find(WALLPAPER) != std::string::npos)) {
524         auto translate = RSUniRenderThread::Instance().GetWallpaperTranslate();
525         canvas.Translate(-translate.first, -translate.second);
526     }
527 
528     RSUiFirstProcessStateCheckerHelper stateCheckerHelper(
529         surfaceParams->GetFirstLevelNodeId(), surfaceParams->GetUifirstRootNodeId(), nodeId_);
530     if (!RSUiFirstProcessStateCheckerHelper::CheckMatchAndWaitNotify(*surfaceParams)) {
531         SetDrawSkipType(DrawSkipType::CHECK_MATCH_AND_WAIT_NOTIFY_FAIL);
532         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw CheckMatchAndWaitNotify failed");
533         return;
534     }
535 
536     // Regional screen recording does not enable uifirst.
537     bool enableVisiableRect = RSUniRenderThread::Instance().GetEnableVisiableRect();
538     if (!enableVisiableRect) {
539         if (drawWindowCache_.DealWithCachedWindow(this, *rscanvas, *surfaceParams, *uniParam)) {
540             SetDrawSkipType(DrawSkipType::DEAL_WITH_CACHED_WINDOW);
541             return;
542         }
543         if (DealWithUIFirstCache(*rscanvas, *surfaceParams, *uniParam)) {
544             if (GetDrawSkipType() == DrawSkipType::NONE) {
545                 SetDrawSkipType(DrawSkipType::UI_FIRST_CACHE_SKIP);
546             }
547             return;
548         }
549     }
550 
551     auto cacheState = GetCacheSurfaceProcessedStatus();
552     auto useNodeMatchOptimize = cacheState != CacheProcessStatus::WAITING && cacheState != CacheProcessStatus::DOING;
553     if (!RSUiFirstProcessStateCheckerHelper::CheckMatchAndWaitNotify(*surfaceParams, useNodeMatchOptimize)) {
554         SetDrawSkipType(DrawSkipType::CHECK_MATCH_AND_WAIT_NOTIFY_FAIL);
555         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw CheckMatchAndWaitNotify failed");
556         return;
557     }
558 
559     RSRenderNodeSingleDrawableLocker singleLocker(this);
560     if (UNLIKELY(!singleLocker.IsLocked())) {
561         singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
562         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw node %{public}" PRIu64 " onDraw!!!", GetId());
563         if (RSSystemProperties::GetSingleDrawableLockerEnabled()) {
564             SetDrawSkipType(DrawSkipType::MULTI_ACCESS);
565             return;
566         }
567     }
568 
569     TotalProcessedSurfaceCountInc(*rscanvas);
570     std::shared_ptr<Drawing::GPUContext> gpuContext = nullptr;
571     auto realTid = gettid();
572     if (realTid == RSUniRenderThread::Instance().GetTid()) {
573         gpuContext = RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetSharedDrGPUContext();
574     } else {
575         gpuContext = RSSubThreadManager::Instance()->GetGrContextFromSubThread(realTid);
576     }
577     RSTagTracker tagTracker(gpuContext.get(), surfaceParams->GetId(),
578         RSTagTracker::TAGTYPE::TAG_DRAW_SURFACENODE, surfaceParams->GetName());
579 
580     // Draw base pipeline start
581     RSAutoCanvasRestore acr(rscanvas, RSPaintFilterCanvas::SaveType::kAll);
582     bool needOffscreen = (realTid == RSUniRenderThread::Instance().GetTid()) &&
583         surfaceParams->GetNeedOffscreen() && !rscanvas->GetTotalMatrix().IsIdentity() &&
584         surfaceParams->IsAppWindow() && GetName().substr(0, 3) != "SCB" && !IsHardwareEnabled() &&
585         (surfaceParams->GetVisibleRegion().Area() == (surfaceParams->GetOpaqueRegion().Area() +
586         surfaceParams->GetRoundedCornerRegion().Area()));
587     curCanvas_ = rscanvas;
588     if (needOffscreen) {
589         isInRotationFixed_ = false;
590         releaseCount_ = 0;
591         if (!PrepareOffscreenRender()) {
592             needOffscreen = false;
593         }
594     } else {
595         if (offscreenSurface_ != nullptr) {
596             releaseCount_++;
597             if (releaseCount_ == MAX_RELEASE_FRAME) {
598                 std::shared_ptr<Drawing::Surface> hold = offscreenSurface_;
599                 RSUniRenderThread::Instance().PostTask([hold] {});
600                 offscreenSurface_ = nullptr;
601                 releaseCount_ = 0;
602             }
603         }
604     }
605     PreprocessUnobscuredUEC(*curCanvas_);
606     surfaceParams->ApplyAlphaAndMatrixToCanvas(*curCanvas_, !needOffscreen);
607 
608     bool isSelfDrawingSurface = surfaceParams->GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
609         !surfaceParams->IsSpherizeValid() && !surfaceParams->IsAttractionValid();
610     if (isSelfDrawingSurface) {
611         SetSkip(surfaceParams->GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE);
612         // Restore in OnGeneralProcess
613         curCanvas_->Save();
614     }
615 
616     if (surfaceParams->IsMainWindowType()) {
617         RSRenderNodeDrawable::ClearTotalProcessedNodeCount();
618         RSRenderNodeDrawable::ClearProcessedNodeCount();
619         if (!surfaceParams->GetNeedOffscreen()) {
620             curCanvas_->PushDirtyRegion(curSurfaceDrawRegion);
621         }
622     }
623 
624     // disable filter cache when surface global position is enabled
625     bool isDisableFilterCache = curCanvas_->GetDisableFilterCache();
626     curCanvas_->SetDisableFilterCache(isDisableFilterCache || surfaceParams->GetGlobalPositionEnabled());
627     auto parentSurfaceMatrix = RSRenderParams::GetParentSurfaceMatrix();
628     RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
629 
630     // add a blending disable rect op behind floating window, to enable overdraw buffer feature on special gpu.
631     if (surfaceParams->IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()
632         && surfaceParams->IsGpuOverDrawBufferOptimizeNode()) {
633         EnableGpuOverDrawDrawBufferOptimization(*curCanvas_, surfaceParams);
634     }
635     OnGeneralProcess(*curCanvas_, *surfaceParams, *uniParam, isSelfDrawingSurface);
636     if (surfaceParams->GetRSFreezeFlag() && GetCacheImageByCapture() && !isUiFirstNode) {
637         RS_TRACE_NAME("Drawing cachedImage by capture");
638         DrawCachedImage(*curCanvas_, surfaceParams->GetCacheSize());
639     } else {
640         if (GetCacheImageByCapture()) {
641             SetCacheImageByCapture(nullptr);
642         }
643         RS_LOGI_LIMIT(
644             "RSSurfaceRenderNodeDrawable::OnDraw name:%{public}s, the number of total processedNodes: %{public}d",
645             name_.c_str(), RSRenderNodeDrawable::GetTotalProcessedNodeCount());
646     }
647 
648     if (needOffscreen && canvasBackup_) {
649         Drawing::AutoCanvasRestore acrBackUp(*canvasBackup_, true);
650         if (isInRotationFixed_) {
651             canvasBackup_->Clear(Drawing::Color::COLOR_BLACK);
652         }
653         if (surfaceParams->HasSandBox()) {
654             canvasBackup_->SetMatrix(surfaceParams->GetParentSurfaceMatrix());
655             canvasBackup_->ConcatMatrix(surfaceParams->GetMatrix());
656         } else {
657             canvasBackup_->ConcatMatrix(surfaceParams->GetMatrix());
658         }
659         FinishOffscreenRender(
660             Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NONE));
661         RS_LOGD("FinishOffscreenRender %{public}s node type %{public}d", surfaceParams->GetName().c_str(),
662             int(surfaceParams->GetSurfaceNodeType()));
663     }
664 
665     // Draw base pipeline end
666     if (surfaceParams->IsMainWindowType()) {
667         if (!surfaceParams->GetNeedOffscreen()) {
668             curCanvas_->PopDirtyRegion();
669         }
670         int processedNodes = RSRenderNodeDrawable::GetProcessedNodeCount();
671         AcquireFenceTracker::SetContainerNodeNum(processedNodes);
672         RS_TRACE_NAME_FMT("RSUniRenderThread::Render() the number of total ProcessedNodes: %d",
673             RSRenderNodeDrawable::GetTotalProcessedNodeCount());
674         const RSNodeStatsType nodeStats = CreateRSNodeStatsItem(
675             RSRenderNodeDrawable::GetTotalProcessedNodeCount(), GetId(), GetName());
676         RSNodeStats::GetInstance().AddNodeStats(nodeStats);
677     }
678 
679     curCanvas_->SetDisableFilterCache(isDisableFilterCache);
680     RSRenderParams::SetParentSurfaceMatrix(parentSurfaceMatrix);
681     SetUIExtensionNeedToDraw(false);
682 }
683 
CrossDisplaySurfaceDirtyRegionConversion(const RSRenderThreadParams & uniParam,const RSSurfaceRenderParams & surfaceParam,RectI & surfaceDirtyRect) const684 void RSSurfaceRenderNodeDrawable::CrossDisplaySurfaceDirtyRegionConversion(
685     const RSRenderThreadParams& uniParam, const RSSurfaceRenderParams& surfaceParam, RectI& surfaceDirtyRect) const
686 {
687     if (!surfaceParam.IsFirstLevelCrossNode()) {
688         return;
689     }
690     auto displayConversionMatrices = surfaceParam.GetCrossNodeSkipDisplayConversionMatrix();
691     auto curConversionMatrix = displayConversionMatrices.find(uniParam.GetCurrentVisitDisplayDrawableId());
692     if (curConversionMatrix != displayConversionMatrices.end()) {
693         // transfer from the display coordinate system during quickprepare into current display coordinate system.
694         std::shared_ptr<RSObjAbsGeometry> geoPtr = std::make_shared<RSObjAbsGeometry>();
695         surfaceDirtyRect = geoPtr->MapRect(surfaceDirtyRect.ConvertTo<float>(), curConversionMatrix->second);
696     }
697 }
698 
OnCapture(Drawing::Canvas & canvas)699 void RSSurfaceRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
700 {
701     if (!ShouldPaint()) {
702         return;
703     }
704     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
705     if (!surfaceParams) {
706         RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture surfaceParams is nullptr");
707         return;
708     }
709 
710     auto cloneSourceDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(
711         surfaceParams->GetCloneSourceDrawable().lock());
712     auto cloneSourceParams = cloneSourceDrawable ? cloneSourceDrawable->GetRenderParams().get() : nullptr;
713     if (cloneSourceParams) {
714         cloneSourceDrawable->OnCapture(canvas);
715         return;
716     }
717 
718     if (vmaCacheOff_) {
719         Drawing::StaticFactory::SetVmaCacheStatus(false); // render this frame with vma cache off
720     }
721 
722     // HidePrivacyContent is only for UICapture or NoneSystemCalling-WindowCapture
723     bool isHiddenScene = canvas.GetUICapture() ||
724         (RSUniRenderThread::GetCaptureParam().isSingleSurface_ &&
725         !RSUniRenderThread::GetCaptureParam().isSystemCalling_);
726     if ((surfaceNodeType_ == RSSurfaceNodeType::UI_EXTENSION_COMMON_NODE ||
727         surfaceNodeType_ == RSSurfaceNodeType::UI_EXTENSION_SECURE_NODE) &&
728         isHiddenScene && surfaceParams->GetHidePrivacyContent()) {
729         RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture surfacenode nodeId:[%{public}" PRIu64
730                 "] is not allowed to be captured", nodeId_);
731         return;
732     }
733 
734     RSUiFirstProcessStateCheckerHelper stateCheckerHelper(
735         surfaceParams->GetFirstLevelNodeId(), surfaceParams->GetUifirstRootNodeId(), nodeId_);
736     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
737     if (UNLIKELY(!uniParam)) {
738         RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture uniParam is nullptr");
739         return;
740     }
741 
742     auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
743     if (!rscanvas) {
744         RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture, rscanvas us nullptr");
745         return;
746     }
747 
748     if (DrawCloneNode(*rscanvas, *uniParam, *surfaceParams, true)) {
749         return;
750     }
751 
752     rscanvas->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
753     // process white list
754     auto whiteList = RSUniRenderThread::Instance().GetWhiteList();
755     SetVirtualScreenWhiteListRootId(whiteList, surfaceParams->GetLeashPersistentId());
756 
757     if (RSSystemProperties::GetCacheOptimizeRotateEnable() &&
758         surfaceParams->GetName().find(WALLPAPER) != std::string::npos) {
759         auto translate = RSUniRenderThread::Instance().GetWallpaperTranslate();
760         canvas.Translate(-translate.first, -translate.second);
761     }
762 
763     if (CheckIfSurfaceSkipInMirror(*surfaceParams)) {
764         SetDrawSkipType(DrawSkipType::SURFACE_SKIP_IN_MIRROR);
765         RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnCapture surface skipped in mirror name:[%s] id:%" PRIu64,
766             name_.c_str(), surfaceParams->GetId());
767         return;
768     }
769 
770     if (surfaceParams->GetHardCursorStatus() &&
771         (uniParam->HasPhysicMirror() || RSUniRenderThread::GetCaptureParam().isSnapshot_)) {
772         SetDrawSkipType(DrawSkipType::HARD_CURSOR_ENAbLED);
773         RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnCapture hardcursor skip SurfaceName:%s", name_.c_str());
774         return;
775     }
776 
777     if (uniParam->IsOcclusionEnabled() && surfaceParams->IsMainWindowType() &&
778         surfaceParams->GetVisibleRegionInVirtual().IsEmpty() && whiteList.empty() &&
779         UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_)) {
780         RS_TRACE_NAME("RSSurfaceRenderNodeDrawable::OnCapture occlusion skip :[" + name_ + "] " +
781             surfaceParams->GetAbsDrawRect().ToString());
782         return;
783     }
784 
785     RS_TRACE_NAME("RSSurfaceRenderNodeDrawable::OnCapture:[" + name_ + "] " +
786         surfaceParams->GetAbsDrawRect().ToString() + "Alpha: " +
787         std::to_string(surfaceParams->GetGlobalAlpha()));
788     if (DrawCacheImageForMultiScreenView(*rscanvas, *surfaceParams)) {
789         return;
790     }
791     RSAutoCanvasRestore acr(rscanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
792 
793     // First node don't need to concat matrix for application
794     if (RSUniRenderThread::GetCaptureParam().isFirstNode_) {
795         // Planning: If node is a sandbox.
796         rscanvas->MultiplyAlpha(surfaceParams->GetAlpha());
797         RSUniRenderThread::GetCaptureParam().isFirstNode_ = false;
798     } else {
799         PreprocessUnobscuredUEC(*rscanvas);
800         surfaceParams->ApplyAlphaAndMatrixToCanvas(*rscanvas);
801     }
802 
803     CaptureSurface(*rscanvas, *surfaceParams);
804     ResetVirtualScreenWhiteListRootId(surfaceParams->GetLeashPersistentId());
805 }
806 
CheckIfSurfaceSkipInMirror(const RSSurfaceRenderParams & surfaceParams)807 bool RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror(const RSSurfaceRenderParams& surfaceParams)
808 {
809     const auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
810     if (uniParam && !uniParam->IsMirrorScreen()) {
811         return false;
812     }
813     // Check black list.
814     const auto& blackList = RSUniRenderThread::Instance().GetBlackList();
815     if (surfaceParams.IsLeashWindow() && blackList.find(surfaceParams.GetLeashPersistentId()) != blackList.end()) {
816         RS_LOGD("RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror: \
817             (LeashPersistentId:[%{public}" PRIu64 "]) is in black list", surfaceParams.GetLeashPersistentId());
818         return true;
819     }
820     if (blackList.find(surfaceParams.GetId()) != blackList.end()) {
821         RS_LOGD("RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror: \
822             (surfaceParamsId:[%{public}" PRIu64 "]) is in black list", surfaceParams.GetId());
823         return true;
824     }
825     // Check white list.
826     const auto& whiteList = RSUniRenderThread::Instance().GetWhiteList();
827     if (!whiteList.empty() && RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ == INVALID_NODEID) {
828         RS_LOGD("RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror: \
829             (id:[%{public}" PRIu64 "]) isn't in white list", surfaceParams.GetId());
830         return true;
831     }
832 
833     return false;
834 }
835 
SetVirtualScreenWhiteListRootId(const std::unordered_set<NodeId> & whiteList,NodeId id)836 void RSSurfaceRenderNodeDrawable::SetVirtualScreenWhiteListRootId(
837     const std::unordered_set<NodeId>& whiteList, NodeId id)
838 {
839     if (whiteList.find(id) == whiteList.end()) {
840         return;
841     }
842     // don't update if it's ancestor has already set
843     if (RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ != INVALID_NODEID) {
844         return;
845     }
846     RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ = id;
847 }
848 
ResetVirtualScreenWhiteListRootId(NodeId id)849 void RSSurfaceRenderNodeDrawable::ResetVirtualScreenWhiteListRootId(NodeId id)
850 {
851     // only reset by the node which sets the flag
852     if (RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ == id) {
853         RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ = INVALID_NODEID;
854     }
855 }
856 
CaptureSurface(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)857 void RSSurfaceRenderNodeDrawable::CaptureSurface(RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams)
858 {
859     auto& uniParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
860     if (UNLIKELY(!uniParams)) {
861         RS_LOGE("RSSurfaceRenderNodeDrawable::CaptureSurface uniParams is nullptr");
862         return;
863     }
864     const auto& specialLayerManager = surfaceParams.GetSpecialLayerMgr();
865     bool isSecLayersNotExempted = specialLayerManager.Find(SpecialLayerType::SECURITY) && !uniParams->GetSecExemption();
866     bool needSkipDrawWhite =
867         RSUniRenderThread::GetCaptureParam().isNeedBlur_ || RSUniRenderThread::GetCaptureParam().isSelfCapture_;
868     // Draw White
869     if (RSUniRenderThread::GetCaptureParam().isSingleSurface_ &&
870         (UNLIKELY(isSecLayersNotExempted && !needSkipDrawWhite) || specialLayerManager.Find(SpecialLayerType::SKIP))) {
871         RS_LOGD("RSSurfaceRenderNodeDrawable::CaptureSurface: "
872                 "process RSSurfaceRenderNode(id:[%{public}" PRIu64 "] name:[%{public}s])"
873                 "draw white with security or skip layer for SingleSurface, isNeedBlur:[%{public}s], "
874                 "isSelfCapture:[%{public}s]",
875             surfaceParams.GetId(), name_.c_str(), RSUniRenderThread::GetCaptureParam().isNeedBlur_ ? "true" : "false",
876             RSUniRenderThread::GetCaptureParam().isSelfCapture_ ? "true" : "false");
877         RS_TRACE_NAME_FMT(
878             "CaptureSurface: RSSurfaceRenderNode(id:[%" PRIu64 "] name:[%s])"
879             "draw white with security or skip layer for SingleSurface, isNeedBlur: [%s], isSelfCapture:[%s]",
880             surfaceParams.GetId(), name_.c_str(), RSUniRenderThread::GetCaptureParam().isNeedBlur_ ? "true" : "false",
881             RSUniRenderThread::GetCaptureParam().isSelfCapture_ ? "true" : "false");
882 
883         Drawing::Brush rectBrush;
884         rectBrush.SetColor(Drawing::Color::COLOR_WHITE);
885         canvas.AttachBrush(rectBrush);
886         canvas.DrawRect(Drawing::Rect(
887             0, 0, surfaceParams.GetBounds().GetWidth(), surfaceParams.GetBounds().GetHeight()));
888         canvas.DetachBrush();
889         return;
890     }
891 
892     // Draw Black
893     bool isScreenshot = RSUniRenderThread::GetCaptureParam().isSnapshot_ &&
894         !RSUniRenderThread::GetCaptureParam().isSingleSurface_;
895     if (specialLayerManager.Find(SpecialLayerType::PROTECTED) || UNLIKELY(isSecLayersNotExempted && isScreenshot)) {
896         RS_LOGD("RSSurfaceRenderNodeDrawable::CaptureSurface: "
897             "process RSSurfaceRenderNode(id:[%{public}" PRIu64 "] name:[%{public}s])"
898             "draw black with protected layer or screenshot security layer", surfaceParams.GetId(), name_.c_str());
899         RS_TRACE_NAME_FMT("CaptureSurface: RSSurfaceRenderNode(id:[%" PRIu64 "] name:[%s])"
900             "draw black with protected layer or screenshot security layer", surfaceParams.GetId(), name_.c_str());
901 
902         Drawing::Brush rectBrush;
903         rectBrush.SetColor(Drawing::Color::COLOR_BLACK);
904         canvas.AttachBrush(rectBrush);
905         canvas.DrawRect(Drawing::Rect(0, 0, surfaceParams.GetBounds().GetWidth(),
906             surfaceParams.GetBounds().GetHeight()));
907         canvas.DetachBrush();
908         return;
909     }
910 
911     // Skip Drawing
912     auto isSnapshotSkipLayer =
913         RSUniRenderThread::GetCaptureParam().isSnapshot_ && specialLayerManager.Find(SpecialLayerType::SNAPSHOT_SKIP);
914     if ((!RSUniRenderThread::GetCaptureParam().isSingleSurface_ && specialLayerManager.Find(SpecialLayerType::SKIP)) ||
915         isSnapshotSkipLayer) {
916         RS_LOGD("RSSurfaceRenderNodeDrawable::CaptureSurface: "
917             "process RSSurfaceRenderNode(id:[%{public}" PRIu64 "] name:[%{public}s])"
918             "skip layer or snapshotskip layer", surfaceParams.GetId(), name_.c_str());
919         RS_TRACE_NAME_FMT("CaptureSurface: RSSurfaceRenderNode(id:[%" PRIu64 "] name:[%s])"
920             "skip layer or snapshotskip layer", surfaceParams.GetId(), name_.c_str());
921         return;
922     }
923 
924     RS_LOGD("HDRService hasHdrPresent_: %{public}d, GetId: %{public}" PRIu64 "",
925         surfaceParams.GetHDRPresent(), surfaceParams.GetId());
926     bool hasHidePrivacyContent = surfaceParams.HasPrivacyContentLayer() &&
927         RSUniRenderThread::GetCaptureParam().isSingleSurface_ &&
928         !RSUniRenderThread::GetCaptureParam().isSystemCalling_;
929     bool enableVisiableRect = RSUniRenderThread::Instance().GetEnableVisiableRect();
930     if (!(specialLayerManager.Find(HAS_GENERAL_SPECIAL) || surfaceParams.GetHDRPresent() || hasHidePrivacyContent ||
931         enableVisiableRect)) {
932         if (drawWindowCache_.DealWithCachedWindow(this, canvas, surfaceParams, *uniParams)) {
933             if (RSUniRenderThread::GetCaptureParam().isSingleSurface_) {
934                 RS_LOGI("%{public}s DealWithCachedWindow", __func__);
935             }
936             return;
937         }
938         if (DealWithUIFirstCache(canvas, surfaceParams, *uniParams)) {
939             if (RSUniRenderThread::GetCaptureParam().isSingleSurface_) {
940                 RS_LOGI("%{public}s DealWithUIFirstCache", __func__);
941             }
942             return;
943         }
944     }
945 
946     if (!RSUiFirstProcessStateCheckerHelper::CheckMatchAndWaitNotify(surfaceParams, false)) {
947         RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture CheckMatchAndWaitNotify failed");
948         return;
949     }
950 
951     RSRenderNodeSingleDrawableLocker singleLocker(this);
952     if (UNLIKELY(!singleLocker.IsLocked())) {
953         singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
954         RS_LOGE("RSSurfaceRenderNodeDrawable::CaptureSurface node %{public}" PRIu64 " onDraw!!!", GetId());
955         if (RSSystemProperties::GetSingleDrawableLockerEnabled()) {
956             return;
957         }
958     }
959 
960     bool isSelfDrawingSurface = surfaceParams.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
961         !surfaceParams.IsSpherizeValid() && !surfaceParams.IsAttractionValid();
962     if (isSelfDrawingSurface) {
963         SetSkip(surfaceParams.GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE);
964         // Restore in OnGeneralProcess
965         canvas.Save();
966     }
967 
968     auto parentSurfaceMatrix = RSRenderParams::GetParentSurfaceMatrix();
969     RSRenderParams::SetParentSurfaceMatrix(canvas.GetTotalMatrix());
970 
971     OnGeneralProcess(canvas, surfaceParams, *uniParams, isSelfDrawingSurface);
972 
973     RSRenderParams::SetParentSurfaceMatrix(parentSurfaceMatrix);
974 }
975 
GetAncestorDisplayColorGamut(const RSSurfaceRenderParams & surfaceParams)976 GraphicColorGamut RSSurfaceRenderNodeDrawable::GetAncestorDisplayColorGamut(const RSSurfaceRenderParams& surfaceParams)
977 {
978     GraphicColorGamut targetColorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
979     auto ancestorDrawable = surfaceParams.GetAncestorDisplayDrawable().lock();
980     if (!ancestorDrawable) {
981         RS_LOGE("ancestorDrawable return nullptr");
982         return targetColorGamut;
983     }
984     auto ancestorDisplayDrawable = std::static_pointer_cast<RSDisplayRenderNodeDrawable>(ancestorDrawable);
985     if (!ancestorDisplayDrawable) {
986         RS_LOGE("ancestorDisplayDrawable return nullptr");
987         return targetColorGamut;
988     }
989     auto& ancestorParam = ancestorDrawable->GetRenderParams();
990     if (!ancestorParam) {
991         RS_LOGE("ancestorParam return nullptr");
992         return targetColorGamut;
993     }
994 
995     auto renderParams = static_cast<RSDisplayRenderParams*>(ancestorParam.get());
996     targetColorGamut = renderParams->GetNewColorSpace();
997     RS_LOGD("params.targetColorGamut is %{public}d in DealWithSelfDrawingNodeBuffer", targetColorGamut);
998     return targetColorGamut;
999 }
1000 
DealWithSelfDrawingNodeBuffer(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)1001 void RSSurfaceRenderNodeDrawable::DealWithSelfDrawingNodeBuffer(
1002     RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams)
1003 {
1004     if ((surfaceParams.GetHardwareEnabled() || surfaceParams.GetHardCursorStatus()) &&
1005         RSUniRenderThread::IsExpandScreenMode()) {
1006         if (!IsHardwareEnabledTopSurface() && !surfaceParams.IsLayerTop()) {
1007             ClipHoleForSelfDrawingNode(canvas, surfaceParams);
1008         }
1009         if (surfaceParams.GetNeedMakeImage()) {
1010             RS_TRACE_NAME_FMT("DealWithSelfDrawingNodeBuffer Id:%" PRIu64 "", surfaceParams.GetId());
1011             RSAutoCanvasRestore arc(&canvas);
1012             surfaceParams.SetGlobalAlpha(1.0f);
1013             pid_t threadId = gettid();
1014             auto params = RSUniRenderUtil::CreateBufferDrawParam(*this, false, threadId);
1015 
1016             Drawing::Matrix rotateMatrix = canvas.GetTotalMatrix();
1017             rotateMatrix.PreConcat(params.matrix);
1018 
1019             auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1020             if (!renderEngine) {
1021                 RS_LOGE("DealWithSelfDrawingNodeBuffer renderEngine is nullptr");
1022                 return;
1023             }
1024             VideoInfo videoInfo;
1025             auto surfaceNodeImage = renderEngine->CreateImageFromBuffer(canvas, params, videoInfo);
1026 
1027             SurfaceNodeInfo surfaceNodeInfo = {surfaceNodeImage, rotateMatrix, params.srcRect, params.dstRect};
1028             HveFilter::GetHveFilter().PushSurfaceNodeInfo(surfaceNodeInfo);
1029         }
1030         return;
1031     }
1032     if (surfaceParams.GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
1033         RS_LOGD("protected layer cannot draw in non-protected context.");
1034         return;
1035     }
1036     if (surfaceParams.IsInFixedRotation()) {
1037         isInRotationFixed_ = true;
1038         DrawBufferForRotationFixed(canvas, surfaceParams);
1039         return;
1040     }
1041 
1042     RSAutoCanvasRestore arc(&canvas);
1043     surfaceParams.SetGlobalAlpha(1.0f);
1044     pid_t threadId = gettid();
1045     auto params = RSUniRenderUtil::CreateBufferDrawParam(*this, false, threadId);
1046     params.targetColorGamut = GetAncestorDisplayColorGamut(surfaceParams);
1047     if (threadId == RSUniRenderThread::Instance().GetTid()) {
1048         params.screenId = RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetScreenInfo().id;
1049     }
1050 #ifdef USE_VIDEO_PROCESSING_ENGINE
1051     params.sdrNits = surfaceParams.GetSdrNit();
1052     params.tmoNits = surfaceParams.GetDisplayNit();
1053     params.displayNits = params.tmoNits / std::pow(surfaceParams.GetBrightnessRatio(), GAMMA2_2); // gamma 2.2
1054     // color temperature
1055     params.layerLinearMatrix = surfaceParams.GetLayerLinearMatrix();
1056     params.hasMetadata = surfaceParams.GetSdrHasMetadata();
1057 #endif
1058 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1059     if (IsHardwareEnabledTopSurface() && RSUniRenderThread::Instance().GetRSRenderThreadParams()->HasMirrorDisplay()) {
1060         RSMagicPointerRenderManager::GetInstance().SetCacheImgForPointer(canvas.GetSurface()->GetImageSnapshot());
1061     }
1062 #endif
1063 
1064     DrawSelfDrawingNodeBuffer(canvas, surfaceParams, params);
1065 }
1066 
RecordTimestamp(NodeId id,uint32_t seqNum)1067 bool RSSurfaceRenderNodeDrawable::RecordTimestamp(NodeId id, uint32_t seqNum)
1068 {
1069     uint64_t currentTime = static_cast<uint64_t>(
1070         std::chrono::duration_cast<std::chrono::nanoseconds>(
1071         std::chrono::steady_clock::now().time_since_epoch()).count());
1072     auto& surfaceFpsManager = RSSurfaceFpsManager::GetInstance();
1073     return surfaceFpsManager.RecordPresentTime(id, currentTime, seqNum);
1074 }
1075 
DrawCloneNode(RSPaintFilterCanvas & canvas,RSRenderThreadParams & uniParam,RSSurfaceRenderParams & surfaceParams,bool isCapture)1076 bool RSSurfaceRenderNodeDrawable::DrawCloneNode(RSPaintFilterCanvas& canvas,
1077                                                 RSRenderThreadParams& uniParam,
1078                                                 RSSurfaceRenderParams& surfaceParams, bool isCapture)
1079 {
1080     if (!surfaceParams.IsCloneNode()) {
1081         return false;
1082     }
1083     auto clonedNodeRenderDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(
1084         surfaceParams.GetClonedNodeRenderDrawable().lock());
1085     if (clonedNodeRenderDrawable == nullptr) {
1086         RS_LOGD("RSSurfaceRenderNodeDrawable::DrawCloneNode clonedNodeRenderDrawable is null");
1087         return false;
1088     }
1089     if (!surfaceParams.IsClonedNodeOnTheTree()) {
1090         RS_LOGI("RSSurfaceRenderNodeDrawable::DrawCloneNode clonedNode of %{public}s isn't on the tree",
1091             name_.c_str());
1092         clonedNodeRenderDrawable->drawWindowCache_.ClearCache();
1093         return false;
1094     }
1095     RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::DrawCloneNode Draw cloneNode %s", name_.c_str());
1096     bool isOpDropped = uniParam.IsOpDropped();
1097     uniParam.SetOpDropped(false);
1098     RSAutoCanvasRestore acr(&canvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
1099     canvas.MultiplyAlpha(surfaceParams.GetAlpha());
1100     isCapture ? clonedNodeRenderDrawable->OnCapture(canvas) : clonedNodeRenderDrawable->OnDraw(canvas);
1101     uniParam.SetOpDropped(isOpDropped);
1102     clonedNodeRenderDrawable->drawWindowCache_.ClearCache();
1103     return true;
1104 }
1105 
ClipHoleForSelfDrawingNode(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)1106 void RSSurfaceRenderNodeDrawable::ClipHoleForSelfDrawingNode(RSPaintFilterCanvas& canvas,
1107     RSSurfaceRenderParams& surfaceParams)
1108 {
1109     if (surfaceParams.GetForceDisableClipHoleForDRM()) {
1110         RS_LOGD("DMA buffer avoid clippingHole during Attraction effect");
1111         RS_OPTIONAL_TRACE_NAME_FMT("DMA buffer avoid clippingHole during Attraction effect [%s] ", name_.c_str());
1112         return;
1113     }
1114     RSAutoCanvasRestore arc(&canvas);
1115     auto bounds = surfaceParams.GetBounds();
1116     canvas.ClipRect({std::round(bounds.GetLeft()), std::round(bounds.GetTop()),
1117         std::round(bounds.GetRight()), std::round(bounds.GetBottom())});
1118     canvas.Clear(Drawing::Color::COLOR_TRANSPARENT);
1119     if (RSSystemProperties::GetDebugTraceEnabled()) {
1120         Drawing::RectF absRect;
1121         canvas.GetTotalMatrix().MapRect(absRect, bounds);
1122         RS_TRACE_NAME_FMT("hwc debug: clipHole: [%f,%f,%f,%f], absRect: [%s]", bounds.GetLeft(), bounds.GetTop(),
1123             bounds.GetRight(), bounds.GetBottom(), absRect.ToString().c_str());
1124     }
1125 }
1126 
DrawBufferForRotationFixed(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)1127 void RSSurfaceRenderNodeDrawable::DrawBufferForRotationFixed(RSPaintFilterCanvas& canvas,
1128     RSSurfaceRenderParams& surfaceParams)
1129 {
1130     ClipHoleForSelfDrawingNode(canvas, surfaceParams);
1131 
1132     Drawing::Brush brush;
1133     brush.SetBlendMode(Drawing::BlendMode::DST_OVER);
1134     Drawing::SaveLayerOps layerOps(nullptr, &brush);
1135     canvas.SaveLayer(layerOps);
1136 
1137     Drawing::Matrix inverse;
1138     if (!(surfaceParams.GetLayerInfo().matrix.Invert(inverse))) {
1139         RS_LOGE("DrawBufferForRotationFixed failed to get invert matrix");
1140     }
1141     canvas.ConcatMatrix(inverse);
1142     auto params = RSUniRenderUtil::CreateBufferDrawParamForRotationFixed(*this, surfaceParams);
1143     RSUniRenderThread::Instance().GetRenderEngine()->DrawSurfaceNodeWithParams(canvas, *this, params);
1144     canvas.Restore();
1145 }
1146 
DrawSelfDrawingNodeBuffer(RSPaintFilterCanvas & canvas,const RSSurfaceRenderParams & surfaceParams,BufferDrawParam & params)1147 void RSSurfaceRenderNodeDrawable::DrawSelfDrawingNodeBuffer(
1148     RSPaintFilterCanvas& canvas, const RSSurfaceRenderParams& surfaceParams, BufferDrawParam& params)
1149 {
1150     if (params.buffer == nullptr) {
1151         RS_LOGE("RSSurfaceRenderNodeDrawable::DrawSelfDrawingNodeBuffer params.buffer is nullptr");
1152     } else {
1153         RecordTimestamp(surfaceParams.GetId(), params.buffer->GetSeqNum());
1154     }
1155     auto bgColor = surfaceParams.GetBackgroundColor();
1156     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1157     if ((surfaceParams.GetSelfDrawingNodeType() != SelfDrawingNodeType::VIDEO) &&
1158         (bgColor != RgbPalette::Transparent())) {
1159         Drawing::Brush brush;
1160         brush.SetColor(Drawing::Color(bgColor.AsArgbInt()));
1161         if (HasCornerRadius(surfaceParams)) {
1162             auto bounds = RSPropertiesPainter::Rect2DrawingRect({ 0, 0,
1163                 std::round(surfaceParams.GetBounds().GetWidth()), std::round(surfaceParams.GetBounds().GetHeight()) });
1164             Drawing::SaveLayerOps layerOps(&bounds, nullptr);
1165             canvas.SaveLayer(layerOps);
1166             canvas.AttachBrush(brush);
1167             canvas.DrawRoundRect(RSPropertiesPainter::RRect2DrawingRRect(surfaceParams.GetRRect()));
1168             canvas.DetachBrush();
1169             renderEngine->DrawSurfaceNodeWithParams(canvas, *this, params);
1170             canvas.Restore();
1171         } else {
1172             canvas.AttachBrush(brush);
1173             canvas.DrawRect(surfaceParams.GetBounds());
1174             canvas.DetachBrush();
1175             renderEngine->DrawSurfaceNodeWithParams(canvas, *this, params);
1176         }
1177     } else {
1178         renderEngine->DrawSurfaceNodeWithParams(canvas, *this, params);
1179     }
1180 }
1181 
HasCornerRadius(const RSSurfaceRenderParams & surfaceParams) const1182 bool RSSurfaceRenderNodeDrawable::HasCornerRadius(const RSSurfaceRenderParams& surfaceParams) const
1183 {
1184     auto rrect = surfaceParams.GetRRect();
1185     for (auto index = 0; index < CORNER_SIZE; ++index) {
1186         if (!ROSEN_EQ(rrect.radius_[index].x_, 0.f) || !ROSEN_EQ(rrect.radius_[index].y_, 0.f)) {
1187             return true;
1188         }
1189     }
1190     return false;
1191 }
1192 
DealWithUIFirstCache(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams,RSRenderThreadParams & uniParams)1193 bool RSSurfaceRenderNodeDrawable::DealWithUIFirstCache(
1194     RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams, RSRenderThreadParams& uniParams)
1195 {
1196     auto enableType = surfaceParams.GetUifirstNodeEnableParam();
1197     auto cacheState = GetCacheSurfaceProcessedStatus();
1198     if ((!RSUniRenderThread::GetCaptureParam().isSnapshot_ && enableType == MultiThreadCacheType::NONE &&
1199         // WAITING may change to DOING in subThread at any time
1200         cacheState != CacheProcessStatus::WAITING && cacheState != CacheProcessStatus::DOING) ||
1201         (RSUniRenderThread::GetCaptureParam().isSnapshot_ && !HasCachedTexture())) {
1202         return false;
1203     }
1204     if (RSUniRenderThread::GetCaptureParam().isSnapshot_) {
1205         RS_LOGI("%{public}s name:%{public}s surfaceCount:%{public}d nodeCount:%{public}d alpha:%{public}f",
1206             __func__, GetName().c_str(), cacheCompletedSurfaceInfo_.processedSurfaceCount,
1207             cacheCompletedSurfaceInfo_.processedNodeCount, cacheCompletedSurfaceInfo_.alpha);
1208     }
1209     RS_TRACE_NAME_FMT("DrawUIFirstCache [%s] %" PRIu64 ", type %d", name_.c_str(), surfaceParams.GetId(), enableType);
1210     RSUifirstManager::Instance().AddReuseNode(surfaceParams.GetId());
1211     Drawing::Rect bounds = GetRenderParams() ? GetRenderParams()->GetBounds() : Drawing::Rect(0, 0, 0, 0);
1212     RSAutoCanvasRestore acr(&canvas);
1213     // Alpha and matrix have been applied in func CaptureSurface
1214     if (!RSUniRenderThread::GetCaptureParam().isSnapshot_ && !RSUniRenderThread::GetCaptureParam().isMirror_) {
1215         canvas.MultiplyAlpha(surfaceParams.GetAlpha());
1216         canvas.ConcatMatrix(surfaceParams.GetMatrix());
1217     }
1218     // This branch is entered only when the conditions for executing the DrawUIFirstCache function are met.
1219     if (surfaceParams.GetGlobalPositionEnabled() &&
1220         surfaceParams.GetUifirstUseStarting() == INVALID_NODEID) {
1221         auto matrix = surfaceParams.GetTotalMatrix();
1222         matrix.Translate(-offsetX_, -offsetY_);
1223         canvas.ConcatMatrix(matrix);
1224         RS_LOGD("RSSurfaceRenderNodeDrawable::DealWithUIFirstCache Translate screenId=[%{public}" PRIu64 "] "
1225             "offsetX=%{public}d offsetY=%{public}d", curDisplayScreenId_, offsetX_, offsetY_);
1226     }
1227 
1228     auto stencilVal = surfaceParams.GetStencilVal();
1229     if (surfaceParams.IsLeashWindow()) {
1230         DrawLeashWindowBackground(canvas, bounds,
1231             uniParams.IsStencilPixelOcclusionCullingEnabled(), stencilVal);
1232     } else {
1233         DrawBackground(canvas, bounds);
1234     }
1235     canvas.SetStencilVal(stencilVal);
1236     bool drawCacheSuccess = true;
1237     if (surfaceParams.GetUifirstUseStarting() != INVALID_NODEID) {
1238         drawCacheSuccess = DrawUIFirstCacheWithStarting(canvas, surfaceParams.GetUifirstUseStarting());
1239     } else {
1240         bool canSkipFirstWait = (enableType == MultiThreadCacheType::ARKTS_CARD) &&
1241             uniParams.GetUIFirstCurrentFrameCanSkipFirstWait();
1242         drawCacheSuccess = DrawUIFirstCache(canvas, canSkipFirstWait);
1243     }
1244     canvas.SetStencilVal(Drawing::Canvas::INVALID_STENCIL_VAL);
1245     if (!drawCacheSuccess) {
1246         SetDrawSkipType(DrawSkipType::UI_FIRST_CACHE_FAIL);
1247         RS_TRACE_NAME_FMT("[%s] reuse failed!", name_.c_str());
1248         RS_LOGI("uifirst %{public}s drawcache failed! id:%{public}" PRIu64, name_.c_str(), nodeId_);
1249     }
1250     DrawForeground(canvas, bounds);
1251     DrawWatermark(canvas, surfaceParams);
1252     if (uniParams.GetUIFirstDebugEnabled()) {
1253         DrawUIFirstDfx(canvas, enableType, surfaceParams, drawCacheSuccess);
1254     }
1255     return true;
1256 }
1257 
DrawUIFirstDfx(RSPaintFilterCanvas & canvas,MultiThreadCacheType enableType,RSSurfaceRenderParams & surfaceParams,bool drawCacheSuccess)1258 void RSSurfaceRenderNodeDrawable::DrawUIFirstDfx(RSPaintFilterCanvas& canvas, MultiThreadCacheType enableType,
1259     RSSurfaceRenderParams& surfaceParams, bool drawCacheSuccess)
1260 {
1261     auto sizeDebug = surfaceParams.GetCacheSize();
1262     Drawing::Brush rectBrush;
1263     if (drawCacheSuccess) {
1264         if (enableType == MultiThreadCacheType::ARKTS_CARD) {
1265             // rgba: Alpha 128, blue 128
1266             rectBrush.SetColor(Drawing::Color(0, 0, 128, 128));
1267         } else {
1268             // rgba: Alpha 128, green 128, blue 128
1269             rectBrush.SetColor(Drawing::Color(0, 128, 128, 128));
1270         }
1271     } else {
1272         // rgba: Alpha 128, red 128
1273         rectBrush.SetColor(Drawing::Color(128, 0, 0, 128));
1274     }
1275     canvas.AttachBrush(rectBrush);
1276     canvas.DrawRect(Drawing::Rect(0, 0, sizeDebug.x_, sizeDebug.y_));
1277     canvas.DetachBrush();
1278 }
1279 
EnableGpuOverDrawDrawBufferOptimization(Drawing::Canvas & canvas,RSSurfaceRenderParams * surfaceParams)1280 void RSSurfaceRenderNodeDrawable::EnableGpuOverDrawDrawBufferOptimization(Drawing::Canvas& canvas,
1281     RSSurfaceRenderParams* surfaceParams)
1282 {
1283     const Vector4f& radius = surfaceParams->GetOverDrawBufferNodeCornerRadius();
1284     if (radius.IsZero()) {
1285         return;
1286     }
1287     RS_OPTIONAL_TRACE_NAME_FMT("EnableGpuOverDrawDrawBufferOptimization Id:%" PRIu64 "", surfaceParams->GetId());
1288     const Drawing::Rect& bounds = surfaceParams->GetFrameRect();
1289     Drawing::Brush brush;
1290     // must set src blend mode, so overdraw buffer feature can enabled.
1291     brush.SetBlendMode(Drawing::BlendMode::SRC);
1292     // cause the rect will be covered by the child background node, so we just add a white rect
1293     brush.SetColor(Drawing::Color::COLOR_WHITE);
1294     canvas.AttachBrush(brush);
1295     Drawing::AutoCanvasRestore arc(canvas, true);
1296     canvas.Translate(radius.x_, radius.y_);
1297     canvas.DrawRect(Drawing::Rect {0, 0, bounds.GetWidth() - 2 * radius.x_, bounds.GetHeight() - 2 * radius.y_});
1298     canvas.DetachBrush();
1299 }
1300 
BufferFormatNeedUpdate(std::shared_ptr<Drawing::Surface> cacheSurface,bool isNeedFP16)1301 bool RSSurfaceRenderNodeDrawable::BufferFormatNeedUpdate(std::shared_ptr<Drawing::Surface> cacheSurface,
1302     bool isNeedFP16)
1303 {
1304     bool bufferFormatNeedUpdate = cacheSurface ? isNeedFP16 &&
1305         cacheSurface->GetImageInfo().GetColorType() != Drawing::ColorType::COLORTYPE_RGBA_F16 : false;
1306     RS_LOGD("RSSurfaceRenderNodeDrawable::BufferFormatNeedUpdate: %{public}d", bufferFormatNeedUpdate);
1307     return bufferFormatNeedUpdate;
1308 }
1309 
GetVisibleDirtyRegion() const1310 const Occlusion::Region& RSSurfaceRenderNodeDrawable::GetVisibleDirtyRegion() const
1311 {
1312     return visibleDirtyRegion_;
1313 }
1314 
SetVisibleDirtyRegion(const Occlusion::Region & region)1315 void RSSurfaceRenderNodeDrawable::SetVisibleDirtyRegion(const Occlusion::Region& region)
1316 {
1317     visibleDirtyRegion_ = region;
1318 }
1319 
SetAlignedVisibleDirtyRegion(const Occlusion::Region & alignedRegion)1320 void RSSurfaceRenderNodeDrawable::SetAlignedVisibleDirtyRegion(const Occlusion::Region& alignedRegion)
1321 {
1322     alignedVisibleDirtyRegion_ = alignedRegion;
1323 }
1324 
SetGlobalDirtyRegion(Occlusion::Region region)1325 void RSSurfaceRenderNodeDrawable::SetGlobalDirtyRegion(Occlusion::Region region)
1326 {
1327     globalDirtyRegion_ = region;
1328 }
1329 
GetGlobalDirtyRegion() const1330 const Occlusion::Region& RSSurfaceRenderNodeDrawable::GetGlobalDirtyRegion() const
1331 {
1332     return globalDirtyRegion_;
1333 }
1334 
SetDirtyRegionAlignedEnable(bool enable)1335 void RSSurfaceRenderNodeDrawable::SetDirtyRegionAlignedEnable(bool enable)
1336 {
1337     isDirtyRegionAlignedEnable_ = enable;
1338 }
1339 
SetDirtyRegionBelowCurrentLayer(Occlusion::Region & region)1340 void RSSurfaceRenderNodeDrawable::SetDirtyRegionBelowCurrentLayer(Occlusion::Region& region)
1341 {
1342 #ifndef ROSEN_CROSS_PLATFORM
1343     if (!renderParams_) {
1344         return;
1345     }
1346     Occlusion::Rect dirtyRect { renderParams_->GetOldDirtyInSurface() };
1347     Occlusion::Region dirtyRegion { dirtyRect };
1348     dirtyRegionBelowCurrentLayer_ = dirtyRegion.And(region);
1349     dirtyRegionBelowCurrentLayerIsEmpty_ = dirtyRegionBelowCurrentLayer_.IsEmpty();
1350 #endif
1351 }
1352 
GetSyncDirtyManager() const1353 std::shared_ptr<RSDirtyRegionManager> RSSurfaceRenderNodeDrawable::GetSyncDirtyManager() const
1354 {
1355     return syncDirtyManager_;
1356 }
1357 
1358 #ifndef ROSEN_CROSS_PLATFORM
RegisterDeleteBufferListenerOnSync(sptr<IConsumerSurface> consumer)1359 void RSSurfaceRenderNodeDrawable::RegisterDeleteBufferListenerOnSync(sptr<IConsumerSurface> consumer)
1360 {
1361     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1362     if (!renderEngine || !consumerOnDraw_) {
1363         return;
1364     }
1365     renderEngine->RegisterDeleteBufferListener(consumerOnDraw_);
1366 }
1367 #endif
1368 
1369 } // namespace OHOS::Rosen::DrawableV2
1370