• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 "feature/opinc/rs_opinc_cache.h"
17 #ifdef DDGR_ENABLE_FEATURE_OPINC_DFX
18 #include "string_utils.h"
19 #endif
20 #include "common/rs_optional_trace.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 
25 constexpr int64_t MIN_REUSECOUNT = 10;
26 constexpr int64_t MAX_REUSECOUNT = 20;
27 constexpr int32_t MAX_TRY_TIMES = 3;
28 constexpr int32_t MIN_UNCHANGE_COUNT = 3;
29 constexpr int32_t MAX_UNCHANGE_COUNT = 100;
30 constexpr int32_t INIT_WAIT_COUNT = 60;
31 
32 // mark stable node
OpincSetInAppStateStart(bool & unchangeMarkInApp)33 void RSOpincCache::OpincSetInAppStateStart(bool& unchangeMarkInApp)
34 {
35     if (unchangeMarkInApp) {
36         return;
37     }
38     isUnchangeMarkInApp_ = true;
39     unchangeMarkInApp = true;
40 }
41 
OpincSetInAppStateEnd(bool & unchangeMarkInApp)42 void RSOpincCache::OpincSetInAppStateEnd(bool& unchangeMarkInApp)
43 {
44     if (isUnchangeMarkInApp_) {
45         isUnchangeMarkInApp_ = false;
46         unchangeMarkInApp = false;
47     }
48 }
49 
OpincQuickMarkStableNode(bool & unchangeMarkInApp,bool & unchangeMarkEnable,bool isSelfDirty)50 void RSOpincCache::OpincQuickMarkStableNode(bool& unchangeMarkInApp, bool& unchangeMarkEnable,
51     bool isSelfDirty)
52 {
53     if (!unchangeMarkInApp) {
54         return;
55     }
56     if (IsSuggestOpincNode() && !unchangeMarkEnable) {
57         isUnchangeMarkEnable_ = true;
58         unchangeMarkEnable = true;
59     }
60     if (!unchangeMarkEnable) {
61         return;
62     }
63     if (isSelfDirty) {
64         NodeCacheStateChange(NodeChangeType::SELF_DIRTY);
65     } else if (nodeCacheState_ != NodeCacheState::STATE_UNCHANGE) {
66         NodeCacheStateChange(NodeChangeType::KEEP_UNCHANGE);
67     } else {
68         if (waitCount_ > 0) {
69             waitCount_--;
70         } else {
71             unchangeCountUpper_ = MIN_UNCHANGE_COUNT;
72         }
73     }
74 }
75 
UpdateSubTreeSupportFlag(bool childSupportFlag,bool childRootFlag,bool groupTypeIsNone)76 void RSOpincCache::UpdateSubTreeSupportFlag(bool childSupportFlag, bool childRootFlag, bool groupTypeIsNone)
77 {
78     subTreeSupportFlag_ = subTreeSupportFlag_ && childSupportFlag && !childRootFlag && groupTypeIsNone;
79 }
80 
OpincUpdateRootFlag(bool & unchangeMarkEnable,bool isOpincNodeSupportFlag)81 void RSOpincCache::OpincUpdateRootFlag(bool& unchangeMarkEnable, bool isOpincNodeSupportFlag)
82 {
83     if (unchangeMarkEnable) {
84         if (IsOpincUnchangeState() && isOpincNodeSupportFlag) {
85             isOpincRootFlag_ = true;
86         }
87     }
88     if (isUnchangeMarkEnable_) {
89         isUnchangeMarkEnable_ = false;
90         unchangeMarkEnable = false;
91     }
92 }
93 
IsOpincUnchangeState()94 bool RSOpincCache::IsOpincUnchangeState()
95 {
96     return (nodeCacheState_ == NodeCacheState::STATE_UNCHANGE) && IsSuggestOpincNode();
97 }
98 
IsMarkedRenderGroup(bool groupTypeNotNone)99 bool RSOpincCache::IsMarkedRenderGroup(bool groupTypeNotNone)
100 {
101     return groupTypeNotNone || isOpincRootFlag_;
102 }
103 
OpincForcePrepareSubTree(bool autoCacheEnable,bool isDirty,bool supportFlag)104 bool RSOpincCache::OpincForcePrepareSubTree(bool autoCacheEnable, bool isDirty, bool supportFlag)
105 {
106     if (!autoCacheEnable) {
107         return false;
108     }
109     // Non-root nodes that support opinc and are marked by arkui need to forcibly prepare subtrees
110     // until they are marked as root
111     return (!isDirty) && IsSuggestOpincNode() && supportFlag && !isOpincRootFlag_;
112 }
113 
OpincGetRootFlag() const114 bool RSOpincCache::OpincGetRootFlag() const
115 {
116     return isOpincRootFlag_;
117 }
118 
GetCacheChangeFlag() const119 bool RSOpincCache::GetCacheChangeFlag() const
120 {
121     return cacheChangeFlag_;
122 }
123 
124 // arkui mark
MarkSuggestOpincNode(bool isOpincNode,bool isNeedCalculate)125 void RSOpincCache::MarkSuggestOpincNode(bool isOpincNode, bool isNeedCalculate)
126 {
127     isSuggestOpincNode_ = isOpincNode;
128     isNeedCalculate_ = isNeedCalculate;
129     NodeCacheStateReset(NodeCacheState::STATE_CHANGE);
130 }
131 
IsSuggestOpincNode() const132 bool RSOpincCache::IsSuggestOpincNode() const
133 {
134     return isSuggestOpincNode_;
135 }
136 
NodeCacheStateChange(NodeChangeType type)137 void RSOpincCache::NodeCacheStateChange(NodeChangeType type)
138 {
139 #ifdef DDGR_ENABLE_FEATURE_OPINC_DFX
140     RS_TRACE_NAME_FMT("NodeCacheStateChange type:%d r%d unc:%d uncU:%d",
141         type, nodeCacheState_, unchangeCount_, unchangeCountUpper_);
142 #endif
143     switch (type) {
144         case NodeChangeType::KEEP_UNCHANGE:
145             unchangeCount_++;
146             if (unchangeCount_ > unchangeCountUpper_) {
147                 nodeCacheState_ = NodeCacheState::STATE_UNCHANGE;
148             }
149             cacheChangeFlag_ = false;
150             break;
151         case NodeChangeType::SELF_DIRTY:
152             NodeCacheStateReset(NodeCacheState::STATE_CHANGE);
153             break;
154     }
155 }
156 
SetCacheStateByRetrytime()157 void RSOpincCache::SetCacheStateByRetrytime()
158 {
159     tryCacheTimes_++;
160     if (unchangeCountUpper_ > MAX_UNCHANGE_COUNT) {
161         return;
162     }
163     if (tryCacheTimes_ < MAX_TRY_TIMES) {
164         unchangeCountUpper_ = unchangeCountUpper_ + MIN_REUSECOUNT;
165         return;
166     }
167     unchangeCountUpper_ = unchangeCountUpper_ + MAX_REUSECOUNT;
168 }
169 
NodeCacheStateReset(NodeCacheState nodeCacheState)170 void RSOpincCache::NodeCacheStateReset(NodeCacheState nodeCacheState)
171 {
172     if (nodeCacheState_ == NodeCacheState::STATE_UNCHANGE) {
173         waitCount_ = INIT_WAIT_COUNT;
174     }
175     nodeCacheState_ = nodeCacheState;
176     unchangeCount_ = 0;
177     isUnchangeMarkInApp_ = false;
178     isUnchangeMarkEnable_ = false;
179     if (OpincGetRootFlag()) {
180         SetCacheStateByRetrytime();
181     }
182     cacheChangeFlag_ = true;
183     isOpincRootFlag_ = false;
184 }
185 } // namespace Rosen
186 } // namespace OHOS
187