• 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,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