b0fde87fd5fd545efb4cdb0c86b43468c28ab79e
[framework/osp/uifw.git] / src / ui / animations / FUiAnim_DisplayManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FUiAnim_DisplayManager.cpp
20  * @brief       This file contains implementation of _DisplayManager class
21  *
22  * This file contains implementation _DisplayManager class.
23  */
24 #include <Ecore.h>
25 #include <new>
26 #include <FBaseSysLog.h>
27 #include "FUiAnim_NativeLayer.h"
28 #include "FUiAnim_RootVisualElement.h"
29 #include "FUiAnim_VisualElementImpl.h"
30 #include "FUiAnim_VisualElementEnvironment.h"
31 #include "FUiAnim_AnimationManager.h"
32 #include "FUiAnim_DisplayManager.h"
33
34 using namespace Tizen;
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::Ui::Animations;
38
39
40 namespace
41 {
42 Eina_Bool
43 WakeupEventCallback(void* pData, int type, void* pEvent)
44 {
45         _DisplayManager::__wakeUpEventAdded = false;
46
47         return ECORE_CALLBACK_PASS_ON;
48 }
49
50 }
51
52 namespace Tizen { namespace Ui { namespace Animations
53 {
54 int _DisplayManager::__eventType = 0;
55 void* _DisplayManager::__pWakeUpEventHandler = null;
56 bool _DisplayManager::__wakeUpEventAdded = false;
57 _DisplayManager* _DisplayManager::__pInstance = null;
58
59 _DisplayManager::_DisplayManager(void)
60         : __roots()
61 {
62         __roots.Construct();
63 }
64
65 _DisplayManager::~_DisplayManager(void)
66 {
67         while (__roots.GetCount() > 0)
68         {
69                 _RootVisualElement* pRoot = static_cast< _RootVisualElement* >(__roots.GetAt(0));
70
71                 pRoot->Destroy();
72                 __roots.RemoveAt(0);
73         }
74 }
75
76 result
77 _DisplayManager::CreateInstance(void)
78 {
79         SysTryReturnResult(NID_UI_ANIM, !__pInstance, E_OBJ_ALREADY_EXIST, "The display manager is already created.");
80
81         __pInstance = new (std::nothrow) _DisplayManager();
82         if (!__pInstance)
83         {
84                 return E_OUT_OF_MEMORY;
85         }
86
87         _VisualElementEnvironment::Initialize();
88
89         // for wake up event
90         __eventType = ecore_event_type_new();
91         __pWakeUpEventHandler = (void*)ecore_event_handler_add(__eventType, WakeupEventCallback, null);
92
93         return E_SUCCESS;
94 }
95
96 result
97 _DisplayManager::ReleaseInstance(void)
98 {
99         SysTryReturnResult(NID_UI_ANIM, __pInstance, E_INVALID_STATE, "The display manager is not created.");
100
101         if (__pWakeUpEventHandler)
102         {
103                 ecore_event_handler_del((Ecore_Event_Handler*)__pWakeUpEventHandler);
104         }
105
106         delete __pInstance;
107         __pInstance = null;
108
109         return E_SUCCESS;
110 }
111
112 _RootVisualElement*
113 _DisplayManager::CreateRoot(void)
114 {
115         _RootVisualElement* pRoot = new (std::nothrow) _RootVisualElement();
116         if (!pRoot)
117         {
118                 return null;
119         }
120
121         pRoot->Construct();
122         pRoot->SetImplicitAnimationEnabled(false);
123         pRoot->SetShowState(true);
124
125         RegisterRoot(*pRoot);
126
127         return pRoot;
128 }
129
130 result
131 _DisplayManager::DestroyRoot(_RootVisualElement& root)
132 {
133         result r = UnregisterRoot(root);
134
135         if (r != E_SUCCESS)
136         {
137                 SysLogException(NID_UI_ANIM, E_INVALID_ARG, "[E_INVALID_ARG] root is not managed in the DisplayManager" );
138         }
139
140         root.Destroy();
141
142         return E_SUCCESS;
143 }
144
145 result
146 _DisplayManager::RegisterRoot(_RootVisualElement& root)
147 {
148         return __roots.Add(root);
149 }
150
151 result
152 _DisplayManager::UnregisterRoot(_RootVisualElement& root)
153 {
154         return __roots.Remove(root);
155 }
156
157 int
158 _DisplayManager::GetRootCount(void) const
159 {
160         return __roots.GetCount();
161 }
162
163 _RootVisualElement*
164 _DisplayManager::GetRoot(int index) const
165 {
166         const _RootVisualElement* pRoot = static_cast< const _RootVisualElement* >(__roots.GetAt(index));
167         return const_cast< _RootVisualElement* >(pRoot);
168 }
169
170 void
171 _DisplayManager::AddWakeUpEvent(void)
172 {
173         if (!__wakeUpEventAdded)
174         {
175                 ecore_event_add(__eventType, NULL, NULL, NULL);
176                 __wakeUpEventAdded = true;
177         }
178 }
179
180 bool
181 _DisplayManager::RenderAll(void)
182 {
183         bool needUpdate = false;
184         int count = __roots.GetCount();
185         if (count > 0)
186         {
187                 for (int i = 0; i < count; i++)
188                 {
189                         _RootVisualElement* pRoot = static_cast< _RootVisualElement* >(__roots.GetAt(i));
190                         if (likely(pRoot))
191                         {
192                                 bool updated = Render(*pRoot);
193
194                                 needUpdate |= updated;
195
196                                 if (updated)
197                                 {
198                                         _NativeLayer* pLayer = pRoot->GetNativeLayer();
199                                         if (likely(pLayer))
200                                         {
201                                                 pLayer->SetFlushNeeded();
202                                         }
203                                 }
204
205                                 PostRender(*pRoot);
206                         }
207                 }
208         }
209
210         return needUpdate;
211 }
212
213 bool
214 _DisplayManager::Render(_RootVisualElement& root)
215 {
216         // VisualElement Rendering
217         // Fill contents
218
219         // Prevent recursion for rendering !
220
221         // WARNING:
222         //      EFL BUG !!!!!
223         //      if the contents of evas object image is changed with geometry change,
224         //      damage area is not calculated correctly !!! when event freeze/thaw enabled.
225         //      --> artifact occurs
226
227         //evas_event_freeze(__pEvas);
228
229         bool updated = false;
230
231         _RootVisualElement* pPresentationRoot = static_cast< _RootVisualElement* >(const_cast<VisualElement*>(root.AcquirePresentationInstance()));
232         if (pPresentationRoot)
233         {
234                 _VisualElementImpl* pRootModelImpl = _VisualElementImpl::GetInstance(root);
235                 _VisualElementImpl* pRootPresentationImpl = _VisualElementImpl::GetInstance(*pPresentationRoot);
236
237                 if (likely(pRootModelImpl) && likely(pRootPresentationImpl))
238                 {
239                         //-------------------;
240                         //
241                         if (//likely((pRootModelImpl->__childrenNeedsUpdateProps) != 0) ||
242                                 likely(pRootPresentationImpl->__childrenNeedsUpdateProps != 0) ||
243                                 likely(pRootPresentationImpl->__pSharedData->NeedNativeReconfigure()) ||
244                                 unlikely(root.GetNeedsContentUpdate()) ||
245                                 unlikely(pPresentationRoot->GetNeedsContentUpdate()))
246                         {
247                                 root.SetNeedsContentUpdate(false);
248                                 pRootModelImpl->Draw();
249
250                                 pPresentationRoot->SetNeedsContentUpdate(false);
251                                 pRootPresentationImpl->Draw();
252
253                                 updated = true;
254                         }
255                 }
256         }
257         root.ReleasePresentationInstance();
258
259
260         //evas_event_thaw(__pEvas);
261         //evas_event_thaw_eval(__pEvas); // CHECKME: needed ???
262
263         return updated;
264 }
265
266 result
267 _DisplayManager::PostRender(_RootVisualElement& root)
268 {
269 //      _ElapsedTime foo("PostRender");
270
271
272         _RootVisualElement* pPresentationRoot = static_cast< _RootVisualElement* >(const_cast<VisualElement*>(root.AcquirePresentationInstance()));
273         if (likely(pPresentationRoot))
274         {
275                 _VisualElementImpl* pRootPresentationImpl = _VisualElementImpl::GetInstance(*pPresentationRoot);
276
277                 if (likely(pRootPresentationImpl->__childrenNeedsUpdateProps) ||
278                         likely(pRootPresentationImpl->__pSharedData->NeedNativeReconfigure()) ||
279                         unlikely(root.GetNeedsContentUpdate()) ||
280                         unlikely(pPresentationRoot->GetNeedsContentUpdate()))
281                 {
282                         // CHECKME:
283                         //      We need wake-up main-loop for VE to be validated(draw) on next loop iteration.
284                         //      Is there another good method for this???
285
286                         AddWakeUpEvent();
287                 }
288         }
289         root.ReleasePresentationInstance();
290
291         return E_SUCCESS;
292 }
293
294 result
295 _DisplayManager::Flush(void)
296 {
297         int count = __roots.GetCount();
298         if (count > 0)
299         {
300                 for (int i = 0; i < count; i++)
301                 {
302                         _RootVisualElement* pRoot = static_cast< _RootVisualElement* >(__roots.GetAt(i));
303                         if (likely(pRoot))
304                         {
305                                 _NativeLayer* pLayer = pRoot->GetNativeLayer();
306
307 //CHECK ME : when evas marked update flag.
308 //                              if (pLayer && pLayer->IsFlushNeeded())
309                                 {
310                                         pLayer->Flush();
311                                         pLayer->ResetFlushNeeded();
312                                 }
313                         }
314                 }
315         }
316
317         return E_SUCCESS;
318 }
319
320
321
322
323 }}}             // Tizen::Ui::Animations
324