• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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