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