• 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/rs_canvas_render_node.h"
22 #include "pipeline/rs_paint_filter_canvas.h"
23 #include "pipeline/rs_uni_render_thread.h"
24 #include "platform/common/rs_log.h"
25 #include "utils/rect.h"
26 #include "utils/region.h"
27 
28 namespace OHOS::Rosen::DrawableV2 {
29 RSCanvasRenderNodeDrawable::Registrar RSCanvasRenderNodeDrawable::instance_;
30 
RSCanvasRenderNodeDrawable(std::shared_ptr<const RSRenderNode> && node)31 RSCanvasRenderNodeDrawable::RSCanvasRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node)
32     : RSRenderNodeDrawable(std::move(node))
33 {}
34 
OnGenerate(std::shared_ptr<const RSRenderNode> node)35 RSRenderNodeDrawable::Ptr RSCanvasRenderNodeDrawable::OnGenerate(std::shared_ptr<const RSRenderNode> node)
36 {
37     return new RSCanvasRenderNodeDrawable(std::move(node));
38 }
39 
40 /*
41  * This function will be called recursively many times, and the logic should be as concise as possible.
42  */
OnDraw(Drawing::Canvas & canvas)43 void RSCanvasRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
44 {
45     SetDrawSkipType(DrawSkipType::NONE);
46     if (!ShouldPaint()) {
47         SetDrawSkipType(DrawSkipType::SHOULD_NOT_PAINT);
48         return;
49     }
50     const auto& params = GetRenderParams();
51     if (params == nullptr) {
52         SetDrawSkipType(DrawSkipType::RENDER_PARAMS_NULL);
53         return;
54     }
55     auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
56     if (params->GetStartingWindowFlag() && paintFilterCanvas) { // do not draw startingwindows in sudthread
57         if (paintFilterCanvas->GetIsParallelCanvas()) {
58             SetDrawSkipType(DrawSkipType::PARALLEL_CANVAS_SKIP);
59             return;
60         }
61     }
62     auto isOpincDraw = PreDrawableCacheState(*params, isOpincDropNodeExt_);
63     RSAutoCanvasRestore acr(paintFilterCanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
64     params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
65     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
66     if ((UNLIKELY(!uniParam) || uniParam->IsOpDropped()) && GetOpDropped() &&
67         QuickReject(canvas, params->GetLocalDrawRect()) && isOpincDraw) {
68         SetDrawSkipType(DrawSkipType::OCCLUSION_SKIP);
69         return;
70     }
71 
72     if (LIKELY(isDrawingCacheEnabled_)) {
73         BeforeDrawCache(nodeCacheType_, canvas, *params, isOpincDropNodeExt_);
74         if (!drawBlurForCache_) {
75             GenerateCacheIfNeed(canvas, *params);
76         }
77         CheckCacheTypeAndDraw(canvas, *params);
78         AfterDrawCache(nodeCacheType_, canvas, *params, isOpincDropNodeExt_, opincRootTotalCount_);
79     } else {
80         RSRenderNodeDrawable::OnDraw(canvas);
81     }
82     RSRenderNodeDrawable::ProcessedNodeCountInc();
83 }
84 
85 /*
86  * This function will be called recursively many times, and the logic should be as concise as possible.
87  */
OnCapture(Drawing::Canvas & canvas)88 void RSCanvasRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
89 {
90     if (!ShouldPaint()) {
91         return;
92     }
93     const auto& params = GetRenderParams();
94     auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
95     RSAutoCanvasRestore acr(paintFilterCanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
96     params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
97 
98     // To be deleted after captureWindow being deleted
99     if (UNLIKELY(RSUniRenderThread::GetCaptureParam().isMirror_) && EnableRecordingOptimization(*params)) {
100         return;
101     }
102 
103     if (LIKELY(isDrawingCacheEnabled_)) {
104         if (canvas.GetUICapture() && !drawBlurForCache_) {
105             GenerateCacheIfNeed(canvas, *params);
106         }
107         CheckCacheTypeAndDraw(canvas, *params, true);
108     } else {
109         RSRenderNodeDrawable::OnDraw(canvas);
110     }
111 }
112 
113 // To be deleted after captureWindow being deleted
EnableRecordingOptimization(RSRenderParams & params)114 bool RSCanvasRenderNodeDrawable::EnableRecordingOptimization(RSRenderParams& params)
115 {
116     auto& threadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
117     if (threadParams) {
118         NodeId nodeId = threadParams->GetRootIdOfCaptureWindow();
119         bool hasCaptureImg = threadParams->GetHasCaptureImg();
120         if (nodeId == params.GetId()) {
121             RS_LOGD("RSCanvasRenderNodeDrawable::EnableRecordingOptimization: (id:[%{public}" PRIu64 "])",
122                 params.GetId());
123             threadParams->SetStartVisit(true);
124         }
125         if (hasCaptureImg && !threadParams->GetStartVisit()) {
126             RS_LOGD("RSCanvasRenderNodeDrawable::EnableRecordingOptimization: (id:[%{public}" PRIu64 "]) Skip layer.",
127                 params.GetId());
128             return true;
129         }
130     }
131     return false;
132 }
133 } // namespace OHOS::Rosen::DrawableV2
134