1 /*
2 * Copyright (c) 2024 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 "params/rs_render_params.h"
17 #include "pipeline/rs_render_node.h"
18 #ifdef DDGR_ENABLE_FEATURE_OPINC_DFX
19 #include "string_utils.h"
20 #endif
21 #include "common/rs_optional_trace.h"
22
23 namespace OHOS {
24 namespace Rosen {
25
26 constexpr int64_t MIN_REUSECOUNT = 10;
27 constexpr int64_t MAX_REUSECOUNT = 60;
28 constexpr int32_t MAX_TRY_TIMES = 3;
29
30 // mark stable node
OpincSetInAppStateStart(bool & unchangeMarkInApp)31 void RSRenderNode::OpincSetInAppStateStart(bool& unchangeMarkInApp)
32 {
33 if (unchangeMarkInApp) {
34 return;
35 }
36 isUnchangeMarkInApp_ = true;
37 unchangeMarkInApp = true;
38 }
39
OpincSetInAppStateEnd(bool & unchangeMarkInApp)40 void RSRenderNode::OpincSetInAppStateEnd(bool& unchangeMarkInApp)
41 {
42 if (isUnchangeMarkInApp_) {
43 isUnchangeMarkInApp_ = false;
44 unchangeMarkInApp = false;
45 }
46 }
47
OpincQuickMarkStableNode(bool & unchangeMarkInApp,bool & unchangeMarkEnable,bool isAccessibilityChanged)48 void RSRenderNode::OpincQuickMarkStableNode(bool& unchangeMarkInApp, bool& unchangeMarkEnable,
49 bool isAccessibilityChanged)
50 {
51 if (!unchangeMarkInApp) {
52 return;
53 }
54 if (GetSuggestOpincNode() && !unchangeMarkEnable) {
55 isUnchangeMarkEnable_ = true;
56 unchangeMarkEnable = true;
57 }
58 if (!unchangeMarkEnable) {
59 return;
60 }
61 auto isSelfDirty = IsSubTreeDirty() || IsContentDirty() ||
62 nodeGroupType_ > RSRenderNode::NodeGroupType::NONE || (isOpincRootFlag_ && isAccessibilityChanged);
63 if (isSelfDirty) {
64 NodeCacheStateChange(NodeChangeType::SELF_DIRTY);
65 } else if (nodeCacheState_ != NodeCacheState::STATE_UNCHANGE) {
66 NodeCacheStateChange(NodeChangeType::KEEP_UNCHANGE);
67 }
68 }
69
OpincUpdateRootFlag(bool & unchangeMarkEnable)70 void RSRenderNode::OpincUpdateRootFlag(bool& unchangeMarkEnable)
71 {
72 if (unchangeMarkEnable) {
73 if (IsOpincUnchangeState()) {
74 isOpincRootFlag_ = true;
75 if (stagingRenderParams_) {
76 stagingRenderParams_->OpincUpdateRootFlag(true);
77 }
78 }
79 }
80 if (isUnchangeMarkEnable_) {
81 isUnchangeMarkEnable_ = false;
82 unchangeMarkEnable = false;
83 }
84 }
85
IsOpincUnchangeState()86 bool RSRenderNode::IsOpincUnchangeState()
87 {
88 return (nodeCacheState_ == NodeCacheState::STATE_UNCHANGE) && OpincGetNodeSupportFlag() && GetSuggestOpincNode();
89 }
90
QuickGetNodeDebugInfo()91 std::string RSRenderNode::QuickGetNodeDebugInfo()
92 {
93 std::string ret("");
94 #ifdef DDGR_ENABLE_FEATURE_OPINC_DFX
95 AppendFormat(ret, "%llx, IsSTD:%d s:%d uc:%d suggest:%d support:%d rootF:%d",
96 GetId(), IsSubTreeDirty(), nodeCacheState_, unchangeCount_, GetSuggestOpincNode(),
97 OpincGetNodeSupportFlag(), isOpincRootFlag_);
98 #endif
99 return ret;
100 }
101
102 // mark support node
OpincUpdateNodeSupportFlag(bool supportFlag)103 void RSRenderNode::OpincUpdateNodeSupportFlag(bool supportFlag)
104 {
105 isOpincNodeSupportFlag_ = isOpincNodeSupportFlag_ && supportFlag && (!IsMarkedRenderGroup());
106 }
107
IsMarkedRenderGroup()108 bool RSRenderNode::IsMarkedRenderGroup()
109 {
110 return (nodeGroupType_ > RSRenderNode::NodeGroupType::NONE) || isOpincRootFlag_;
111 }
112
OpincForcePrepareSubTree()113 bool RSRenderNode::OpincForcePrepareSubTree()
114 {
115 bool flag = (!(IsSubTreeDirty() || IsContentDirty())) && GetSuggestOpincNode() &&
116 OpincGetNodeSupportFlag() && !isOpincRootFlag_;
117 if (flag) {
118 SetParentSubTreeDirty();
119 }
120 return flag;
121 }
122
OpincGetRootFlag() const123 bool RSRenderNode::OpincGetRootFlag() const
124 {
125 return isOpincRootFlag_;
126 }
127
128 // arkui mark
MarkSuggestOpincNode(bool isOpincNode,bool isNeedCalculate)129 void RSRenderNode::MarkSuggestOpincNode(bool isOpincNode, bool isNeedCalculate)
130 {
131 RS_TRACE_NAME_FMT("mark opinc %llx, isopinc:%d. isCal:%d", GetId(), isOpincNode, isNeedCalculate);
132 isSuggestOpincNode_ = isOpincNode;
133 isNeedCalculate_ = isNeedCalculate;
134 SetDirty();
135 }
136
GetSuggestOpincNode() const137 bool RSRenderNode::GetSuggestOpincNode() const
138 {
139 return isSuggestOpincNode_;
140 }
141
NodeCacheStateChange(NodeChangeType type)142 void RSRenderNode::NodeCacheStateChange(NodeChangeType type)
143 {
144 #ifdef DDGR_ENABLE_FEATURE_OPINC_DFX
145 RS_TRACE_NAME_FMT("NodeCacheStateChange %llx, type:%d r%d unc:%d uncU:%d",
146 GetId(), type, nodeCacheState_, unchangeCount_, unchangeCountUpper_);
147 #endif
148 switch (type) {
149 case NodeChangeType::KEEP_UNCHANGE:
150 unchangeCount_++;
151 if (unchangeCount_ > unchangeCountUpper_) {
152 nodeCacheState_ = NodeCacheState::STATE_UNCHANGE;
153 }
154 if (stagingRenderParams_) {
155 stagingRenderParams_->OpincSetCacheChangeFlag(false, lastFrameSynced_);
156 }
157 break;
158 case NodeChangeType::SELF_DIRTY:
159 NodeCacheStateReset(NodeCacheState::STATE_CHANGE);
160 break;
161 }
162 }
163
SetCacheStateByRetrytime()164 void RSRenderNode::SetCacheStateByRetrytime()
165 {
166 tryCacheTimes_++;
167 if (tryCacheTimes_ < MAX_TRY_TIMES) {
168 unchangeCountUpper_ = unchangeCountUpper_ + MIN_REUSECOUNT;
169 return;
170 }
171 unchangeCountUpper_ = unchangeCountUpper_ + MAX_REUSECOUNT;
172 }
173
NodeCacheStateReset(NodeCacheState nodeCacheState)174 void RSRenderNode::NodeCacheStateReset(NodeCacheState nodeCacheState)
175 {
176 nodeCacheState_ = nodeCacheState;
177 unchangeCount_ = 0;
178 isUnchangeMarkInApp_ = false;
179 isUnchangeMarkEnable_ = false;
180 if (OpincGetRootFlag()) {
181 SetCacheStateByRetrytime();
182 }
183 if (stagingRenderParams_) {
184 stagingRenderParams_->OpincSetCacheChangeFlag(true, lastFrameSynced_);
185 stagingRenderParams_->OpincUpdateRootFlag(false);
186 }
187 isOpincRootFlag_ = false;
188 }
189 } // namespace Rosen
190 } // namespace OHOS
191