2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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)
278 _EflLayer::~_EflLayer(void)
281 #ifdef VE_VSYNC_UPDATE
282 ecore_evas_manual_render_set(_pEcoreEvas, EINA_FALSE);
284 if(_countOfLayer <= 0)
286 ecore_idle_enterer_del(__pOnIdleLoopIterator);
287 __pOnIdleLoopIterator = null;
290 #ifdef _NEED_DAMAGE_HANDER_
291 if (_pOnWindowDamagedHandler)
293 ecore_event_handler_del(_pOnWindowDamagedHandler);
294 _pOnWindowDamagedHandler = null;
297 if (_pOnWindowConfiguredHandler)
299 ecore_event_handler_del(_pOnWindowConfiguredHandler);
300 _pOnWindowConfiguredHandler = null;
302 if (_pOnWindowHideHandler)
304 ecore_event_handler_del(_pOnWindowHideHandler);
305 _pOnWindowHideHandler = null;
308 if (_pOnWindowShowHandler)
310 ecore_event_handler_del(_pOnWindowShowHandler);
311 _pOnWindowShowHandler = null;
320 ecore_evas_callback_pre_render_set(_pEcoreEvas, null);
321 ecore_evas_callback_post_render_set(_pEcoreEvas, null);
327 evas_object_del(_pWindow);
335 _EflLayer::OnConstructed(void)
337 //Ecore_X_Window window = 0;
341 return E_OBJ_ALREADY_EXIST;
344 _pWindow = elm_win_add(NULL, NULL, ELM_WIN_BASIC);
346 SysTryReturnResult(NID_UI, _pWindow, E_SYSTEM, "A system error has been occurred.");
348 result r = Initialize(_pWindow);
351 evas_object_del(_pWindow);
355 Ecore_X_Window window = (Ecore_X_Window) ecore_evas_window_get(_pEcoreEvas);
356 SysTryReturnResult(NID_UI, window != 0,E_SYSTEM, "A system error has been occurred.");
358 #ifdef VE_VSYNC_UPDATE
359 ecore_x_vsync_animator_tick_source_set(window);
360 ecore_evas_manual_render_set(_pEcoreEvas, EINA_TRUE);
361 ecore_evas_callback_pre_free_set(_pEcoreEvas, OnEcoreEvasFree);
364 ecore_x_netwm_window_type_set(window, ECORE_X_WINDOW_TYPE_NORMAL);
365 ecore_x_e_virtual_keyboard_state_set(window, (Ecore_X_Virtual_Keyboard_State)ELM_WIN_KEYBOARD_UNKNOWN);
372 _EflLayer::Initialize(Evas_Object* pWindow)
375 SysTryCatch(NID_UI, _pWindow, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
376 _pEvas = evas_object_evas_get(_pWindow);
377 SysTryCatch(NID_UI, _pEvas, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
378 _pEcoreEvas = ecore_evas_ecore_evas_get(_pEvas);
379 SysTryCatch(NID_UI, _pEcoreEvas, , E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
381 // CHECK ME: Is this needed for GL mode?
382 #ifdef _NEED_DAMAGE_HANDER_
383 if(_pOnWindowDamagedHandler == null)
385 _pOnWindowDamagedHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, OnXWindowDamaged, this);
388 if (_pOnWindowConfiguredHandler == null)
390 _pOnWindowConfiguredHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, OnXWindowConfigured, this);
393 if (_pOnWindowHideHandler == null)
395 _pOnWindowHideHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, OnXWindowHidden, this);
398 if (_pOnWindowShowHandler == null)
400 _pOnWindowShowHandler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, OnXWindowShown, this);
405 #ifdef VE_VSYNC_UPDATE
406 if(__pOnIdleLoopIterator == null)
408 __pOnIdleLoopIterator = ecore_idle_enterer_add(OnIdleLoopIterate, null);
411 ecore_evas_callback_pre_render_set(_pEcoreEvas, PreRenderCallback);
412 ecore_evas_callback_post_render_set(_pEcoreEvas, PostRenderCallback);
415 ecore_evas_data_set(_pEcoreEvas, "EflLayer", this);
423 _pRootVisualElement = null;
428 _EflLayer::Configure(_RootVisualElement& rootElement)
430 _EflNode* pNode = dynamic_cast<_EflNode*>(rootElement.GetNativeNode());
433 _pRootVisualElement = &rootElement;
435 return pNode->ReConstruct(*this);
442 _EflLayer::SetBounds(const FloatRectangle& bounds)
446 evas_object_move(_pWindow, bounds.x, bounds.y);
447 evas_object_resize(_pWindow, bounds.width, bounds.height);
453 _EflLayer::GetBounds(void) const
461 evas_object_geometry_get(_pWindow, &x, &y, &w, &h);
463 return FloatRectangle(x, y, w, h);
466 return FloatRectangle();
470 _EflLayer::SetShowState(bool show)
472 #ifdef ECORE_EVAS_ASYNC_VISIBILITY_BUG_HACK
478 if (_needShowStateChangeRequest)
480 // Show State is not applied yet. Need cancel the visibility change request.
481 _needShowStateChangeRequest = false;
482 PRINT("Cancel SetShowState request (%d)\n", show);
486 _needShowStateChangeRequest = true;
487 _DisplayManager::GetInstance()->AddWakeUpEvent();
488 PRINT("SetShowState request (%d)\n", show);
497 evas_object_show(_pWindow);
501 evas_object_hide(_pWindow);
510 _EflLayer::GetShowState(void) const
516 _EflLayer::SetOpacity(float opacity)
525 else if(opacity<0.0f)
530 if (_FloatCompare(opacity, 1.0f))
532 ecore_evas_alpha_set(_pEcoreEvas, EINA_FALSE);
534 evas_object_color_get(_pWindow, &r, &g, &b, &a);
535 evas_object_color_set(_pWindow, r, g, b, 255);
538 else if (opacity < 1.0f)
541 ecore_evas_alpha_set(_pEcoreEvas, EINA_TRUE);
544 evas_object_color_get(_pWindow, &r, &g, &b, &a);
546 evas_object_color_set(_pWindow, r, g, b, a);
551 _EflLayer::GetOpacity(void)
557 evas_object_color_get(_pWindow, &r, &g, &b, &a);
566 _EflLayer::Flush(void)
570 PRINT("Flush StateChange(%p) - is Pending(%d) \n",this , _isVisibilityChangeInProgress);
572 if (_needShowStateChangeRequest && (!_needAsyncVisibilityChangeRequest || !_isVisibilityChangeInProgress))
576 evas_object_show(_pWindow);
578 // QUICK-DIRTY HACK TO BE REMOVED !!!
579 #ifdef ECORE_EVAS_ASYNC_VISIBILITY_BUG_HACK
584 FloatRectangle bounds = GetBounds();
585 evas_damage_rectangle_add(_pEvas, 0, 0, (int)bounds.width, (int)bounds.height);
588 PRINT("evas_object_show(%p) \n", this);
592 evas_object_hide(_pWindow);
593 PRINT("evas_object_hide(%p) \n", this);
596 _isVisibilityChangeInProgress = true;
597 _needShowStateChangeRequest = false;
600 if (_needEvasRender > 0)
602 _DisplayManager::GetInstance()->AddWakeUpEvent();
607 ecore_evas_manual_render(_pEcoreEvas);
615 evas_render_idle_flush(_pEvas);
626 }}} // Tizen::Ui::Animations