• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "drawable/rs_surface_render_node_drawable.h"
17 
18 #include "acquire_fence_manager.h"
19 #include "impl_interface/region_impl.h"
20 #include "rs_trace.h"
21 #include "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