2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0/
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.
19 * @file FUiAnim_EflLayer.cpp
20 * @brief This file contains implementation of _EflLayer class
22 * This file contains implementation _EflLayer class.
27 #include <Elementary.h>
29 #include <FBaseErrors.h>
30 #include <FBaseSysLog.h>
32 #include <FGrpFloatRectangle.h>
33 #include "FUiAnim_NativeLayer.h"
34 #include "FUiAnim_EflLayer.h"
35 #include "FUiAnim_EflNode.h"
36 #include "FUiAnim_RootVisualElement.h"
37 #include "FUiAnim_AnimationManager.h"
38 #include "FUiAnim_DisplayManager.h"
42 using namespace Tizen;
43 using namespace Tizen::Graphics;
44 using namespace Tizen::Ui;
45 using namespace Tizen::Ui::Animations;
47 //#define _NEED_DAMAGE_HANDER_
49 //#define PRINT printf
58 #ifdef VE_VSYNC_UPDATE
60 Ecore_Idle_Enterer* __pOnIdleLoopIterator = null;
63 //static const double fpsLimitInterval = 1.0 / 55.0;
66 OnIdleLoopIterate(void* pData)
68 _DisplayManager* pDisplayManager = _DisplayManager::GetInstance();
70 // PRINT("OnIdleLoopIterate()\n");
75 return ECORE_CALLBACK_CANCEL; // for remove callback
78 Tizen::Ui::Animations::_AnimationManager* pAnimationManager = Tizen::Ui::Animations::_AnimationManager::GetInstance();
80 if (!pAnimationManager)
82 return ECORE_CALLBACK_CANCEL; // for remove callback
85 //CHECK ME : how about the performance?
86 // double currentTime = ecore_time_get();
87 // static double prevFlushTime = 0;
89 // if (currentTime - prevFlushTime >= fpsLimitInterval * 0.99)
91 pAnimationManager->ProcessAnimationTick();
93 // prevFlushTime = currentTime;
95 pDisplayManager->RenderAll();
97 pDisplayManager->Flush();
100 return ECORE_CALLBACK_RENEW;
103 // WARNING: Without this, idle-enterer will be called after evas destroyed which may cause crash while accessing ecore-evas.
105 OnEcoreEvasFree(Ecore_Evas* pEcoreEvas)
107 ecore_evas_manual_render_set(pEcoreEvas, EINA_FALSE);
112 #ifdef _NEED_DAMAGE_HANDER_
115 OnXWindowDamaged(void* pData __UNUSED__, int type __UNUSED__, void* pEventInfo)
118 _Ecore_X_Event_Window_Damage* pEvent = (_Ecore_X_Event_Window_Damage*)pEventInfo;
122 _EflLayer* pLayer = (_EflLayer*)pData;
124 if (pLayer->GetEvas() && pLayer->GetEcoreEvas() && pEvent->win == ecore_evas_window_get(pLayer->GetEcoreEvas()))
126 FloatRectangle bounds = pLayer->GetBounds();
128 evas_damage_rectangle_add(pLayer->GetEvas(), 0, 0, (int)bounds.width, (int)bounds.height);
129 pLayer->SetEvasRenderNeeded();
131 _DisplayManager::GetInstance()->AddWakeUpEvent();
133 PRINT("OnXWindowDamaged(%p)[%d,%d,%d,%d]------------\n", pLayer->GetEvas(), pEvent->x, pEvent->y, pEvent->w, pEvent->h);
141 OnXWindowConfigured(void* pData, int type, void* pEventInfo)
144 _Ecore_X_Event_Window_Configure* pEvent = (_Ecore_X_Event_Window_Configure*)pEventInfo;
148 _EflLayer* pLayer = (_EflLayer*)pData;
150 if (pLayer->GetEvas() && pLayer->GetEcoreEvas() && pEvent->win == ecore_evas_window_get(pLayer->GetEcoreEvas()))
152 FloatRectangle bounds = pLayer->GetBounds();
154 evas_damage_rectangle_add(pLayer->GetEvas(), 0, 0, (int)bounds.width, (int)bounds.height);
155 pLayer->SetEvasRenderNeeded();
157 _DisplayManager::GetInstance()->AddWakeUpEvent();
159 PRINT("OnXWindowConfigured(%p)[%d,%d,%d,%d]------------\n", pLayer->GetEvas(), pEvent->x, pEvent->y, pEvent->w, pEvent->h);
168 OnXWindowHidden(void* pData, int type, void* pEventInfo)
170 _Ecore_X_Event_Window_Hide* pEvent = (_Ecore_X_Event_Window_Hide*)pEventInfo;
177 _EflLayer* pLayer = (_EflLayer*)pData;
178 PRINT("############ Hidden (%p, 0x%x) \n" , pLayer, pEvent->win);
180 if (pLayer->GetEvas() && pLayer->GetEcoreEvas() && pEvent->win == ecore_evas_window_get(pLayer->GetEcoreEvas()))
182 PRINT("############ Hidden (%p) -> EventDone() \n" , pData);
183 pLayer->SetVisibilityChangeCompleted();
184 _DisplayManager::GetInstance()->AddWakeUpEvent();
191 OnXWindowShown(void* pData, int type, void* pEventInfo)
193 _Ecore_X_Event_Window_Show* pEvent = (_Ecore_X_Event_Window_Show*)pEventInfo;
200 _EflLayer* pLayer = (_EflLayer*)pData;
201 PRINT("############ Shown (%p, 0x%x) \n" , pLayer, pEvent->win);
203 if (pLayer->GetEvas() && pLayer->GetEcoreEvas() && pEvent->win == ecore_evas_window_get(pLayer->GetEcoreEvas()))
205 PRINT("############ Shown (%p) -> EventDone() \n" , pData);
207 FloatRectangle bounds = pLayer->GetBounds();
209 evas_damage_rectangle_add(pLayer->GetEvas(), 0, 0, (int)bounds.width, (int)bounds.height);
211 pLayer->SetVisibilityChangeCompleted();
212 _DisplayManager::GetInstance()->AddWakeUpEvent();
221 PreRenderCallback(Ecore_Evas* ee)
223 _EflLayer* pEflLayer = (_EflLayer*)ecore_evas_data_get(ee, "EflLayer");
225 if (pEflLayer && pEflLayer->GetRootVisualElement())
227 #ifndef VE_VSYNC_UPDATE
228 static double loopTime = 0;
229 double prevLoopTime = loopTime;
230 loopTime = ecore_loop_time_get();
231 if (loopTime != prevLoopTime)
233 _AnimationManager::GetInstance()->ProcessAnimationTick();
237 _DisplayManager::GetInstance()->Render(*pEflLayer->GetRootVisualElement());
242 PostRenderCallback(Ecore_Evas* ee)
244 _EflLayer* pEflLayer = (_EflLayer*)ecore_evas_data_get(ee, "EflLayer");
246 if (pEflLayer && pEflLayer->GetRootVisualElement())
248 _DisplayManager::GetInstance()->PostRender(*pEflLayer->GetRootVisualElement());
254 namespace Tizen { namespace Ui { namespace Animations
257 int _EflLayer::_countOfLayer = 0;
259 _EflLayer::_EflLayer(void)
260 : _pRootVisualElement(null)
264 , _pOnWindowDamagedHandler(null)
265 , _pOnWindowConfiguredHandler(null)
266 , _pOnWindowHideHandler(null)
267 , _pOnWindowShowHandler(null)
269 , _needShowStateChangeRequest(false)
271 , _isVisibilityChangeInProgress(false)
272 , _needAsyncVisibilityChangeRequest(true)
275 , __isWinObject(true)
280 _EflLayer::_EflLayer(bool isMainType)
281 : _pRootVisualElement(null)
285 , _pOnWindowDamagedHandler(null)
286 , _pOnWindowConfiguredHandler(null)
287 , _pOnWindowHideHandler(null)
288 , _pOnWindowShowHandler(null)
290 , _needShowStateChangeRequest(false)
292 , _isVisibilityChangeInProgress(false)
293 , _needAsyncVisibilityChangeRequest(true)
294 , _isMainType(isMainType)
296 , __isWinObject(true)
301 _EflLayer::~_EflLayer(void)
304 #ifdef VE_VSYNC_UPDATE
305 ecore_evas_manual_render_set(_pEcoreEvas, EINA_FALSE);
307 if(_countOfLayer <= 0)
309 ecore_idle_enterer_del(__pOnIdleLoopIterator);
310 __pOnIdleLoopIterator = null;
313 #ifdef _NEED_DAMAGE_HANDER_
314 if (_pOnWindowDamagedHandler)
316 ecore_event_handler_del(_pOnWindowDamagedHandler);
317 _pOnWindowDamagedHandler = null;
320 if (_pOnWindowConfiguredHandler)
322 ecore_event_handler_del(_pOnWindowConfiguredHandler);
323 _pOnWindowConfiguredHandler = null;
325 if (_pOnWindowHideHandler)
327 ecore_event_handler_del(_pOnWindowHideHandler);
328 _pOnWindowHideHandler = null;
331 if (_pOnWindowShowHandler)
333 ecore_event_handler_del(_pOnWindowShowHandler);
334 _pOnWindowShowHandler = null;
343 ecore_evas_callback_pre_render_set(_pEcoreEvas, null);
344 ecore_evas_callback_post_render_set(_pEcoreEvas, null);
350 evas_object_del(_pWindow);
358 _EflLayer::OnConstructed(void)
360 //Ecore_X_Window window = 0;
364 return E_OBJ_ALREADY_EXIST;
369 _pWindow = elm_win_add(NULL, NULL, ELM_WIN_BASIC);
373 _pWindow = elm_win_add(NULL, NULL, ELM_WIN_UTILITY);
376 SysTryReturnResult(NID_UI, _pWindow, E_SYSTEM, "A system error has been occurred.");
378 result r = Initialize(_pWindow);
381 evas_object_del(_pWindow);
385 Ecore_X_Window window = (Ecore_X_Window) ecore_evas_window_get(_pEcoreEvas);
386 SysTryReturnResult(NID_UI, window != 0,E_SYSTEM, "A system error has been occurred.");
388 #ifdef VE_VSYNC_UPDATE
389 ecore_x_vsync_animator_tick_source_set(window);
390 ecore_evas_manual_render_set(_pEcoreEvas, EINA_TRUE);
391 ecore_evas_callback_pre_free_set(_pEcoreEvas, OnEcoreEvasFree);
394 ecore_x_netwm_window_type_set(window, ECORE_X_WINDOW_TYPE_NORMAL);
395 ecore_x_e_virtual_keyboard_state_set(window, (Ecore_X_Virtual_Keyboard_State)ELM_WIN_KEYBOARD_UNKNOWN);
402 _EflLayer::Initialize(Evas_Object* pWindow)
404 const char* pType = null;
407 SysTryCatch(NID_UI, _pWindow, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
408 _pEvas = evas_object_evas_get(_pWindow);
409 SysTryCatch(NID_UI, _pEvas, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
410 _pEcoreEvas = ecore_evas_ecore_evas_get(_pEvas);
411 SysTryCatch(NID_UI, _pEcoreEvas, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
413 pType = evas_object_type_get(_pWindow);
414 if (strcmp("elm_win", pType))
416 __isWinObject = false;
419 // CHECK ME: Is this needed for GL mode?
420 #ifdef _NEED_DAMAGE_HANDER_
421 if(_pOnWindowDamagedHandler == null)
423 _pOnWindowDamagedHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, OnXWindowDamaged, this);
426 if (_pOnWindowConfiguredHandler == null)
428 _pOnWindowConfiguredHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, OnXWindowConfigured, this);
431 if (_pOnWindowHideHandler == null)
433 _pOnWindowHideHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, OnXWindowHidden, this);
436 if (_pOnWindowShowHandler == null)
438 _pOnWindowShowHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, OnXWindowShown, this);
443 #ifdef VE_VSYNC_UPDATE
444 if(__pOnIdleLoopIterator == null)
446 __pOnIdleLoopIterator = ecore_idle_enterer_add(OnIdleLoopIterate, null);
449 ecore_evas_callback_pre_render_set(_pEcoreEvas, PreRenderCallback);
450 ecore_evas_callback_post_render_set(_pEcoreEvas, PostRenderCallback);
453 ecore_evas_data_set(_pEcoreEvas, "EflLayer", this);
461 _pRootVisualElement = null;
466 _EflLayer::Configure(_RootVisualElement& rootElement)
468 _EflNode* pNode = dynamic_cast<_EflNode*>(rootElement.GetNativeNode());
471 _pRootVisualElement = &rootElement;
473 return pNode->ReConstruct(*this);
480 _EflLayer::SetBounds(const FloatRectangle& bounds)
484 evas_object_move(_pWindow, bounds.x, bounds.y);
485 evas_object_resize(_pWindow, bounds.width, bounds.height);
491 _EflLayer::GetBounds(void) const
500 evas_object_geometry_get(_pWindow, null, null, &w, &h);
502 if (__isWinObject == true)
504 elm_win_screen_position_get(_pWindow, &x, &y);
507 return FloatRectangle(x, y, w, h);
510 return FloatRectangle();
514 _EflLayer::SetShowState(bool show)
516 #ifdef ECORE_EVAS_ASYNC_VISIBILITY_BUG_HACK
522 if (_needShowStateChangeRequest)
524 // Show State is not applied yet. Need cancel the visibility change request.
525 _needShowStateChangeRequest = false;
526 PRINT("Cancel SetShowState request (%d)\n", show);
530 _needShowStateChangeRequest = true;
531 _DisplayManager::GetInstance()->AddWakeUpEvent();
532 PRINT("SetShowState request (%d)\n", show);
541 evas_object_show(_pWindow);
545 evas_object_hide(_pWindow);
554 _EflLayer::GetShowState(void) const
560 _EflLayer::SetOpacity(float opacity)
569 else if(opacity<0.0f)
574 if (_FloatCompare(opacity, 1.0f))
576 // ecore_evas_alpha_set(_pEcoreEvas, EINA_FALSE);
577 if (__isWinObject == true)
579 elm_win_alpha_set(_pWindow, EINA_FALSE);
583 evas_object_color_get(_pWindow, &r, &g, &b, &a);
584 evas_object_color_set(_pWindow, r, g, b, 255);
587 else if (opacity < 1.0f)
590 // ecore_evas_alpha_set(_pEcoreEvas, EINA_TRUE);
591 if (__isWinObject == true)
593 elm_win_alpha_set(_pWindow, EINA_TRUE);
597 evas_object_color_get(_pWindow, &r, &g, &b, &a);
599 evas_object_color_set(_pWindow, r, g, b, a);
604 _EflLayer::GetOpacity(void)
610 evas_object_color_get(_pWindow, &r, &g, &b, &a);
619 _EflLayer::Flush(void)
623 PRINT("Flush StateChange(%p) - is Pending(%d) \n",this , _isVisibilityChangeInProgress);
625 if (_needShowStateChangeRequest && (!_needAsyncVisibilityChangeRequest || !_isVisibilityChangeInProgress))
629 evas_object_show(_pWindow);
631 // QUICK-DIRTY HACK TO BE REMOVED !!!
632 #ifdef ECORE_EVAS_ASYNC_VISIBILITY_BUG_HACK
637 FloatRectangle bounds = GetBounds();
638 evas_damage_rectangle_add(_pEvas, 0, 0, (int)bounds.width, (int)bounds.height);
641 PRINT("evas_object_show(%p) \n", this);
645 evas_object_hide(_pWindow);
646 PRINT("evas_object_hide(%p) \n", this);
649 #ifdef _NEED_DAMAGE_HANDER_
650 _isVisibilityChangeInProgress = true;
652 _needShowStateChangeRequest = false;
655 if (_needEvasRender > 0)
657 _DisplayManager::GetInstance()->AddWakeUpEvent();
660 FloatRectangle rect = GetBounds();
663 PRINT("_needRender = false bounds(%f %f %f %f)\n", rect.x, rect.y, rect.width, rect.height);
667 PRINT("ecore_evas_manual_render bounds(%f %f %f %f)\n", rect.x, rect.y, rect.width, rect.height);
669 ecore_evas_manual_render(_pEcoreEvas);
677 evas_render_idle_flush(_pEvas);
688 }}} // Tizen::Ui::Animations