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