• 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_canvas_render_node_drawable.h"
17 
18 #include "rs_trace.h"
19 
20 #include "common/rs_optional_trace.h"
21 #include "pipeline/render_thread/rs_uni_render_thread.h"
22 #include "pipeline/rs_canvas_render_node.h"
23 #include "pipeline/rs_paint_filter_canvas.h"
24 #include "platform/common/rs_log.h"
25 #include "utils/rect.h"
26 #include "utils/region.h"
27 #include "include/gpu/vk/GrVulkanTrackerInterface.h"
28 #include "rs_root_render_node_drawable.h"
29 
30 namespace OHOS::Rosen::DrawableV2 {
31 RSCanvasRenderNodeDrawable::Registrar RSCanvasRenderNodeDrawable::instance_;
32 
RSCanvasRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)33 RSCanvasRenderNodeDrawable::RSCanvasRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
34     : RSRenderNodeDrawable(std::move(node))
35 {}
36 
OnGenerate(std::shared_ptr<const RSRenderNode> node)37 RSRenderNodeDrawable::Ptr RSCanvasRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
38 {
39     return new RSCanvasRenderNodeDrawable(std::move(node));
40 }
41 
42 /*
43  * This function will be called recursively many times, and the logic should be as concise as possible.
44  */
OnDraw(Drawing::Canvas & canvas)45 void RSCanvasRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
46 {
47 #ifdef RS_ENABLE_GPU
48     SetDrawSkipType(DrawSkipType::NONE);
49     if (!ShouldPaint()) {
50         SetDrawSkipType(DrawSkipType::SHOULD_NOT_PAINT);
51         return;
52     }
53     const auto& params = GetRenderParams();
54     if (params == nullptr) {
55         SetDrawSkipType(DrawSkipType::RENDER_PARAMS_NULL);
56         return;
57     }
58     RECORD_GPU_RESOURCE_DRAWABLE_CALLER(GetId())
59     auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
60     if (params->GetStartingWindowFlag() && paintFilterCanvas) { // do not draw startingwindows in subthread
61         if (paintFilterCanvas->GetIsParallelCanvas()) {
62             SetDrawSkipType(DrawSkipType::PARALLEL_CANVAS_SKIP);
63             return;
64         }
65     }
66 
67     auto linkedDrawable = std::static_pointer_cast<RSRootRenderNodeDrawable>(
68         params->GetLinkedRootNodeDrawable().lock());
69     auto isOpincDraw = PreDrawableCacheState(*params, isOpincDropNodeExt_);
70     RSAutoCanvasRestore acr(paintFilterCanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
71     params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
72     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
73     if ((UNLIKELY(!uniParam) || uniParam->IsOpDropped()) && GetOpDropped() &&
74         QuickReject(canvas, params->GetLocalDrawRect()) && isOpincDraw && !params->HasUnobscuredUEC() &&
75         LIKELY(linkedDrawable == nullptr)) {
76         SetDrawSkipType(DrawSkipType::OCCLUSION_SKIP);
77         return;
78     }
79 
80     RSRenderNodeSingleDrawableLocker singleLocker(this);
81     if (UNLIKELY(!singleLocker.IsLocked())) {
82         singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
83         RS_LOGE("RSCanvasRenderNodeDrawable::OnDraw node %{public}" PRIu64 " onDraw!!!", GetId());
84         if (RSSystemProperties::GetSingleDrawableLockerEnabled()) {
85             SetDrawSkipType(DrawSkipType::MULTI_ACCESS);
86             return;
87         }
88     }
89 
90     // [Attention] Only used in PC window resize scene now
91     if (UNLIKELY(linkedDrawable != nullptr)) {
92         linkedDrawable->DrawWindowKeyFrameOffscreenBuffer(*paintFilterCanvas, params->GetFrameRect(),
93             params->GetAlpha(), params->GetRSFreezeFlag());
94         return;
95     }
96 
97     if (LIKELY(isDrawingCacheEnabled_)) {
98         BeforeDrawCache(nodeCacheType_, canvas, *params, isOpincDropNodeExt_);
99         if (!drawBlurForCache_) {
100             GenerateCacheIfNeed(canvas, *params);
101         }
102         CheckCacheTypeAndDraw(canvas, *params);
103         AfterDrawCache(nodeCacheType_, canvas, *params, isOpincDropNodeExt_, opincRootTotalCount_);
104     } else {
105         RSRenderNodeDrawable::OnDraw(canvas);
106     }
107     RSRenderNodeDrawable::ProcessedNodeCountInc();
108 #endif
109 }
110 
111 /*
112  * This function will be called recursively many times, and the logic should be as concise as possible.
113  */
OnCapture(Drawing::Canvas & canvas)114 void RSCanvasRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
115 {
116 #ifdef RS_ENABLE_GPU
117     if (!ShouldPaint()) {
118         return;
119     }
120     const auto& params = GetRenderParams();
121     auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
122     RSAutoCanvasRestore acr(paintFilterCanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
123     params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
124 
125     RSRenderNodeSingleDrawableLocker singleLocker(this);
126     if (UNLIKELY(!singleLocker.IsLocked())) {
127         singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
128         RS_LOGE("RSCanvasRenderNodeDrawable::OnCapture node %{public}" PRIu64 " onDraw!!!", GetId());
129         if (RSSystemProperties::GetSingleDrawableLockerEnabled()) {
130             return;
131         }
132     }
133     if (LIKELY(isDrawingCacheEnabled_)) {
134         if (canvas.GetUICapture() && !drawBlurForCache_) {
135             GenerateCacheIfNeed(canvas, *params);
136         }
137         CheckCacheTypeAndDraw(canvas, *params, true);
138     } else {
139         RSRenderNodeDrawable::OnDraw(canvas);
140     }
141 #endif
142 }
143 } // namespace OHOS::Rosen::DrawableV2
144