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