Applied context restoring
[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 _DisplayManager::RestoreContextCallback _DisplayManager::__pRestoreContextCallback = null;
59
60 _DisplayManager::_DisplayManager(void)
61         : __roots()
62 {
63         __roots.Construct();
64 }
65
66 _DisplayManager::~_DisplayManager(void)
67 {
68         while (__roots.GetCount() > 0)
69         {
70                 _RootVisualElement* pRoot = static_cast< _RootVisualElement* >(__roots.GetAt(0));
71
72                 pRoot->Destroy();
73                 __roots.RemoveAt(0);
74         }
75 }
76
77 result
78 _DisplayManager::CreateInstance(void)
79 {
80         SysTryReturnResult(NID_UI_ANIM, !__pInstance, E_OBJ_ALREADY_EXIST, "The display manager is already created.");
81
82         __pInstance = new (std::nothrow) _DisplayManager();
83         if (!__pInstance)
84         {
85                 return E_OUT_OF_MEMORY;
86         }
87
88         _VisualElementEnvironment::Initialize();
89
90         // for wake up event
91         __eventType = ecore_event_type_new();
92         __pWakeUpEventHandler = (void*)ecore_event_handler_add(__eventType, WakeupEventCallback, null);
93
94         return E_SUCCESS;
95 }
96
97 result
98 _DisplayManager::ReleaseInstance(void)
99 {
100         SysTryReturnResult(NID_UI_ANIM, __pInstance, E_INVALID_STATE, "The display manager is not created.");
101
102         if (__pWakeUpEventHandler)
103         {
104                 ecore_event_handler_del((Ecore_Event_Handler*)__pWakeUpEventHandler);
105         }
106
107         delete __pInstance;
108         __pInstance = null;
109
110         return E_SUCCESS;
111 }
112
113 _RootVisualElement*
114 _DisplayManager::CreateRoot(void)
115 {
116         _RootVisualElement* pRoot = new (std::nothrow) _RootVisualElement();
117         if (!pRoot)
118         {
119                 return null;
120         }
121
122         pRoot->Construct();
123         pRoot->SetImplicitAnimationEnabled(false);
124         pRoot->SetShowState(true);
125
126         RegisterRoot(*pRoot);
127
128         return pRoot;
129 }
130
131 result
132 _DisplayManager::DestroyRoot(_RootVisualElement& root)
133 {
134         result r = UnregisterRoot(root);
135
136         if (r != E_SUCCESS)
137         {
138                 SysLogException(NID_UI_ANIM, E_INVALID_ARG, "[E_INVALID_ARG] root is not managed in the DisplayManager" );
139         }
140
141         root.Destroy();
142
143         return E_SUCCESS;
144 }
145
146 result
147 _DisplayManager::RegisterRoot(_RootVisualElement& root)
148 {
149         return __roots.Add(root);
150 }
151
152 result
153 _DisplayManager::UnregisterRoot(_RootVisualElement& root)
154 {
155         return __roots.Remove(root);
156 }
157
158 int
159 _DisplayManager::GetRootCount(void) const
160 {
161         return __roots.GetCount();
162 }
163
164 _RootVisualElement*
165 _DisplayManager::GetRoot(int index) const
166 {
167         const _RootVisualElement* pRoot = static_cast< const _RootVisualElement* >(__roots.GetAt(index));
168         return const_cast< _RootVisualElement* >(pRoot);
169 }
170
171 void
172 _DisplayManager::AddWakeUpEvent(void)
173 {
174         if (!__wakeUpEventAdded)
175         {
176                 ecore_event_add(__eventType, NULL, NULL, NULL);
177                 __wakeUpEventAdded = true;
178         }
179 }
180
181 bool
182 _DisplayManager::RenderAll(void)
183 {
184         bool needUpdate = false;
185         int count = __roots.GetCount();
186         if (count > 0)
187         {
188                 for (int i = 0; i < count; i++)
189                 {
190                         _RootVisualElement* pRoot = static_cast< _RootVisualElement* >(__roots.GetAt(i));
191                         if (likely(pRoot))
192                         {
193                                 bool updated = Render(*pRoot);
194
195                                 needUpdate |= updated;
196
197                                 if (updated)
198                                 {
199                                         _NativeLayer* pLayer = pRoot->GetNativeLayer();
200                                         if (likely(pLayer))
201                                         {
202                                                 pLayer->SetFlushNeeded();
203                                         }
204                                 }
205
206                                 PostRender(*pRoot);
207                         }
208                 }
209         }
210
211         return needUpdate;
212 }
213
214 bool
215 _DisplayManager::Render(_RootVisualElement& root)
216 {
217         // VisualElement Rendering
218         // Fill contents
219
220         // Prevent recursion for rendering !
221
222         // WARNING:
223         //      EFL BUG !!!!!
224         //      if the contents of evas object image is changed with geometry change,
225         //      damage area is not calculated correctly !!! when event freeze/thaw enabled.
226         //      --> artifact occurs
227
228         //evas_event_freeze(__pEvas);
229
230         bool updated = false;
231
232         _RootVisualElement* pPresentationRoot = static_cast< _RootVisualElement* >(const_cast<VisualElement*>(root.AcquirePresentationInstance()));
233         if (pPresentationRoot)
234         {
235                 _VisualElementImpl* pRootModelImpl = _VisualElementImpl::GetInstance(root);
236                 _VisualElementImpl* pRootPresentationImpl = _VisualElementImpl::GetInstance(*pPresentationRoot);
237
238                 if (likely(pRootModelImpl) && likely(pRootPresentationImpl))
239                 {
240                         //-------------------;
241                         //
242                         if (//likely((pRootModelImpl->__childrenNeedsUpdateProps) != 0) ||
243                                 likely(pRootPresentationImpl->__childrenNeedsUpdateProps != 0) ||
244                                 likely(pRootPresentationImpl->__pSharedData->NeedNativeReconfigure()) ||
245                                 unlikely(root.GetNeedsContentUpdate()) ||
246                                 unlikely(pPresentationRoot->GetNeedsContentUpdate()))
247                         {
248                                 root.SetNeedsContentUpdate(false);
249                                 pRootModelImpl->Draw();
250
251                                 pPresentationRoot->SetNeedsContentUpdate(false);
252                                 pRootPresentationImpl->Draw();
253
254                                 updated = true;
255                         }
256                 }
257         }
258         root.ReleasePresentationInstance();
259
260
261         //evas_event_thaw(__pEvas);
262         //evas_event_thaw_eval(__pEvas); // CHECKME: needed ???
263
264         return updated;
265 }
266
267 result
268 _DisplayManager::PostRender(_RootVisualElement& root)
269 {
270 //      _ElapsedTime foo("PostRender");
271
272
273         _RootVisualElement* pPresentationRoot = static_cast< _RootVisualElement* >(const_cast<VisualElement*>(root.AcquirePresentationInstance()));
274         if (likely(pPresentationRoot))
275         {
276                 _VisualElementImpl* pRootPresentationImpl = _VisualElementImpl::GetInstance(*pPresentationRoot);
277
278                 if (likely(pRootPresentationImpl->__childrenNeedsUpdateProps) ||
279                         likely(pRootPresentationImpl->__pSharedData->NeedNativeReconfigure()) ||
280                         unlikely(root.GetNeedsContentUpdate()) ||
281                         unlikely(pPresentationRoot->GetNeedsContentUpdate()))
282                 {
283                         // CHECKME:
284                         //      We need wake-up main-loop for VE to be validated(draw) on next loop iteration.
285                         //      Is there another good method for this???
286
287                         AddWakeUpEvent();
288                 }
289         }
290         root.ReleasePresentationInstance();
291
292         return E_SUCCESS;
293 }
294
295 result
296 _DisplayManager::Flush(void)
297 {
298         int count = __roots.GetCount();
299         if (count > 0)
300         {
301                 for (int i = 0; i < count; i++)
302                 {
303                         _RootVisualElement* pRoot = static_cast< _RootVisualElement* >(__roots.GetAt(i));
304                         if (likely(pRoot))
305                         {
306                                 _NativeLayer* pLayer = pRoot->GetNativeLayer();
307
308 //CHECK ME : when evas marked update flag.
309 //                              if (pLayer && pLayer->IsFlushNeeded())
310                                 {
311                                         pLayer->Flush();
312                                         pLayer->ResetFlushNeeded();
313                                 }
314                         }
315                 }
316         }
317
318         return E_SUCCESS;
319 }
320
321 void
322 _DisplayManager::SetRestoreContextCallback(RestoreContextCallback pRestoreContextCallback)
323 {
324         __pRestoreContextCallback = pRestoreContextCallback;
325 }
326
327 void
328 _DisplayManager::RestoreContext(void)
329 {
330         if (__pRestoreContextCallback)
331         {
332                 (*__pRestoreContextCallback)();
333         }
334 }
335
336 }}}             // Tizen::Ui::Animations
337