1 /*
2 * Copyright (c) 2022 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 "pipeline/rs_proxy_render_node.h"
17
18 #include "command/rs_surface_node_command.h"
19 #include "pipeline/rs_surface_render_node.h"
20 #include "platform/common/rs_log.h"
21 #include "visitor/rs_node_visitor.h"
22
23 namespace OHOS {
24 namespace Rosen {
RSProxyRenderNode(NodeId id,std::weak_ptr<RSSurfaceRenderNode> target,NodeId targetId,const std::weak_ptr<RSContext> & context)25 RSProxyRenderNode::RSProxyRenderNode(
26 NodeId id, std::weak_ptr<RSSurfaceRenderNode> target, NodeId targetId, const std::weak_ptr<RSContext>& context)
27 : RSRenderNode(id, context), target_(target), targetId_(targetId)
28 {
29 #ifndef ROSEN_ARKUI_X
30 MemoryInfo info = {sizeof(*this), ExtractPid(id), id, MEMORY_TYPE::MEM_RENDER_NODE};
31 MemoryTrack::Instance().AddNodeRecord(id, info);
32 #endif
33 }
34
~RSProxyRenderNode()35 RSProxyRenderNode::~RSProxyRenderNode()
36 {
37 ROSEN_LOGD("RSProxyRenderNode::~RSProxyRenderNode, proxy id:%{public}" PRIu64 " target:%{public}" PRIu64,
38 GetId(), targetId_);
39 #ifndef ROSEN_ARKUI_X
40 MemoryTrack::Instance().RemoveNodeRecord(GetId());
41 #endif
42 CleanUp(true);
43 }
44
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)45 void RSProxyRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
46 {
47 if (!visitor) {
48 return;
49 }
50 visitor->PrepareProxyRenderNode(*this);
51 }
52
Process(const std::shared_ptr<RSNodeVisitor> & visitor)53 void RSProxyRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
54 {
55 if (!visitor) {
56 return;
57 }
58 RSRenderNode::RenderTraceDebug();
59 visitor->ProcessProxyRenderNode(*this);
60 }
61
62 #ifndef USE_ROSEN_DRAWING
SetContextMatrix(const std::optional<SkMatrix> & matrix)63 void RSProxyRenderNode::SetContextMatrix(const std::optional<SkMatrix>& matrix)
64 #else
65 void RSProxyRenderNode::SetContextMatrix(const std::optional<Drawing::Matrix>& matrix)
66 #endif
67 {
68 if (contextMatrix_ == matrix) {
69 return;
70 }
71 contextMatrix_ = matrix;
72 if (auto target = target_.lock()) {
73 target->SetContextMatrix(matrix, false);
74 return;
75 }
76 // send a Command
77 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextMatrix>(targetId_, matrix);
78 SendCommandFromRT(command, GetId());
79 }
80
SetContextAlpha(float alpha)81 void RSProxyRenderNode::SetContextAlpha(float alpha)
82 {
83 if (contextAlpha_ == alpha) {
84 return;
85 }
86 contextAlpha_ = alpha;
87 if (auto target = target_.lock()) {
88 target->SetContextAlpha(alpha, false);
89 return;
90 }
91 // send a Command
92 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextAlpha>(targetId_, alpha);
93 SendCommandFromRT(command, GetId());
94 }
95
96 #ifndef USE_ROSEN_DRAWING
SetContextClipRegion(const std::optional<SkRect> & clipRegion)97 void RSProxyRenderNode::SetContextClipRegion(const std::optional<SkRect>& clipRegion)
98 #else
99 void RSProxyRenderNode::SetContextClipRegion(const std::optional<Drawing::Rect>& clipRegion)
100 #endif
101 {
102 if (contextClipRect_ == clipRegion) {
103 return;
104 }
105 contextClipRect_ = clipRegion;
106 if (auto target = target_.lock()) {
107 target->SetContextClipRegion(clipRegion, false);
108 return;
109 }
110 // send a Command
111 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextClipRegion>(targetId_, clipRegion);
112 SendCommandFromRT(command, GetId());
113 }
114
ResetContextVariableCache()115 void RSProxyRenderNode::ResetContextVariableCache()
116 {
117 // reset context variable cache, make sure next visit will flush correct context variables.
118 contextAlpha_ = -1.0f;
119 contextMatrix_.reset();
120 contextClipRect_.reset();
121 }
122
OnTreeStateChanged()123 void RSProxyRenderNode::OnTreeStateChanged()
124 {
125 RSRenderNode::OnTreeStateChanged();
126 if (!IsOnTheTree()) {
127 // removed from tree, clean up context variables
128 CleanUp(false);
129 }
130 ResetContextVariableCache();
131 }
132
CleanUp(bool removeModifiers)133 void RSProxyRenderNode::CleanUp(bool removeModifiers)
134 {
135 // if target do not exist (in RT) or already destroyed (in RS), skip reset
136 auto target = target_.lock();
137 if (target == nullptr) {
138 return;
139 }
140
141 // reset target node context properties
142 target->SetContextAlpha(1.0f, false);
143 target->SetContextMatrix(std::nullopt, false);
144 target->SetContextClipRegion(std::nullopt, false);
145
146 if (!removeModifiers) {
147 return;
148 }
149
150 // remove all modifiers and animations added via proxy node
151 const auto pid_of_this_node = ExtractPid(GetId());
152 target->FilterModifiersByPid(pid_of_this_node);
153 target->GetAnimationManager().FilterAnimationByPid(pid_of_this_node);
154 }
155 } // namespace Rosen
156 } // namespace OHOS
157