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