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 "draw/brush.h"
26 #include "drawable/rs_display_render_node_drawable.h"
27 #include "memory/rs_tag_tracker.h"
28 #include "params/rs_display_render_params.h"
29 #include "params/rs_surface_render_params.h"
30 #include "pipeline/rs_paint_filter_canvas.h"
31 #include "pipeline/rs_surface_handler.h"
32 #include "pipeline/rs_surface_render_node.h"
33 #include "pipeline/rs_uni_render_thread.h"
34 #include "pipeline/rs_uni_render_util.h"
35 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
36 #include "pipeline/pointer_render/rs_pointer_render_manager.h"
37 #endif
38
39 #include "platform/common/rs_log.h"
40 #include "platform/ohos/rs_node_stats.h"
41 #include "utils/rect.h"
42 #include "utils/region.h"
43
44 #include "pipeline/rs_uifirst_manager.h"
45 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
46 #include "pipeline/rs_main_thread.h"
47 #include "static_factory.h"
48 #ifdef RS_ENABLE_VK
49 #include "include/gpu/GrBackendSurface.h"
50 #include "platform/ohos/backend/native_buffer_utils.h"
51 #include "platform/ohos/backend/rs_vulkan_context.h"
52 #endif
53 #include "render/rs_high_performance_visual_engine.h"
54
55 #include "luminance/rs_luminance_control.h"
56 #ifdef USE_VIDEO_PROCESSING_ENGINE
57 #include "metadata_helper.h"
58 #endif
59 namespace {
60 constexpr int32_t CORNER_SIZE = 4;
61 constexpr float GAMMA2_2 = 2.2f;
62 }
63 namespace OHOS::Rosen::DrawableV2 {
64 RSSurfaceRenderNodeDrawable::Registrar RSSurfaceRenderNodeDrawable::instance_;
65
RSSurfaceRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)66 RSSurfaceRenderNodeDrawable::RSSurfaceRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
67 : RSRenderNodeDrawable(std::move(node)), syncDirtyManager_(std::make_shared<RSDirtyRegionManager>())
68 {
69 auto nodeSp = std::const_pointer_cast<RSRenderNode>(node);
70 auto surfaceNode = std::static_pointer_cast<RSSurfaceRenderNode>(nodeSp);
71 name_ = surfaceNode->GetName();
72 if (name_.find("SCBScreenLock") != std::string::npos) {
73 vmaCacheOff_ = true;
74 }
75 surfaceNodeType_ = surfaceNode->GetSurfaceNodeType();
76 #ifndef ROSEN_CROSS_PLATFORM
77 consumerOnDraw_ = surfaceNode->GetRSSurfaceHandler()->GetConsumer();
78 #endif
79 surfaceHandlerUiFirst_ = std::make_shared<RSSurfaceHandler>(nodeId_);
80 }
81
~RSSurfaceRenderNodeDrawable()82 RSSurfaceRenderNodeDrawable::~RSSurfaceRenderNodeDrawable()
83 {
84 ClearCacheSurfaceInThread();
85 }
86
OnGenerate(std::shared_ptr<const RSRenderNode> node)87 RSRenderNodeDrawable::Ptr RSSurfaceRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
88 {
89 RS_TRACE_NAME("RSRenderNodeDrawable::Ptr RSSurfaceRenderNodeDrawable::OnGenerate");
90 return new RSSurfaceRenderNodeDrawable(std::move(node));
91 }
92
OnGeneralProcess(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams,bool isSelfDrawingSurface)93 void RSSurfaceRenderNodeDrawable::OnGeneralProcess(
94 RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams, bool isSelfDrawingSurface)
95 {
96 auto bounds = surfaceParams.GetFrameRect();
97
98 // 1. draw background
99 DrawBackground(canvas, bounds);
100
101 // 2. draw self drawing node
102 if (surfaceParams.GetBuffer() != nullptr) {
103 DealWithSelfDrawingNodeBuffer(canvas, surfaceParams);
104 }
105
106 if (isSelfDrawingSurface) {
107 canvas.Restore();
108 }
109
110 if (surfaceParams.GetNeedCacheSurface()) {
111 // 3/4 Draw content and children of this node by the main canvas, and cache
112 drawWindowCache_.DrawAndCacheWindowContent(this, canvas, bounds);
113 } else {
114 // 3. Draw content of this node by the main canvas.
115 DrawContent(canvas, bounds);
116
117 // 4. Draw children of this node by the main canvas.
118 DrawChildren(canvas, bounds);
119 }
120
121 // 5. Draw foreground of this node by the main canvas.
122 DrawForeground(canvas, bounds);
123 }
124
MergeSubSurfaceNodesDirtyRegionForMainWindow(RSSurfaceRenderParams & surfaceParams,Occlusion::Region & surfaceDirtyRegion) const125 void RSSurfaceRenderNodeDrawable::MergeSubSurfaceNodesDirtyRegionForMainWindow(
126 RSSurfaceRenderParams& surfaceParams, Occlusion::Region& surfaceDirtyRegion) const
127 {
128 for (const auto& drawable : GetDrawableVectorById(surfaceParams.GetAllSubSurfaceNodeIds())) {
129 auto surfaceNodeDrawable = std::static_pointer_cast<RSSurfaceRenderNodeDrawable>(drawable);
130 if (surfaceNodeDrawable && surfaceNodeDrawable->GetSyncDirtyManager()) {
131 Occlusion::Region subSurfaceDirtyRegion(surfaceNodeDrawable->GetSyncDirtyManager()->GetDirtyRegion());
132 surfaceDirtyRegion.OrSelf(subSurfaceDirtyRegion);
133 }
134 }
135 }
136
CalculateVisibleDirtyRegion(RSRenderThreadParams & uniParam,RSSurfaceRenderParams & surfaceParams,RSSurfaceRenderNodeDrawable & surfaceDrawable,bool isOffscreen) const137 Drawing::Region RSSurfaceRenderNodeDrawable::CalculateVisibleDirtyRegion(RSRenderThreadParams& uniParam,
138 RSSurfaceRenderParams& surfaceParams, RSSurfaceRenderNodeDrawable& surfaceDrawable, bool isOffscreen) const
139 {
140 Drawing::Region resultRegion;
141 if (!surfaceParams.IsMainWindowType()) {
142 return resultRegion;
143 }
144
145 // FUTURE: return real region
146 if (isOffscreen) {
147 resultRegion.SetRect(Drawing::RectI(0, 0,
148 DRAWING_MAX_S32_FITS_IN_FLOAT, DRAWING_MAX_S32_FITS_IN_FLOAT));
149 return resultRegion;
150 }
151
152 auto visibleRegion = surfaceParams.GetVisibleRegion();
153 if (uniParam.IsOcclusionEnabled() && visibleRegion.IsEmpty()) {
154 return resultRegion;
155 }
156 // The region is dirty region of this SurfaceNode (including sub-surface node in its subtree).
157 Occlusion::Region surfaceNodeDirtyRegion(GetSyncDirtyManager()->GetDirtyRegion());
158 // Dirty region of sub-surface nodes should also be count in parent main surface node, to avoid early skipping.
159 if (surfaceParams.HasSubSurfaceNodes()) {
160 MergeSubSurfaceNodesDirtyRegionForMainWindow(surfaceParams, surfaceNodeDirtyRegion);
161 }
162 // The region is the result of global dirty region AND occlusion region.
163 Occlusion::Region globalDirtyRegion = GetGlobalDirtyRegion();
164 // This include dirty region and occlusion region when surfaceNode is mainWindow.
165 auto dirtyRegion = globalDirtyRegion.Or(surfaceNodeDirtyRegion);
166 auto visibleDirtyRegion = dirtyRegion.And(visibleRegion);
167 if (visibleDirtyRegion.IsEmpty()) {
168 RS_LOGD("RSSurfaceRenderNodeDrawable::OnDraw occlusion skip SurfaceName:%s NodeId:%" PRIu64 "",
169 surfaceDrawable.GetName().c_str(), surfaceParams.GetId());
170 return resultRegion;
171 }
172
173 for (auto& rect : visibleDirtyRegion.GetRegionRects()) {
174 Drawing::Region tempRegion;
175 tempRegion.SetRect(Drawing::RectI(rect.left_, rect.top_, rect.right_, rect.bottom_));
176 resultRegion.Op(tempRegion, Drawing::RegionOp::UNION);
177 }
178 return resultRegion;
179 }
180
PrepareOffscreenRender()181 bool RSSurfaceRenderNodeDrawable::PrepareOffscreenRender()
182 {
183 // cleanup
184 canvasBackup_ = nullptr;
185
186 // check offscreen size
187 if (curCanvas_->GetSurface() == nullptr) {
188 RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, current surface is nullptr");
189 return false;
190 }
191 int offscreenWidth = curCanvas_->GetSurface()->Width();
192 int offscreenHeight = curCanvas_->GetSurface()->Height();
193 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
194 if (uniParam && uniParam->IsMirrorScreen() &&
195 uniParam->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
196 auto screenInfo = uniParam->GetScreenInfo();
197 offscreenWidth = static_cast<int>(screenInfo.width);
198 offscreenHeight = static_cast<int>(screenInfo.height);
199 }
200 if (offscreenWidth <= 0 || offscreenHeight <= 0) {
201 RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, offscreenWidth or offscreenHeight is invalid");
202 return false;
203 }
204
205 int maxRenderSize = std::max(offscreenWidth, offscreenHeight);
206 // create offscreen surface and canvas
207 if (offscreenSurface_ == nullptr || maxRenderSize_ != maxRenderSize) {
208 RS_LOGD("PrepareOffscreenRender create offscreen surface offscreenSurface_,\
209 new [%{public}d, %{public}d %{public}d]", offscreenWidth, offscreenHeight, maxRenderSize);
210 RS_TRACE_NAME_FMT("PrepareOffscreenRender surface size: [%d, %d]", maxRenderSize, maxRenderSize);
211 maxRenderSize_ = maxRenderSize;
212 offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(maxRenderSize_, maxRenderSize_);
213 }
214 if (offscreenSurface_ == nullptr) {
215 RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, offscreenSurface is nullptr");
216 return false;
217 }
218
219 offscreenCanvas_ = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
220
221 // copy HDR properties into offscreen canvas
222 offscreenCanvas_->CopyHDRConfiguration(*curCanvas_);
223 // copy current canvas properties into offscreen canvas
224 offscreenCanvas_->CopyConfigurationToOffscreenCanvas(*curCanvas_);
225
226 // backup current canvas and replace with offscreen canvas
227 canvasBackup_ = curCanvas_;
228 curCanvas_ = offscreenCanvas_.get();
229 curCanvas_->SetDisableFilterCache(true);
230 arc_ = std::make_unique<RSAutoCanvasRestore>(curCanvas_, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
231 curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
232 return true;
233 }
234
FinishOffscreenRender(const Drawing::SamplingOptions & sampling)235 void RSSurfaceRenderNodeDrawable::FinishOffscreenRender(const Drawing::SamplingOptions& sampling)
236 {
237 if (canvasBackup_ == nullptr) {
238 RS_LOGE("RSSurfaceRenderNodeDrawable::FinishOffscreenRender, canvasBackup_ is nullptr");
239 return;
240 }
241 if (offscreenSurface_ == nullptr) {
242 RS_LOGE("RSSurfaceRenderNodeDrawable::FinishOffscreenRender, offscreenSurface_ is nullptr");
243 return;
244 }
245 auto image = offscreenSurface_->GetImageSnapshot();
246 if (image == nullptr) {
247 RS_LOGE("RSSurfaceRenderNodeDrawable::FinishOffscreenRender, Surface::GetImageSnapshot is nullptr");
248 return;
249 }
250 // draw offscreen surface to current canvas
251 Drawing::Brush paint;
252 paint.SetAntiAlias(true);
253 canvasBackup_->AttachBrush(paint);
254 canvasBackup_->DrawImage(*image, 0, 0, sampling);
255 canvasBackup_->DetachBrush();
256 arc_ = nullptr;
257 curCanvas_ = canvasBackup_;
258 }
259
IsHardwareEnabled()260 bool RSSurfaceRenderNodeDrawable::IsHardwareEnabled()
261 {
262 auto& hardwareDrawables =
263 RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
264 for (const auto& [_, drawable] : hardwareDrawables) {
265 if (!drawable || !drawable->GetRenderParams()) {
266 continue;
267 }
268 auto params = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
269 if (!params || !params->GetHardwareEnabled()) {
270 continue;
271 }
272 return true;
273 }
274 return false;
275 }
276
OnDraw(Drawing::Canvas & canvas)277 void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
278 {
279 SetDrawSkipType(DrawSkipType::NONE);
280 if (!ShouldPaint()) {
281 SetDrawSkipType(DrawSkipType::SHOULD_NOT_PAINT);
282 RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw %s should not paint", name_.c_str());
283 return;
284 }
285
286 if (vmaCacheOff_) {
287 Drawing::StaticFactory::SetVmaCacheStatus(false); // render this frame with vma cache off
288 }
289
290 auto rscanvas = reinterpret_cast<RSPaintFilterCanvas*>(&canvas);
291 if (!rscanvas) {
292 SetDrawSkipType(DrawSkipType::CANVAS_NULL);
293 RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw, rscanvas us nullptr");
294 return;
295 }
296 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
297 if (UNLIKELY(!uniParam)) {
298 SetDrawSkipType(DrawSkipType::RENDER_THREAD_PARAMS_NULL);
299 RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw uniParam is nullptr");
300 return;
301 }
302 auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
303 if (!surfaceParams) {
304 SetDrawSkipType(DrawSkipType::RENDER_PARAMS_NULL);
305 RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw params is nullptr");
306 return;
307 }
308 if (surfaceParams->GetSkipDraw()) {
309 SetDrawSkipType(DrawSkipType::SURFACE_PARAMS_SKIP_DRAW);
310 RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw SkipDraw [%s] Id:%" PRIu64 "",
311 name_.c_str(), surfaceParams->GetId());
312 return;
313 }
314 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
315 if (!renderEngine) {
316 RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw renderEngine is nullptr");
317 return;
318 }
319 auto unmappedCache = surfaceParams->GetBufferClearCacheSet();
320 if (unmappedCache.size() > 0) {
321 // remove imagecahce when its bufferQueue gobackground
322 renderEngine->ClearCacheSet(unmappedCache);
323 }
324 if (autoCacheEnable_) {
325 nodeCacheType_ = NodeStrategyType::CACHE_NONE;
326 }
327 bool isUiFirstNode = rscanvas->GetIsParallelCanvas();
328 bool disableFilterCache = rscanvas->GetDisableFilterCache();
329 if (!disableFilterCache && !isUiFirstNode && surfaceParams->GetOccludedByFilterCache()) {
330 SetDrawSkipType(DrawSkipType::FILTERCACHE_OCCLUSION_SKIP);
331 RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw filterCache occlusion skip [%s] %sAlpha: %f, "
332 "NodeId:%" PRIu64 "", name_.c_str(), surfaceParams->GetAbsDrawRect().ToString().c_str(),
333 surfaceParams->GetGlobalAlpha(), surfaceParams->GetId());
334 return;
335 }
336 hasSkipCacheLayer_ =
337 (surfaceParams->GetIsSecurityLayer() && !uniParam->GetSecExemption()) || surfaceParams->GetIsSkipLayer();
338 if (hasSkipCacheLayer_ && curDrawingCacheRoot_) {
339 curDrawingCacheRoot_->SetSkipCacheLayer(true);
340 }
341
342 Drawing::Region curSurfaceDrawRegion = CalculateVisibleDirtyRegion(*uniParam, *surfaceParams, *this, isUiFirstNode);
343 if (!isUiFirstNode) {
344 MergeDirtyRegionBelowCurSurface(*uniParam, curSurfaceDrawRegion);
345 if (uniParam->IsOpDropped() && surfaceParams->IsVisibleDirtyRegionEmpty(curSurfaceDrawRegion)) {
346 SetDrawSkipType(DrawSkipType::OCCLUSION_SKIP);
347 RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw occlusion skip SurfaceName:%s %sAlpha: %f, NodeId:"
348 "%" PRIu64 "", name_.c_str(), surfaceParams->GetAbsDrawRect().ToString().c_str(),
349 surfaceParams->GetGlobalAlpha(), surfaceParams->GetId());
350 return;
351 }
352 }
353 const auto &absDrawRect = surfaceParams->GetAbsDrawRect();
354 // syncDirtyManager_ is not null
355 const RectI& currentFrameDirty = syncDirtyManager_->GetCurrentFrameDirtyRegion();
356 const RectI& mergeHistoryDirty = syncDirtyManager_->GetDirtyRegion();
357 // warning : don't delete this trace or change trace level to optional !!!
358 RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw:[%s] (%d, %d, %d, %d)Alpha: %f, "
359 "currentFrameDirty (%d, %d, %d, %d), mergeHistoryDirty (%d, %d, %d, %d)", name_.c_str(),
360 absDrawRect.left_, absDrawRect.top_, absDrawRect.width_, absDrawRect.height_, surfaceParams->GetGlobalAlpha(),
361 currentFrameDirty.left_, currentFrameDirty.top_, currentFrameDirty.width_, currentFrameDirty.height_,
362 mergeHistoryDirty.left_, mergeHistoryDirty.top_, mergeHistoryDirty.width_, mergeHistoryDirty.height_);
363
364 RS_LOGD("RSSurfaceRenderNodeDrawable::OnDraw node:%{public}" PRIu64 ", name:%{public}s,"
365 "OcclusionVisible:%{public}d Bound:%{public}s",
366 surfaceParams->GetId(), name_.c_str(), surfaceParams->GetOcclusionVisible(),
367 surfaceParams->GetBounds().ToString().c_str());
368
369 RSUiFirstProcessStateCheckerHelper stateCheckerHelper(
370 surfaceParams->GetFirstLevelNodeId(), surfaceParams->GetUifirstRootNodeId(), nodeId_);
371 if (!RSUiFirstProcessStateCheckerHelper::CheckMatchAndWaitNotify(*surfaceParams)) {
372 SetDrawSkipType(DrawSkipType::CHECK_MATCH_AND_WAIT_NOTIFY_FAIL);
373 return;
374 }
375
376 if (drawWindowCache_.DealWithCachedWindow(this, *rscanvas, *surfaceParams)) {
377 return;
378 }
379 if (DealWithUIFirstCache(*rscanvas, *surfaceParams, *uniParam)) {
380 if (GetDrawSkipType() == DrawSkipType::NONE) {
381 SetDrawSkipType(DrawSkipType::UI_FIRST_CACHE_SKIP);
382 }
383 return;
384 }
385
386 RSRenderNodeSingleDrawableLocker singleLocker(this);
387 if (UNLIKELY(!singleLocker.IsLocked())) {
388 SetDrawSkipType(DrawSkipType::MULTI_ACCESS);
389 singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
390 RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw node %{public}" PRIu64 " onDraw!!!", GetId());
391 return;
392 }
393
394 std::shared_ptr<Drawing::GPUContext> gpuContext = nullptr;
395 auto realTid = gettid();
396 if (realTid == RSUniRenderThread::Instance().GetTid()) {
397 gpuContext = RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetSharedDrGPUContext();
398 } else {
399 gpuContext = RSSubThreadManager::Instance()->GetGrContextFromSubThread(realTid);
400 }
401 RSTagTracker tagTracker(gpuContext.get(), surfaceParams->GetId(),
402 RSTagTracker::TAGTYPE::TAG_DRAW_SURFACENODE, surfaceParams->GetName());
403
404 // Draw base pipeline start
405 RSAutoCanvasRestore acr(rscanvas, RSPaintFilterCanvas::SaveType::kAll);
406 bool needOffscreen = (realTid == RSUniRenderThread::Instance().GetTid()) &&
407 surfaceParams->GetNeedOffscreen() && !rscanvas->GetTotalMatrix().IsIdentity() &&
408 surfaceParams->IsAppWindow() && GetName().substr(0, 3) != "SCB" && !IsHardwareEnabled() &&
409 (surfaceParams->GetVisibleRegion().Area() == surfaceParams->GetOpaqueRegion().Area());
410 curCanvas_ = rscanvas;
411 if (needOffscreen) {
412 releaseCount_ = 0;
413 if (!PrepareOffscreenRender()) {
414 needOffscreen = false;
415 }
416 } else {
417 if (offscreenSurface_ != nullptr) {
418 releaseCount_++;
419 if (releaseCount_ == MAX_RELEASE_FRAME) {
420 std::shared_ptr<Drawing::Surface> hold = offscreenSurface_;
421 RSUniRenderThread::Instance().PostTask([hold] {});
422 offscreenSurface_ = nullptr;
423 releaseCount_ = 0;
424 }
425 }
426 }
427
428 surfaceParams->ApplyAlphaAndMatrixToCanvas(*curCanvas_, !needOffscreen);
429
430 bool isSelfDrawingSurface = surfaceParams->GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
431 !surfaceParams->IsSpherizeValid() && !surfaceParams->IsAttractionValid();
432 if (isSelfDrawingSurface) {
433 SetSkip(surfaceParams->GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE);
434 // Restore in OnGeneralProcess
435 curCanvas_->Save();
436 }
437
438 if (surfaceParams->IsMainWindowType()) {
439 RSRenderNodeDrawable::ClearTotalProcessedNodeCount();
440 RSRenderNodeDrawable::ClearProcessedNodeCount();
441 if (!surfaceParams->GetNeedOffscreen()) {
442 curCanvas_->PushDirtyRegion(curSurfaceDrawRegion);
443 }
444 }
445
446 auto parentSurfaceMatrix = RSRenderParams::GetParentSurfaceMatrix();
447 RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
448
449 // add a blending disable rect op behind floating window, to enable overdraw buffer feature on special gpu.
450 if (surfaceParams->IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()
451 && surfaceParams->IsGpuOverDrawBufferOptimizeNode()) {
452 EnableGpuOverDrawDrawBufferOptimization(*curCanvas_, surfaceParams);
453 }
454
455 if (surfaceParams->GetRSFreezeFlag() && GetCacheImageByCapture()) {
456 RS_TRACE_NAME("Drawing cachedImage by capture");
457 DrawCachedImage(*curCanvas_, surfaceParams->GetCacheSize());
458 } else {
459 if (GetCacheImageByCapture()) {
460 SetCacheImageByCapture(nullptr);
461 }
462 OnGeneralProcess(*curCanvas_, *surfaceParams, isSelfDrawingSurface);
463 }
464
465 if (needOffscreen && canvasBackup_) {
466 Drawing::AutoCanvasRestore acrBackUp(*canvasBackup_, true);
467 if (surfaceParams->HasSandBox()) {
468 canvasBackup_->SetMatrix(surfaceParams->GetParentSurfaceMatrix());
469 canvasBackup_->ConcatMatrix(surfaceParams->GetMatrix());
470 } else {
471 canvasBackup_->ConcatMatrix(surfaceParams->GetMatrix());
472 }
473 FinishOffscreenRender(
474 Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NONE));
475 RS_LOGD("FinishOffscreenRender %{public}s node type %{public}d", surfaceParams->GetName().c_str(),
476 int(surfaceParams->GetSurfaceNodeType()));
477 }
478
479 // Draw base pipeline end
480 if (surfaceParams->IsMainWindowType()) {
481 if (!surfaceParams->GetNeedOffscreen()) {
482 curCanvas_->PopDirtyRegion();
483 }
484 int processedNodes = RSRenderNodeDrawable::GetProcessedNodeCount();
485 AcquireFenceTracker::SetContainerNodeNum(processedNodes);
486 RS_TRACE_NAME_FMT("RSUniRenderThread::Render() the number of total ProcessedNodes: %d",
487 RSRenderNodeDrawable::GetTotalProcessedNodeCount());
488 const RSNodeStatsType nodeStats = CreateRSNodeStatsItem(
489 RSRenderNodeDrawable::GetTotalProcessedNodeCount(), GetId(), GetName());
490 RSNodeStats::GetInstance().AddNodeStats(nodeStats);
491 }
492
493 RSRenderParams::SetParentSurfaceMatrix(parentSurfaceMatrix);
494 }
495
MergeDirtyRegionBelowCurSurface(RSRenderThreadParams & uniParam,Drawing::Region & region)496 void RSSurfaceRenderNodeDrawable::MergeDirtyRegionBelowCurSurface(
497 RSRenderThreadParams& uniParam, Drawing::Region& region)
498 {
499 if (!renderParams_) {
500 return;
501 }
502 auto surfaceParams = static_cast<RSSurfaceRenderParams*>(renderParams_.get());
503 auto isMainWindowType = surfaceParams->IsMainWindowType();
504 auto visibleRegion = surfaceParams->GetVisibleRegion();
505 if (isMainWindowType && visibleRegion.IsEmpty()) {
506 return;
507 }
508 if (isMainWindowType || surfaceParams->IsLeashWindow()) {
509 auto& accumulatedDirtyRegion = uniParam.GetAccumulatedDirtyRegion();
510 Occlusion::Region calcRegion;
511 if ((isMainWindowType && surfaceParams->IsParentScaling()) ||
512 surfaceParams->IsSubSurfaceNode() || uniParam.IsAllSurfaceVisibleDebugEnabled()) {
513 calcRegion = visibleRegion;
514 } else if (!surfaceParams->GetTransparentRegion().IsEmpty()) {
515 auto transparentRegion = surfaceParams->GetTransparentRegion();
516 calcRegion = visibleRegion.And(transparentRegion);
517 }
518 if (!calcRegion.IsEmpty()) {
519 auto dirtyRegion = calcRegion.And(accumulatedDirtyRegion);
520 if (!dirtyRegion.IsEmpty()) {
521 for (auto& rect : dirtyRegion.GetRegionRects()) {
522 Drawing::Region tempRegion;
523 tempRegion.SetRect(Drawing::RectI(
524 rect.left_, rect.top_, rect.right_, rect.bottom_));
525 region.Op(tempRegion, Drawing::RegionOp::UNION);
526 }
527 }
528 }
529 // [planing] surfaceDirtyRegion can be optimized by visibleDirtyRegion in some case.
530 auto surfaceDirtyRegion = Occlusion::Region {
531 Occlusion::Rect{ GetSyncDirtyManager()->GetDirtyRegion() } };
532 accumulatedDirtyRegion.OrSelf(surfaceDirtyRegion);
533 // add children window dirty here for uifirst leasf window will not traverse cached children
534 if (surfaceParams->GetUifirstNodeEnableParam() != MultiThreadCacheType::NONE) {
535 auto childrenDirtyRegion = Occlusion::Region {
536 Occlusion::Rect{ surfaceParams->GetUifirstChildrenDirtyRectParam() } };
537 accumulatedDirtyRegion.OrSelf(childrenDirtyRegion);
538 }
539 }
540 }
541
OnCapture(Drawing::Canvas & canvas)542 void RSSurfaceRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
543 {
544 if (!ShouldPaint()) {
545 return;
546 }
547
548 auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
549 if (!surfaceParams) {
550 RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture surfaceParams is nullptr");
551 return;
552 }
553
554 if (vmaCacheOff_) {
555 Drawing::StaticFactory::SetVmaCacheStatus(false); // render this frame with vma cache off
556 }
557
558 // HidePrivacyContent is only for UICapture or NoneSystemCalling-WindowCapture
559 bool isHiddenScene = canvas.GetUICapture() ||
560 (RSUniRenderThread::GetCaptureParam().isSingleSurface_ &&
561 !RSUniRenderThread::GetCaptureParam().isSystemCalling_);
562 if ((surfaceNodeType_ == RSSurfaceNodeType::UI_EXTENSION_COMMON_NODE ||
563 surfaceNodeType_ == RSSurfaceNodeType::UI_EXTENSION_SECURE_NODE) &&
564 isHiddenScene && surfaceParams->GetHidePrivacyContent()) {
565 RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture surfacenode nodeId:[%{public}" PRIu64
566 "] is not allowed to be captured", nodeId_);
567 return;
568 }
569
570 RSUiFirstProcessStateCheckerHelper stateCheckerHelper(
571 surfaceParams->GetFirstLevelNodeId(), surfaceParams->GetUifirstRootNodeId(), nodeId_);
572 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
573 if (UNLIKELY(!uniParam)) {
574 RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture uniParam is nullptr");
575 return;
576 }
577
578 auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
579 if (!rscanvas) {
580 RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture, rscanvas us nullptr");
581 return;
582 }
583 rscanvas->SetHighContrast(RSUniRenderThread::Instance().IsHighContrastTextModeOn());
584 // process white list
585 auto whiteList = RSUniRenderThread::Instance().GetWhiteList();
586 SetVirtualScreenWhiteListRootId(whiteList, surfaceParams->GetLeashPersistentId());
587
588 if (CheckIfSurfaceSkipInMirror(*surfaceParams)) {
589 return;
590 }
591
592 if (uniParam->IsOcclusionEnabled() && surfaceParams->IsMainWindowType() &&
593 surfaceParams->GetVisibleRegionInVirtual().IsEmpty() && whiteList.empty() &&
594 UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_)) {
595 RS_TRACE_NAME("RSSurfaceRenderNodeDrawable::OnCapture occlusion skip :[" + name_ + "] " +
596 surfaceParams->GetAbsDrawRect().ToString());
597 return;
598 }
599
600 RS_TRACE_NAME("RSSurfaceRenderNodeDrawable::OnCapture:[" + name_ + "] " +
601 surfaceParams->GetAbsDrawRect().ToString() + "Alpha: " +
602 std::to_string(surfaceParams->GetGlobalAlpha()));
603 RSAutoCanvasRestore acr(rscanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
604
605 // First node don't need to concat matrix for application
606 if (RSUniRenderThread::GetCaptureParam().isFirstNode_) {
607 // Planning: If node is a sandbox.
608 rscanvas->MultiplyAlpha(surfaceParams->GetAlpha());
609 RSUniRenderThread::GetCaptureParam().isFirstNode_ = false;
610 } else {
611 surfaceParams->ApplyAlphaAndMatrixToCanvas(*rscanvas);
612 }
613
614 CaptureSurface(*rscanvas, *surfaceParams);
615 ResetVirtualScreenWhiteListRootId(surfaceParams->GetLeashPersistentId());
616 }
617
CheckIfSurfaceSkipInMirror(const RSSurfaceRenderParams & surfaceParams)618 bool RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror(const RSSurfaceRenderParams& surfaceParams)
619 {
620 if (!RSUniRenderThread::GetCaptureParam().isMirror_) {
621 return false;
622 }
623 // Check black list.
624 const auto& blackList = RSUniRenderThread::Instance().GetBlackList();
625 if (surfaceParams.IsLeashWindow() && blackList.find(surfaceParams.GetLeashPersistentId()) != blackList.end()) {
626 RS_LOGD("RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror: \
627 (LeashPersistentId:[%{public}" PRIu64 "]) is in black list", surfaceParams.GetLeashPersistentId());
628 return true;
629 }
630 if (blackList.find(surfaceParams.GetId()) != blackList.end()) {
631 RS_LOGD("RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror: \
632 (surfaceParamsId:[%{public}" PRIu64 "]) is in black list", surfaceParams.GetId());
633 return true;
634 }
635 // Check white list.
636 const auto& whiteList = RSUniRenderThread::Instance().GetWhiteList();
637 if (!whiteList.empty() && RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ == INVALID_NODEID) {
638 RS_LOGD("RSSurfaceRenderNodeDrawable::CheckIfSurfaceSkipInMirror: \
639 (id:[%{public}" PRIu64 "]) isn't in white list", surfaceParams.GetId());
640 return true;
641 }
642
643 return false;
644 }
645
SetVirtualScreenWhiteListRootId(const std::unordered_set<NodeId> & whiteList,NodeId id)646 void RSSurfaceRenderNodeDrawable::SetVirtualScreenWhiteListRootId(
647 const std::unordered_set<NodeId>& whiteList, NodeId id)
648 {
649 if (whiteList.find(id) == whiteList.end()) {
650 return;
651 }
652 // don't update if it's ancestor has already set
653 if (RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ != INVALID_NODEID) {
654 return;
655 }
656 RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ = id;
657 }
658
ResetVirtualScreenWhiteListRootId(NodeId id)659 void RSSurfaceRenderNodeDrawable::ResetVirtualScreenWhiteListRootId(NodeId id)
660 {
661 // only reset by the node which sets the flag
662 if (RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ == id) {
663 RSUniRenderThread::GetCaptureParam().rootIdInWhiteList_ = INVALID_NODEID;
664 }
665 }
666
CaptureSurface(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)667 void RSSurfaceRenderNodeDrawable::CaptureSurface(RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams)
668 {
669 auto& uniParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
670 if (UNLIKELY(!uniParams)) {
671 RS_LOGE("RSSurfaceRenderNodeDrawable::CaptureSurface uniParams is nullptr");
672 return;
673 }
674 auto isSnapshotSkipLayer =
675 RSUniRenderThread::GetCaptureParam().isSnapshot_ && surfaceParams.GetIsSnapshotSkipLayer();
676 if (UNLIKELY(surfaceParams.GetIsSecurityLayer() && !uniParams->GetSecExemption()) ||
677 surfaceParams.GetIsSkipLayer() || isSnapshotSkipLayer) {
678 RS_LOGD("RSSurfaceRenderNodeDrawable::CaptureSurface: \
679 process RSSurfaceRenderNode(id:[%{public}" PRIu64 "] name:[%{public}s]) with security or skip layer.",
680 surfaceParams.GetId(), name_.c_str());
681 RS_TRACE_NAME("CaptureSurface with security or skip layer");
682 if (RSUniRenderThread::GetCaptureParam().isSingleSurface_) {
683 Drawing::Brush rectBrush;
684 rectBrush.SetColor(Drawing::Color::COLOR_WHITE);
685 canvas.AttachBrush(rectBrush);
686 canvas.DrawRect(Drawing::Rect(0, 0, surfaceParams.GetBounds().GetWidth(),
687 surfaceParams.GetBounds().GetHeight()));
688 canvas.DetachBrush();
689 }
690 return;
691 }
692
693 if (surfaceParams.GetIsProtectedLayer()) {
694 RS_LOGD("RSSurfaceRenderNodeDrawable::CaptureSurface: \
695 process RSSurfaceRenderNode(id:[%{public}" PRIu64 "] name:[%{public}s]) with protected layer.",
696 surfaceParams.GetId(), name_.c_str());
697 Drawing::Brush rectBrush;
698 rectBrush.SetColor(Drawing::Color::COLOR_BLACK);
699 canvas.AttachBrush(rectBrush);
700 canvas.DrawRect(Drawing::Rect(0, 0, surfaceParams.GetBounds().GetWidth(),
701 surfaceParams.GetBounds().GetHeight()));
702 canvas.DetachBrush();
703 return;
704 }
705
706 bool hwcEnable = surfaceParams.GetHardwareEnabled();
707 surfaceParams.SetHardwareEnabled(false);
708 RS_LOGD("HDR hasHdrPresent_:%{public}d", canvas.IsCapture());
709 bool hasHidePrivacyContent = surfaceParams.HasPrivacyContentLayer() &&
710 RSUniRenderThread::GetCaptureParam().isSingleSurface_ &&
711 !RSUniRenderThread::GetCaptureParam().isSystemCalling_;
712 if (!(surfaceParams.HasSecurityLayer() || surfaceParams.HasSkipLayer() || surfaceParams.HasSnapshotSkipLayer() ||
713 surfaceParams.HasProtectedLayer() || hasHdrPresent_ || hasHidePrivacyContent)) {
714 if (drawWindowCache_.DealWithCachedWindow(this, canvas, surfaceParams)) {
715 surfaceParams.SetHardwareEnabled(hwcEnable);
716 if (RSUniRenderThread::GetCaptureParam().isSingleSurface_) {
717 RS_LOGI("%{public}s DealWithCachedWindow", __func__);
718 }
719 return;
720 }
721 if (DealWithUIFirstCache(canvas, surfaceParams, *uniParams)) {
722 surfaceParams.SetHardwareEnabled(hwcEnable);
723 if (RSUniRenderThread::GetCaptureParam().isSingleSurface_) {
724 RS_LOGI("%{public}s DealWithUIFirstCache", __func__);
725 }
726 return;
727 }
728 }
729 surfaceParams.SetHardwareEnabled(hwcEnable);
730
731 if (!RSUiFirstProcessStateCheckerHelper::CheckMatchAndWaitNotify(surfaceParams, false)) {
732 RS_LOGE("RSSurfaceRenderNodeDrawable::OnCapture CheckMatchAndWaitNotify failed");
733 return;
734 }
735
736 RSRenderNodeSingleDrawableLocker singleLocker(this);
737 if (UNLIKELY(!singleLocker.IsLocked())) {
738 singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
739 RS_LOGE("RSSurfaceRenderNodeDrawable::CaptureSurface node %{public}" PRIu64 " onDraw!!!", GetId());
740 return;
741 }
742
743 bool isSelfDrawingSurface = surfaceParams.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
744 !surfaceParams.IsSpherizeValid() && !surfaceParams.IsAttractionValid();
745 if (isSelfDrawingSurface) {
746 SetSkip(surfaceParams.GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE);
747 // Restore in OnGeneralProcess
748 canvas.Save();
749 }
750
751 auto parentSurfaceMatrix = RSRenderParams::GetParentSurfaceMatrix();
752 RSRenderParams::SetParentSurfaceMatrix(canvas.GetTotalMatrix());
753
754 OnGeneralProcess(canvas, surfaceParams, isSelfDrawingSurface);
755
756 RSRenderParams::SetParentSurfaceMatrix(parentSurfaceMatrix);
757 }
758
GetAncestorDisplayColorGamut(const RSSurfaceRenderParams & surfaceParams)759 GraphicColorGamut RSSurfaceRenderNodeDrawable::GetAncestorDisplayColorGamut(const RSSurfaceRenderParams& surfaceParams)
760 {
761 GraphicColorGamut targetColorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
762 auto ancestorDrawable = surfaceParams.GetAncestorDisplayDrawable().lock();
763 if (!ancestorDrawable) {
764 RS_LOGE("ancestorDrawable return nullptr");
765 return targetColorGamut;
766 }
767 auto ancestorDisplayDrawable = std::static_pointer_cast<RSDisplayRenderNodeDrawable>(ancestorDrawable);
768 if (!ancestorDisplayDrawable) {
769 RS_LOGE("ancestorDisplayDrawable return nullptr");
770 return targetColorGamut;
771 }
772 auto& ancestorParam = ancestorDrawable->GetRenderParams();
773 if (!ancestorParam) {
774 RS_LOGE("ancestorParam return nullptr");
775 return targetColorGamut;
776 }
777
778 auto renderParams = static_cast<RSDisplayRenderParams*>(ancestorParam.get());
779 targetColorGamut = renderParams->GetNewColorSpace();
780 RS_LOGD("params.targetColorGamut is %{public}d in DealWithSelfDrawingNodeBuffer", targetColorGamut);
781 return targetColorGamut;
782 }
783
DealWithSelfDrawingNodeBuffer(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)784 void RSSurfaceRenderNodeDrawable::DealWithSelfDrawingNodeBuffer(
785 RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams)
786 {
787 if (surfaceParams.GetHardwareEnabled() && !RSUniRenderThread::IsInCaptureProcess()) {
788 if (!IsHardwareEnabledTopSurface() && !surfaceParams.IsLayerTop()) {
789 ClipHoleForSelfDrawingNode(canvas, surfaceParams);
790 }
791 if (surfaceParams.GetNeedMakeImage()) {
792 RS_TRACE_NAME_FMT("DealWithSelfDrawingNodeBuffer Id:%" PRIu64 "", surfaceParams.GetId());
793 RSAutoCanvasRestore arc(&canvas);
794 surfaceParams.SetGlobalAlpha(1.0f);
795 pid_t threadId = gettid();
796 auto params = RSUniRenderUtil::CreateBufferDrawParam(*this, false, threadId);
797
798 Drawing::Matrix rotateMatrix = canvas.GetTotalMatrix();
799 rotateMatrix.PreConcat(params.matrix);
800
801 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
802 if (!renderEngine) {
803 RS_LOGE("DealWithSelfDrawingNodeBuffer renderEngine is nullptr");
804 return;
805 }
806 VideoInfo videoInfo;
807 auto surfaceNodeImage = renderEngine->CreateImageFromBuffer(canvas, params, videoInfo);
808
809 SurfaceNodeInfo surfaceNodeInfo = {surfaceNodeImage, rotateMatrix, params.srcRect, params.dstRect};
810 HveFilter::GetHveFilter().PushSurfaceNodeInfo(surfaceNodeInfo);
811 }
812 return;
813 }
814 if (surfaceParams.GetIsProtectedLayer()) {
815 RS_LOGD("protected layer cannot draw in non-protected context.");
816 return;
817 }
818 if (surfaceParams.IsInFixedRotation()) {
819 DrawBufferForRotationFixed(canvas, surfaceParams);
820 return;
821 }
822
823 RSAutoCanvasRestore arc(&canvas);
824 surfaceParams.SetGlobalAlpha(1.0f);
825 pid_t threadId = gettid();
826 auto params = RSUniRenderUtil::CreateBufferDrawParam(*this, false, threadId);
827 params.targetColorGamut = GetAncestorDisplayColorGamut(surfaceParams);
828 #ifdef USE_VIDEO_PROCESSING_ENGINE
829 params.sdrNits = surfaceParams.GetSdrNit();
830 params.tmoNits = surfaceParams.GetDisplayNit();
831 params.displayNits = params.tmoNits / std::pow(surfaceParams.GetBrightnessRatio(), GAMMA2_2); // gamma 2.2
832 #endif
833 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
834 if (IsHardwareEnabledTopSurface() && RSUniRenderThread::Instance().GetRSRenderThreadParams()->HasMirrorDisplay()) {
835 RSPointerRenderManager::GetInstance().SetCacheImgForPointer(canvas.GetSurface()->GetImageSnapshot());
836 }
837 #endif
838
839 DrawSelfDrawingNodeBuffer(canvas, surfaceParams, params);
840 }
841
ClipHoleForSelfDrawingNode(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)842 void RSSurfaceRenderNodeDrawable::ClipHoleForSelfDrawingNode(RSPaintFilterCanvas& canvas,
843 RSSurfaceRenderParams& surfaceParams)
844 {
845 RSAutoCanvasRestore arc(&canvas);
846 auto bounds = surfaceParams.GetBounds();
847 canvas.ClipRect({std::round(bounds.GetLeft()), std::round(bounds.GetTop()),
848 std::round(bounds.GetRight()), std::round(bounds.GetBottom())});
849 canvas.Clear(Drawing::Color::COLOR_TRANSPARENT);
850 }
851
DrawBufferForRotationFixed(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams)852 void RSSurfaceRenderNodeDrawable::DrawBufferForRotationFixed(RSPaintFilterCanvas& canvas,
853 RSSurfaceRenderParams& surfaceParams)
854 {
855 ClipHoleForSelfDrawingNode(canvas, surfaceParams);
856
857 Drawing::Brush brush;
858 brush.SetBlendMode(Drawing::BlendMode::DST_OVER);
859 Drawing::SaveLayerOps layerOps(nullptr, &brush);
860 canvas.SaveLayer(layerOps);
861
862 Drawing::Matrix inverse;
863 if (!(surfaceParams.GetLayerInfo().matrix.Invert(inverse))) {
864 RS_LOGE("DrawBufferForRotationFixed failed to get invert matrix");
865 }
866 canvas.ConcatMatrix(inverse);
867 auto params = RSUniRenderUtil::CreateBufferDrawParamForRotationFixed(*this, surfaceParams);
868 RSUniRenderThread::Instance().GetRenderEngine()->DrawSurfaceNodeWithParams(canvas, *this, params);
869 canvas.Restore();
870 }
871
DrawSelfDrawingNodeBuffer(RSPaintFilterCanvas & canvas,const RSSurfaceRenderParams & surfaceParams,BufferDrawParam & params)872 void RSSurfaceRenderNodeDrawable::DrawSelfDrawingNodeBuffer(
873 RSPaintFilterCanvas& canvas, const RSSurfaceRenderParams& surfaceParams, BufferDrawParam& params)
874 {
875 auto bgColor = surfaceParams.GetBackgroundColor();
876 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
877 if ((surfaceParams.GetSelfDrawingNodeType() != SelfDrawingNodeType::VIDEO) &&
878 (bgColor != RgbPalette::Transparent())) {
879 Drawing::Brush brush;
880 brush.SetColor(Drawing::Color(bgColor.AsArgbInt()));
881 if (HasCornerRadius(surfaceParams)) {
882 auto bounds = RSPropertiesPainter::Rect2DrawingRect({ 0, 0,
883 std::round(surfaceParams.GetBounds().GetWidth()), std::round(surfaceParams.GetBounds().GetHeight()) });
884 Drawing::SaveLayerOps layerOps(&bounds, nullptr);
885 canvas.SaveLayer(layerOps);
886 canvas.AttachBrush(brush);
887 canvas.DrawRoundRect(RSPropertiesPainter::RRect2DrawingRRect(surfaceParams.GetRRect()));
888 canvas.DetachBrush();
889 renderEngine->DrawSurfaceNodeWithParams(canvas, *this, params);
890 canvas.Restore();
891 } else {
892 canvas.AttachBrush(brush);
893 canvas.DrawRect(surfaceParams.GetBounds());
894 canvas.DetachBrush();
895 renderEngine->DrawSurfaceNodeWithParams(canvas, *this, params);
896 }
897 } else {
898 renderEngine->DrawSurfaceNodeWithParams(canvas, *this, params);
899 }
900 }
901
HasCornerRadius(const RSSurfaceRenderParams & surfaceParams) const902 bool RSSurfaceRenderNodeDrawable::HasCornerRadius(const RSSurfaceRenderParams& surfaceParams) const
903 {
904 auto rrect = surfaceParams.GetRRect();
905 for (auto index = 0; index < CORNER_SIZE; ++index) {
906 if (!ROSEN_EQ(rrect.radius_[index].x_, 0.f) || !ROSEN_EQ(rrect.radius_[index].y_, 0.f)) {
907 return true;
908 }
909 }
910 return false;
911 }
912
DealWithUIFirstCache(RSPaintFilterCanvas & canvas,RSSurfaceRenderParams & surfaceParams,RSRenderThreadParams & uniParams)913 bool RSSurfaceRenderNodeDrawable::DealWithUIFirstCache(
914 RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams, RSRenderThreadParams& uniParams)
915 {
916 auto enableType = surfaceParams.GetUifirstNodeEnableParam();
917 auto cacheState = GetCacheSurfaceProcessedStatus();
918 if ((!RSUniRenderThread::GetCaptureParam().isSnapshot_ && enableType == MultiThreadCacheType::NONE &&
919 // WAITING may change to DOING in subThread at any time
920 cacheState != CacheProcessStatus::WAITING && cacheState != CacheProcessStatus::DOING) ||
921 (RSUniRenderThread::GetCaptureParam().isSnapshot_ && !HasCachedTexture())) {
922 return false;
923 }
924 RS_TRACE_NAME_FMT("DrawUIFirstCache [%s] %" PRIu64 ", type %d",
925 name_.c_str(), surfaceParams.GetId(), enableType);
926 RSUifirstManager::Instance().AddReuseNode(surfaceParams.GetId());
927 Drawing::Rect bounds = GetRenderParams() ? GetRenderParams()->GetBounds() : Drawing::Rect(0, 0, 0, 0);
928 RSAutoCanvasRestore acr(&canvas);
929 // Alpha and matrix have been applied in func CaptureSurface
930 if (!RSUniRenderThread::GetCaptureParam().isSnapshot_ && !RSUniRenderThread::GetCaptureParam().isMirror_) {
931 canvas.MultiplyAlpha(surfaceParams.GetAlpha());
932 canvas.ConcatMatrix(surfaceParams.GetMatrix());
933 }
934 bool useDmaBuffer = UseDmaBuffer();
935 DrawBackground(canvas, bounds);
936 bool drawCacheSuccess = true;
937 if (surfaceParams.GetUifirstUseStarting() != INVALID_NODEID) {
938 drawCacheSuccess = DrawUIFirstCacheWithStarting(canvas, surfaceParams.GetUifirstUseStarting());
939 } else {
940 bool canSkipFirstWait = (enableType == MultiThreadCacheType::ARKTS_CARD) &&
941 uniParams.GetUIFirstCurrentFrameCanSkipFirstWait();
942 drawCacheSuccess = useDmaBuffer ?
943 DrawUIFirstCacheWithDma(canvas, surfaceParams) : DrawUIFirstCache(canvas, canSkipFirstWait);
944 }
945 if (!drawCacheSuccess) {
946 SetDrawSkipType(DrawSkipType::UI_FIRST_CACHE_FAIL);
947 RS_TRACE_NAME_FMT("[%s] reuse failed!", name_.c_str());
948 }
949 DrawForeground(canvas, bounds);
950 if (uniParams.GetUIFirstDebugEnabled()) {
951 DrawUIFirstDfx(canvas, enableType, surfaceParams, drawCacheSuccess);
952 }
953 return true;
954 }
955
DrawUIFirstDfx(RSPaintFilterCanvas & canvas,MultiThreadCacheType enableType,RSSurfaceRenderParams & surfaceParams,bool drawCacheSuccess)956 void RSSurfaceRenderNodeDrawable::DrawUIFirstDfx(RSPaintFilterCanvas& canvas, MultiThreadCacheType enableType,
957 RSSurfaceRenderParams& surfaceParams, bool drawCacheSuccess)
958 {
959 auto sizeDebug = surfaceParams.GetCacheSize();
960 Drawing::Brush rectBrush;
961 if (drawCacheSuccess) {
962 if (enableType == MultiThreadCacheType::ARKTS_CARD) {
963 // rgba: Alpha 128, blue 128
964 rectBrush.SetColor(Drawing::Color(0, 0, 128, 128));
965 } else {
966 // rgba: Alpha 128, green 128, blue 128
967 rectBrush.SetColor(Drawing::Color(0, 128, 128, 128));
968 }
969 } else {
970 // rgba: Alpha 128, red 128
971 rectBrush.SetColor(Drawing::Color(128, 0, 0, 128));
972 }
973 canvas.AttachBrush(rectBrush);
974 canvas.DrawRect(Drawing::Rect(0, 0, sizeDebug.x_, sizeDebug.y_));
975 canvas.DetachBrush();
976 }
977
EnableGpuOverDrawDrawBufferOptimization(Drawing::Canvas & canvas,RSSurfaceRenderParams * surfaceParams)978 void RSSurfaceRenderNodeDrawable::EnableGpuOverDrawDrawBufferOptimization(Drawing::Canvas& canvas,
979 RSSurfaceRenderParams* surfaceParams)
980 {
981 const Vector4f& radius = surfaceParams->GetOverDrawBufferNodeCornerRadius();
982 if (radius.IsZero()) {
983 return;
984 }
985 RS_OPTIONAL_TRACE_NAME_FMT("EnableGpuOverDrawDrawBufferOptimization Id:%" PRIu64 "", surfaceParams->GetId());
986 const Drawing::Rect& bounds = surfaceParams->GetFrameRect();
987 Drawing::Brush brush;
988 // must set src blend mode, so overdraw buffer feature can enabled.
989 brush.SetBlendMode(Drawing::BlendMode::SRC);
990 // cause the rect will be covered by the child background node, so we just add a white rect
991 brush.SetColor(Drawing::Color::COLOR_WHITE);
992 canvas.AttachBrush(brush);
993 Drawing::AutoCanvasRestore arc(canvas, true);
994 canvas.Translate(radius.x_, radius.y_);
995 canvas.DrawRect(Drawing::Rect {0, 0, bounds.GetWidth() - 2 * radius.x_, bounds.GetHeight() - 2 * radius.y_});
996 canvas.DetachBrush();
997 }
998
GetVisibleDirtyRegion() const999 const Occlusion::Region& RSSurfaceRenderNodeDrawable::GetVisibleDirtyRegion() const
1000 {
1001 return visibleDirtyRegion_;
1002 }
1003
SetVisibleDirtyRegion(const Occlusion::Region & region)1004 void RSSurfaceRenderNodeDrawable::SetVisibleDirtyRegion(const Occlusion::Region& region)
1005 {
1006 visibleDirtyRegion_ = region;
1007 }
1008
SetAlignedVisibleDirtyRegion(const Occlusion::Region & alignedRegion)1009 void RSSurfaceRenderNodeDrawable::SetAlignedVisibleDirtyRegion(const Occlusion::Region& alignedRegion)
1010 {
1011 alignedVisibleDirtyRegion_ = alignedRegion;
1012 }
1013
SetGlobalDirtyRegion(Occlusion::Region region)1014 void RSSurfaceRenderNodeDrawable::SetGlobalDirtyRegion(Occlusion::Region region)
1015 {
1016 globalDirtyRegion_ = region;
1017 }
1018
GetGlobalDirtyRegion() const1019 const Occlusion::Region& RSSurfaceRenderNodeDrawable::GetGlobalDirtyRegion() const
1020 {
1021 return globalDirtyRegion_;
1022 }
1023
SetDirtyRegionAlignedEnable(bool enable)1024 void RSSurfaceRenderNodeDrawable::SetDirtyRegionAlignedEnable(bool enable)
1025 {
1026 isDirtyRegionAlignedEnable_ = enable;
1027 }
1028
SetDirtyRegionBelowCurrentLayer(Occlusion::Region & region)1029 void RSSurfaceRenderNodeDrawable::SetDirtyRegionBelowCurrentLayer(Occlusion::Region& region)
1030 {
1031 #ifndef ROSEN_CROSS_PLATFORM
1032 if (!renderParams_) {
1033 return;
1034 }
1035 Occlusion::Rect dirtyRect { renderParams_->GetOldDirtyInSurface() };
1036 Occlusion::Region dirtyRegion { dirtyRect };
1037 dirtyRegionBelowCurrentLayer_ = dirtyRegion.And(region);
1038 dirtyRegionBelowCurrentLayerIsEmpty_ = dirtyRegionBelowCurrentLayer_.IsEmpty();
1039 #endif
1040 }
1041
GetSyncDirtyManager() const1042 std::shared_ptr<RSDirtyRegionManager> RSSurfaceRenderNodeDrawable::GetSyncDirtyManager() const
1043 {
1044 return syncDirtyManager_;
1045 }
1046
1047 #ifndef ROSEN_CROSS_PLATFORM
RegisterDeleteBufferListenerOnSync(sptr<IConsumerSurface> consumer)1048 void RSSurfaceRenderNodeDrawable::RegisterDeleteBufferListenerOnSync(sptr<IConsumerSurface> consumer)
1049 {
1050 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1051 if (!renderEngine || !consumerOnDraw_) {
1052 return;
1053 }
1054 renderEngine->RegisterDeleteBufferListener(consumerOnDraw_);
1055 }
1056 #endif
1057
1058 } // namespace OHOS::Rosen::DrawableV2
1059