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