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 ApplyModifiers();
51 visitor->PrepareProxyRenderNode(*this);
52 }
53
Process(const std::shared_ptr<RSNodeVisitor> & visitor)54 void RSProxyRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
55 {
56 if (!visitor) {
57 return;
58 }
59 RSRenderNode::RenderTraceDebug();
60 visitor->ProcessProxyRenderNode(*this);
61 }
62
SetContextMatrix(const std::optional<Drawing::Matrix> & matrix)63 void RSProxyRenderNode::SetContextMatrix(const std::optional<Drawing::Matrix>& matrix)
64 {
65 if (contextMatrix_ == matrix) {
66 return;
67 }
68 contextMatrix_ = matrix;
69 if (auto target = target_.lock()) {
70 target->SetContextMatrix(matrix, false);
71 return;
72 }
73 // send a Command
74 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextMatrix>(targetId_, matrix);
75 SendCommandFromRT(command, GetId());
76 }
77
SetContextAlpha(float alpha)78 void RSProxyRenderNode::SetContextAlpha(float alpha)
79 {
80 if (contextAlpha_ == alpha) {
81 return;
82 }
83 contextAlpha_ = alpha;
84 if (auto target = target_.lock()) {
85 target->SetContextAlpha(alpha, false);
86 return;
87 }
88 // send a Command
89 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextAlpha>(targetId_, alpha);
90 SendCommandFromRT(command, GetId());
91 }
92
SetContextClipRegion(const std::optional<Drawing::Rect> & clipRegion)93 void RSProxyRenderNode::SetContextClipRegion(const std::optional<Drawing::Rect>& clipRegion)
94 {
95 if (contextClipRect_ == clipRegion) {
96 return;
97 }
98 contextClipRect_ = clipRegion;
99 if (auto target = target_.lock()) {
100 target->SetContextClipRegion(clipRegion, false);
101 return;
102 }
103 // send a Command
104 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextClipRegion>(targetId_, clipRegion);
105 SendCommandFromRT(command, GetId());
106 }
107
ResetContextVariableCache()108 void RSProxyRenderNode::ResetContextVariableCache()
109 {
110 // reset context variable cache, make sure next visit will flush correct context variables.
111 contextAlpha_ = -1.0f;
112 contextMatrix_.reset();
113 contextClipRect_.reset();
114 }
115
OnTreeStateChanged()116 void RSProxyRenderNode::OnTreeStateChanged()
117 {
118 RSRenderNode::OnTreeStateChanged();
119 if (!IsOnTheTree()) {
120 // removed from tree, clean up context variables
121 CleanUp(false);
122 }
123 ResetContextVariableCache();
124 }
125
CleanUp(bool removeModifiers)126 void RSProxyRenderNode::CleanUp(bool removeModifiers)
127 {
128 // if target do not exist (in RT) or already destroyed (in RS), skip reset
129 auto target = target_.lock();
130 if (target == nullptr) {
131 return;
132 }
133
134 // reset target node context properties
135 target->SetContextAlpha(1.0f, false);
136 target->SetContextMatrix(std::nullopt, false);
137 target->SetContextClipRegion(std::nullopt, false);
138
139 if (!removeModifiers) {
140 return;
141 }
142
143 // remove all modifiers and animations added via proxy node
144 const auto pid_of_this_node = ExtractPid(GetId());
145 target->FilterModifiersByPid(pid_of_this_node);
146 target->GetAnimationManager().FilterAnimationByPid(pid_of_this_node);
147 }
148 } // namespace Rosen
149 } // namespace OHOS
150