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 subthread
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 RSRenderNodeSingleDrawableLocker singleLocker(this);
73 if (UNLIKELY(!singleLocker.IsLocked())) {
74 SetDrawSkipType(DrawSkipType::MULTI_ACCESS);
75 singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
76 RS_LOGE("RSCanvasRenderNodeDrawable::OnDraw node %{public}" PRIu64 " onDraw!!!", GetId());
77 return;
78 }
79
80 if (LIKELY(isDrawingCacheEnabled_)) {
81 BeforeDrawCache(nodeCacheType_, canvas, *params, isOpincDropNodeExt_);
82 if (!drawBlurForCache_) {
83 GenerateCacheIfNeed(canvas, *params);
84 }
85 CheckCacheTypeAndDraw(canvas, *params);
86 AfterDrawCache(nodeCacheType_, canvas, *params, isOpincDropNodeExt_, opincRootTotalCount_);
87 } else {
88 RSRenderNodeDrawable::OnDraw(canvas);
89 }
90 RSRenderNodeDrawable::ProcessedNodeCountInc();
91 }
92
93 /*
94 * This function will be called recursively many times, and the logic should be as concise as possible.
95 */
OnCapture(Drawing::Canvas & canvas)96 void RSCanvasRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
97 {
98 if (!ShouldPaint()) {
99 return;
100 }
101 const auto& params = GetRenderParams();
102 auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
103 RSAutoCanvasRestore acr(paintFilterCanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
104 params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
105
106 RSRenderNodeSingleDrawableLocker singleLocker(this);
107 if (UNLIKELY(!singleLocker.IsLocked())) {
108 singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
109 RS_LOGE("RSCanvasRenderNodeDrawable::OnCapture node %{public}" PRIu64 " onDraw!!!", GetId());
110 return;
111 }
112 if (LIKELY(isDrawingCacheEnabled_)) {
113 if (canvas.GetUICapture() && !drawBlurForCache_) {
114 GenerateCacheIfNeed(canvas, *params);
115 }
116 CheckCacheTypeAndDraw(canvas, *params, true);
117 } else {
118 RSRenderNodeDrawable::OnDraw(canvas);
119 }
120 }
121 } // namespace OHOS::Rosen::DrawableV2
122