• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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 "core/render_manager.h"
17 
18 #include "components/root_view.h"
19 #include "gfx_utils/graphic_log.h"
20 #include "hal_tick.h"
21 #include "securec.h"
22 #if ENABLE_WINDOW
23 #include "window/window_impl.h"
24 #endif
25 
26 namespace OHOS {
RenderManager()27 RenderManager::RenderManager() : fps_(0.f), needResetFPS_(true), onFPSChangedListener_(nullptr) {}
28 
~RenderManager()29 RenderManager::~RenderManager() {}
30 
GetInstance()31 RenderManager& RenderManager::GetInstance()
32 {
33     static RenderManager instance;
34     return instance;
35 }
36 
Init()37 void RenderManager::Init()
38 {
39     Task::Init();
40 }
41 
Callback()42 void RenderManager::Callback()
43 {
44 #if ENABLE_WINDOW
45     ListNode<Window*>* winNode = winList_.Begin();
46     while (winNode != winList_.End()) {
47         WindowImpl* windowImpl = reinterpret_cast<WindowImpl*>(winNode->data_);
48         windowImpl->Render();
49         winNode = winNode->next_;
50     }
51 #else
52     RootView::GetInstance()->Measure();
53     RootView::GetInstance()->Render();
54 #endif
55 
56 #if ENABLE_FPS_SUPPORT
57     UpdateFPS();
58 #endif
59 }
60 
61 #if ENABLE_FPS_SUPPORT
UpdateFPS()62 void RenderManager::UpdateFPS()
63 {
64     SysInfo::FPSCalculateType type = SysInfo::FPS_CT_FIXED_TIME;
65     if (onFPSChangedListener_) {
66         type = onFPSChangedListener_->GetFPSCalculateType();
67     }
68     if (type == SysInfo::FPS_CT_FIXED_TIME) {
69         UpdateFPSByFixedTimeMethod();
70     } else if (type == SysInfo::FPS_CT_AVERAGE_SAMPLING) {
71         UpdateFPSByAverageSamplingMethod();
72     } else if (type == SysInfo::FPS_CT_PRECISE_SAMPLING) {
73         UpdateFPSByPreciseSamplingMethod();
74     }
75     OnFPSChanged(fps_);
76 }
77 
UpdateFPSByFixedTimeMethod()78 void RenderManager::UpdateFPSByFixedTimeMethod()
79 {
80     static uint16_t frameCount = 0;
81     static uint32_t lastTime = HALTick::GetInstance().GetTime();
82     if (needResetFPS_) {
83         frameCount = 0;
84         lastTime = HALTick::GetInstance().GetTime();
85         needResetFPS_ = false;
86         fps_ = 0.f;
87         return;
88     }
89 
90     frameCount++;
91 
92     uint32_t curTime = HALTick::GetInstance().GetTime();
93     if (curTime - lastTime > MILLISECONDS_PER_SECOND) {
94         fps_ = 1.f * frameCount / (curTime - lastTime) * MILLISECONDS_PER_SECOND;
95         fps_ = (fps_ > MAX_FPS) ? MAX_FPS : fps_;
96         frameCount = 0;
97         lastTime = curTime;
98     }
99 }
100 
UpdateFPSByAverageSamplingMethod()101 void RenderManager::UpdateFPSByAverageSamplingMethod()
102 {
103     static float avgDuration = 0.f;
104     static float alpha = 1.f / SAMPLE_NUMBER;
105     static bool firstFrame = true;
106     static uint32_t lastTime = HALTick::GetInstance().GetTime();
107     if (needResetFPS_) {
108         avgDuration = 0.f;
109         alpha = 1.f / SAMPLE_NUMBER;
110         firstFrame = true;
111         lastTime = HALTick::GetInstance().GetTime();
112         needResetFPS_ = false;
113         fps_ = 0.f;
114         return;
115     }
116     uint32_t curTime = HALTick::GetInstance().GetTime();
117     int32_t deltaTime = curTime - lastTime;
118     lastTime = curTime;
119 
120     if (firstFrame) {
121         avgDuration = static_cast<float>(deltaTime);
122         firstFrame = false;
123     } else {
124         avgDuration = avgDuration * (1 - alpha) + deltaTime * alpha;
125     }
126     fps_ = 1.f / avgDuration * MILLISECONDS_PER_SECOND;
127 }
128 
UpdateFPSByPreciseSamplingMethod()129 void RenderManager::UpdateFPSByPreciseSamplingMethod()
130 {
131     static int32_t deltaTimeQueue[SAMPLE_NUMBER] = {0};
132     static int32_t frameCount = 0;
133     static int32_t sumDuration = 0;
134     static bool isQueueFull = false;
135     static uint32_t lastTime = HALTick::GetInstance().GetTime();
136     if (needResetFPS_) {
137         if (memset_s(deltaTimeQueue, sizeof(deltaTimeQueue), 0, sizeof(deltaTimeQueue)) != EOK) {
138             return;
139         }
140         frameCount = 0;
141         sumDuration = 0;
142         isQueueFull = false;
143         lastTime = HALTick::GetInstance().GetTime();
144         needResetFPS_ = false;
145         fps_ = 0.f;
146         return;
147     }
148     uint32_t curTime = HALTick::GetInstance().GetTime();
149     int32_t deltaTime = curTime - lastTime;
150     lastTime = curTime;
151 
152     if (!isQueueFull && (frameCount == SAMPLE_NUMBER)) {
153         isQueueFull = true;
154     }
155     frameCount %= SAMPLE_NUMBER;
156     sumDuration -= deltaTimeQueue[frameCount];
157     sumDuration += deltaTime;
158     deltaTimeQueue[frameCount++] = deltaTime;
159     if (isQueueFull) {
160         fps_ = 1.f * SAMPLE_NUMBER / sumDuration * MILLISECONDS_PER_SECOND;
161     } else {
162         fps_ = 1.f * frameCount / sumDuration * MILLISECONDS_PER_SECOND;
163     }
164 }
165 #endif
166 
RenderRect(const Rect & rect,RootView * rootView)167 void RenderManager::RenderRect(const Rect& rect, RootView* rootView)
168 {
169     if (rootView == nullptr) {
170         return;
171     }
172 
173     Rect mask = rect;
174 #if ENABLE_WINDOW
175     if (rootView->GetBoundWindow()) {
176         Rect winRect = rootView->GetBoundWindow()->GetRect();
177         winRect.SetPosition(0, 0);
178         mask.Intersect(rect, winRect);
179     }
180 #endif
181 #if LOCAL_RENDER
182     rootView->DrawInvalidMap(mask);
183 #else
184     UIView* topView = rootView->GetTopUIView(mask);
185     rootView->DrawTop(topView, mask);
186 #endif
187 }
188 
RefreshScreen()189 void RenderManager::RefreshScreen()
190 {
191 #if ENABLE_WINDOW
192     ListNode<Window*>* winNode = winList_.Begin();
193     while (winNode != winList_.End()) {
194         WindowImpl* windowImpl = reinterpret_cast<WindowImpl*>(winNode->data_);
195         RootView* rootView = windowImpl->GetRootView();
196         if (rootView == nullptr) {
197             winNode = winNode->next_;
198             continue;
199         }
200         rootView->Invalidate();
201         winNode = winNode->next_;
202     }
203 #else
204     RootView::GetInstance()->Invalidate();
205 #endif
206 }
207 
208 #if ENABLE_WINDOW
AddToDisplay(Window * window)209 void RenderManager::AddToDisplay(Window* window)
210 {
211     if (window == nullptr) {
212         return;
213     }
214     winList_.PushBack(window);
215 }
216 
RemoveFromDisplay(Window * window)217 void RenderManager::RemoveFromDisplay(Window* window)
218 {
219     if (window == nullptr) {
220         return;
221     }
222     ListNode<Window*>* winNode = winList_.Begin();
223     while (winNode != winList_.End()) {
224         if (winNode->data_ == window) {
225             winList_.Remove(winNode);
226             return;
227         }
228         winNode = winNode->next_;
229     }
230 }
231 #endif
232 } // namespace OHOS
233