Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-adaptor.git] / adaptors / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "adaptor-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <boost/thread/tss.hpp>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/integration-api/core.h>
26 #include <dali/integration-api/context-notifier.h>
27 #include <dali/integration-api/profiling.h>
28 #include <dali/integration-api/input-options.h>
29 #include <dali/integration-api/events/touch-event-integ.h>
30
31 // INTERNAL INCLUDES
32 #include <base/update-render-controller.h>
33 #include <base/environment-variables.h>
34 #include <base/performance-logging/performance-interface-factory.h>
35 #include <base/lifecycle-observer.h>
36
37 #include <dali/public-api/text-abstraction/font-client.h>
38
39 #include <callback-manager.h>
40 #include <trigger-event.h>
41 #include <window-render-surface.h>
42 #include <render-surface-impl.h>
43 #include <tts-player-impl.h>
44 #include <accessibility-manager-impl.h>
45 #include <timer-impl.h>
46 #include <events/gesture-manager.h>
47 #include <events/event-handler.h>
48 #include <feedback/feedback-controller.h>
49 #include <feedback/feedback-plugin-proxy.h>
50 #include <gl/gl-proxy-implementation.h>
51 #include <gl/gl-implementation.h>
52 #include <gl/egl-sync-implementation.h>
53 #include <gl/egl-image-extensions.h>
54 #include <gl/egl-factory.h>
55 #include <imf-manager-impl.h>
56 #include <clipboard-impl.h>
57 #include <vsync-monitor.h>
58 #include <object-profiler.h>
59 #include <slp-logging.h>
60
61 using Dali::TextAbstraction::FontClient;
62
63 namespace Dali
64 {
65
66 namespace Internal
67 {
68
69 namespace Adaptor
70 {
71
72 namespace
73 {
74 boost::thread_specific_ptr<Adaptor> gThreadLocalAdaptor;
75
76 unsigned int GetIntegerEnvironmentVariable( const char* variable, unsigned int defaultValue )
77 {
78   const char* variableParameter = std::getenv(variable);
79
80   // if the parameter exists convert it to an integer, else return the default value
81   unsigned int intValue = variableParameter ? atoi(variableParameter) : defaultValue;
82   return intValue;
83 }
84
85 bool GetIntegerEnvironmentVariable( const char* variable, int& intValue )
86 {
87   const char* variableParameter = std::getenv(variable);
88
89   if( !variableParameter )
90   {
91     return false;
92   }
93   // if the parameter exists convert it to an integer, else return the default value
94   intValue = atoi(variableParameter);
95   return true;
96 }
97
98 bool GetFloatEnvironmentVariable( const char* variable, float& floatValue )
99 {
100   const char* variableParameter = std::getenv(variable);
101
102   if( !variableParameter )
103   {
104     return false;
105   }
106   // if the parameter exists convert it to an integer, else return the default value
107   floatValue = atof(variableParameter);
108   return true;
109 }
110
111 } // unnamed namespace
112
113 Dali::Adaptor* Adaptor::New( RenderSurface *surface, const DeviceLayout& baseLayout,
114                              Dali::Configuration::ContextLoss configuration )
115 {
116   DALI_ASSERT_ALWAYS( surface->GetType() != Dali::RenderSurface::NO_SURFACE && "No surface for adaptor" );
117
118   Dali::Adaptor* adaptor = new Dali::Adaptor;
119   Adaptor* impl = new Adaptor( *adaptor, surface, baseLayout );
120   adaptor->mImpl = impl;
121
122   impl->Initialize(configuration);
123
124   return adaptor;
125 }
126
127 void Adaptor::ParseEnvironmentOptions()
128 {
129   // get logging options
130   unsigned int logFrameRateFrequency = GetIntegerEnvironmentVariable( DALI_ENV_FPS_TRACKING, 0 );
131   unsigned int logupdateStatusFrequency = GetIntegerEnvironmentVariable( DALI_ENV_UPDATE_STATUS_INTERVAL, 0 );
132   unsigned int logPerformanceStats = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE_STATS, 0 );
133   unsigned int logPerformanceStatsFrequency = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE_STATS_FREQUENCY, 0 );
134   unsigned int performanceTimeStampOutput= GetIntegerEnvironmentVariable( DALI_ENV_PERFORMANCE_TIMESTAMP_OUTPUT, 0 );
135
136
137   unsigned int logPanGesture = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PAN_GESTURE, 0 );
138
139   // all threads here (event, update, and render) will send their logs to SLP Platform's LogMessage handler.
140   Dali::Integration::Log::LogFunction  logFunction(Dali::SlpPlatform::LogMessage);
141
142   mEnvironmentOptions.SetLogOptions( logFunction, logFrameRateFrequency, logupdateStatusFrequency, logPerformanceStats, logPerformanceStatsFrequency, performanceTimeStampOutput, logPanGesture );
143
144   int predictionMode;
145   if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_PREDICTION_MODE, predictionMode) )
146   {
147     mEnvironmentOptions.SetPanGesturePredictionMode(predictionMode);
148   }
149   int predictionAmount(-1);
150   if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_PREDICTION_AMOUNT, predictionAmount) )
151   {
152     if( predictionAmount < 0 )
153     {
154       // do not support times in the past
155       predictionAmount = 0;
156     }
157     mEnvironmentOptions.SetPanGesturePredictionAmount(predictionAmount);
158   }
159   int minPredictionAmount(-1);
160   if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MIN_PREDICTION_AMOUNT, minPredictionAmount) )
161   {
162     if( minPredictionAmount < 0 )
163     {
164       // do not support times in the past
165       minPredictionAmount = 0;
166     }
167     mEnvironmentOptions.SetPanGestureMinimumPredictionAmount(minPredictionAmount);
168   }
169   int maxPredictionAmount(-1);
170   if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MAX_PREDICTION_AMOUNT, maxPredictionAmount) )
171   {
172     if( minPredictionAmount > -1 && maxPredictionAmount < minPredictionAmount )
173     {
174       // maximum amount should not be smaller than minimum amount
175       maxPredictionAmount = minPredictionAmount;
176     }
177     mEnvironmentOptions.SetPanGestureMaximumPredictionAmount(maxPredictionAmount);
178   }
179   int predictionAmountAdjustment(-1);
180   if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_PREDICTION_AMOUNT_ADJUSTMENT, predictionAmountAdjustment) )
181   {
182     if( predictionAmountAdjustment < 0 )
183     {
184       // negative amount doesn't make sense
185       predictionAmountAdjustment = 0;
186     }
187     mEnvironmentOptions.SetPanGesturePredictionAmountAdjustment(predictionAmountAdjustment);
188   }
189   int smoothingMode;
190   if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_SMOOTHING_MODE, smoothingMode) )
191   {
192     mEnvironmentOptions.SetPanGestureSmoothingMode(smoothingMode);
193   }
194   float smoothingAmount = 1.0f;
195   if( GetFloatEnvironmentVariable(DALI_ENV_PAN_SMOOTHING_AMOUNT, smoothingAmount) )
196   {
197     smoothingAmount = Clamp(smoothingAmount, 0.0f, 1.0f);
198     mEnvironmentOptions.SetPanGestureSmoothingAmount(smoothingAmount);
199   }
200
201   int minimumDistance(-1);
202   if ( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MINIMUM_DISTANCE, minimumDistance ))
203   {
204     mEnvironmentOptions.SetMinimumPanDistance( minimumDistance );
205   }
206
207   int minimumEvents(-1);
208   if ( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MINIMUM_EVENTS, minimumEvents ))
209   {
210     mEnvironmentOptions.SetMinimumPanEvents( minimumEvents );
211   }
212
213   int glesCallTime(0);
214   if ( GetIntegerEnvironmentVariable(DALI_GLES_CALL_TIME, glesCallTime ))
215   {
216     mEnvironmentOptions.SetGlesCallTime( glesCallTime );
217   }
218
219   mEnvironmentOptions.InstallLogFunction();
220 }
221
222 void Adaptor::Initialize(Dali::Configuration::ContextLoss configuration)
223 {
224   ParseEnvironmentOptions();
225
226   mPlatformAbstraction = new SlpPlatform::SlpPlatformAbstraction;
227
228   std::string path;
229   GetDataStoragePath( path );
230   mPlatformAbstraction->SetDataStoragePath( path );
231
232   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
233   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
234   {
235     dataRetentionPolicy = ResourcePolicy::DALI_RETAINS_MESH_DATA;
236   }
237   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
238   // files automatically.
239
240   if( mEnvironmentOptions.PerformanceServerRequired() )
241   {
242     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, mEnvironmentOptions );
243   }
244
245   mCallbackManager = CallbackManager::New();
246
247   PositionSize size = mSurface->GetPositionSize();
248
249   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, mEnvironmentOptions);
250
251   if( mEnvironmentOptions.GetGlesCallTime() > 0 )
252   {
253     mGLES = new GlProxyImplementation( mEnvironmentOptions );
254   }
255   else
256   {
257     mGLES = new GlImplementation();
258   }
259
260   mEglFactory = new EglFactory();
261
262   EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
263
264   mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager, dataRetentionPolicy );
265
266   mObjectProfiler = new ObjectProfiler();
267
268   mNotificationTrigger = new TriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ) );
269
270   mVSyncMonitor = new VSyncMonitor;
271
272   mUpdateRenderController = new UpdateRenderController( *this, mEnvironmentOptions );
273
274   mDaliFeedbackPlugin = new FeedbackPluginProxy( FeedbackPluginProxy::DEFAULT_OBJECT_NAME );
275
276   // Should be called after Core creation
277   if( mEnvironmentOptions.GetPanGestureLoggingLevel() )
278   {
279     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
280   }
281   if( mEnvironmentOptions.GetPanGesturePredictionMode() >= 0 )
282   {
283     Integration::SetPanGesturePredictionMode(mEnvironmentOptions.GetPanGesturePredictionMode());
284   }
285   if( mEnvironmentOptions.GetPanGesturePredictionAmount() >= 0 )
286   {
287     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions.GetPanGesturePredictionAmount());
288   }
289   if( mEnvironmentOptions.GetPanGestureMaximumPredictionAmount() >= 0 )
290   {
291     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions.GetPanGestureMaximumPredictionAmount());
292   }
293   if( mEnvironmentOptions.GetPanGestureMinimumPredictionAmount() >= 0 )
294   {
295     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions.GetPanGestureMinimumPredictionAmount());
296   }
297   if( mEnvironmentOptions.GetPanGesturePredictionAmountAdjustment() >= 0 )
298   {
299     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions.GetPanGesturePredictionAmountAdjustment());
300   }
301   if( mEnvironmentOptions.GetPanGestureSmoothingMode() >= 0 )
302   {
303     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions.GetPanGestureSmoothingMode());
304   }
305   if( mEnvironmentOptions.GetPanGestureSmoothingAmount() >= 0.0f )
306   {
307     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions.GetPanGestureSmoothingAmount());
308   }
309 }
310
311 Adaptor::~Adaptor()
312 {
313   // Ensure stop status
314   Stop();
315
316   // Release first as we do not want any access to Adaptor as it is being destroyed.
317   gThreadLocalAdaptor.release();
318
319   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
320   {
321     (*iter)->OnDestroy();
322   }
323
324   delete mUpdateRenderController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
325   delete mVSyncMonitor;
326   delete mEventHandler;
327   delete mObjectProfiler;
328
329   delete mCore;
330   delete mEglFactory;
331   // Delete feedback controller before feedback plugin & style monitor dependencies
332   delete mFeedbackController;
333   delete mDaliFeedbackPlugin;
334   delete mGLES;
335   delete mGestureManager;
336   delete mPlatformAbstraction;
337   delete mCallbackManager;
338   delete mPerformanceInterface;
339
340   // uninstall it on this thread (main actor thread)
341   Dali::Integration::Log::UninstallLogFunction();
342 }
343
344 void Adaptor::Start()
345 {
346   // it doesn't support restart after stop at this moment
347   // to support restarting, need more testing
348   if( READY != mState )
349   {
350     return;
351   }
352
353   // Start the callback manager
354   mCallbackManager->Start();
355
356   // create event handler
357   mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
358
359   if( mDeferredRotationObserver != NULL )
360   {
361     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
362     mDeferredRotationObserver = NULL;
363   }
364
365   // guarantee map the surface before starting render-thread.
366   mSurface->Map();
367
368   unsigned int dpiHor(0);
369   unsigned int dpiVer(0);
370   mSurface->GetDpi( dpiHor, dpiVer );
371
372   // tell core about the DPI value
373   mCore->SetDpi(dpiHor, dpiVer);
374
375   // set the DPI value for font rendering
376   FontClient fontClient = FontClient::Get();
377   fontClient.SetDpi( dpiHor, dpiVer );
378
379   // Tell the core the size of the surface just before we start the render-thread
380   PositionSize size = mSurface->GetPositionSize();
381   mCore->SurfaceResized( size.width, size.height );
382
383   // Start the update & render threads
384   mUpdateRenderController->Start();
385
386   mState = RUNNING;
387
388   ProcessCoreEvents(); // Ensure any startup messages are processed.
389
390   if ( !mFeedbackController )
391   {
392     // Start sound & haptic feedback
393     mFeedbackController = new FeedbackController( *mDaliFeedbackPlugin );
394   }
395
396   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
397   {
398     (*iter)->OnStart();
399   }
400 }
401
402 // Dali::Internal::Adaptor::Adaptor::Pause
403 void Adaptor::Pause()
404 {
405   // Only pause the adaptor if we're actually running.
406   if( RUNNING == mState )
407   {
408     // Inform observers that we are about to be paused.
409     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
410     {
411       (*iter)->OnPause();
412     }
413
414     // Reset the event handler when adaptor paused
415     if( mEventHandler )
416     {
417       mEventHandler->Reset();
418     }
419
420     mUpdateRenderController->Pause();
421     mCore->Suspend();
422     mState = PAUSED;
423   }
424 }
425
426 // Dali::Internal::Adaptor::Adaptor::Resume
427 void Adaptor::Resume()
428 {
429   // Only resume the adaptor if we are in the suspended state.
430   if( PAUSED == mState )
431   {
432     // We put ResumeFrameTime first, as this was originally called at the start of mCore->Resume()
433     // If there were events pending, mCore->Resume() will call
434     //   RenderController->RequestUpdate()
435     //     UpdateRenderController->RequestUpdate()
436     //       UpdateRenderSynchronization->RequestUpdate()
437     // and we should have reset the frame timers before allowing Core->Update() to be called.
438     //@todo Should we call UpdateRenderController->Resume before mCore->Resume()?
439
440     mUpdateRenderController->ResumeFrameTime();
441     mCore->Resume();
442     mUpdateRenderController->Resume();
443
444     mState = RUNNING;
445
446     // Reset the event handler when adaptor resumed
447     if( mEventHandler )
448     {
449       mEventHandler->Reset();
450     }
451
452     // Inform observers that we have resumed.
453     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
454     {
455       (*iter)->OnResume();
456     }
457
458     ProcessCoreEvents(); // Ensure any outstanding messages are processed
459   }
460 }
461
462 void Adaptor::Stop()
463 {
464   if( RUNNING == mState ||
465       PAUSED  == mState ||
466       PAUSED_WHILE_HIDDEN == mState )
467   {
468     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
469     {
470       (*iter)->OnStop();
471     }
472
473     mUpdateRenderController->Stop();
474     mCore->Suspend();
475
476     // Delete the TTS player
477     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
478     {
479       if(mTtsPlayers[i])
480       {
481         mTtsPlayers[i].Reset();
482       }
483     }
484
485     delete mEventHandler;
486     mEventHandler = NULL;
487
488     delete mNotificationTrigger;
489     mNotificationTrigger = NULL;
490
491     mCallbackManager->Stop();
492
493     mState = STOPPED;
494   }
495 }
496
497 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
498 {
499   mEventHandler->FeedTouchPoint( point, timeStamp );
500 }
501
502 void Adaptor::FeedWheelEvent( MouseWheelEvent& wheelEvent )
503 {
504   mEventHandler->FeedWheelEvent( wheelEvent );
505 }
506
507 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
508 {
509   mEventHandler->FeedKeyEvent( keyEvent );
510 }
511
512 bool Adaptor::MoveResize( const PositionSize& positionSize )
513 {
514   PositionSize old = mSurface->GetPositionSize();
515
516   // just resize the surface. The driver should automatically resize the egl Surface (untested)
517   // EGL Spec says : EGL window surfaces need to be resized when their corresponding native window
518   // is resized. Implementations typically use hooks into the OS and native window
519   // system to perform this resizing on demand, transparently to the client.
520   mSurface->MoveResize( positionSize );
521
522   if(old.width != positionSize.width || old.height != positionSize.height)
523   {
524     SurfaceSizeChanged(positionSize);
525   }
526
527   return true;
528 }
529
530 void Adaptor::SurfaceResized( const PositionSize& positionSize )
531 {
532   PositionSize old = mSurface->GetPositionSize();
533
534   // Called by an application, when it has resized a window outside of Dali.
535   // The EGL driver automatically detects X Window resize calls, and resizes
536   // the EGL surface for us.
537   mSurface->MoveResize( positionSize );
538
539   if(old.width != positionSize.width || old.height != positionSize.height)
540   {
541     SurfaceSizeChanged(positionSize);
542   }
543 }
544
545 void Adaptor::ReplaceSurface( Dali::RenderSurface& surface )
546 {
547   // adaptor implementation needs the implementation of
548   RenderSurface* internalSurface = dynamic_cast<Internal::Adaptor::RenderSurface*>( &surface );
549   DALI_ASSERT_ALWAYS( internalSurface && "Incorrect surface" );
550
551   ECore::WindowRenderSurface* windowSurface = dynamic_cast<Internal::Adaptor::ECore::WindowRenderSurface*>( &surface);
552   if( windowSurface != NULL )
553   {
554     windowSurface->Map();
555     // @todo Restart event handler with new surface
556   }
557
558   mSurface = internalSurface;
559
560   SurfaceSizeChanged( internalSurface->GetPositionSize() );
561
562   // flush the event queue to give update and render threads chance
563   // to start processing messages for new camera setup etc as soon as possible
564   ProcessCoreEvents();
565
566   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
567
568   // this method blocks until the render thread has completed the replace.
569   mUpdateRenderController->ReplaceSurface(internalSurface);
570
571   // Inform core, so that texture resources can be reloaded
572   mCore->RecoverFromContextLoss();
573
574   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
575 }
576
577 Dali::RenderSurface& Adaptor::GetSurface() const
578 {
579   return *mSurface;
580 }
581
582 void Adaptor::ReleaseSurfaceLock()
583 {
584   mSurface->ReleaseLock();
585 }
586
587 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
588 {
589   if(!mTtsPlayers[mode])
590   {
591     // Create the TTS player when it needed, because it can reduce launching time.
592     mTtsPlayers[mode] = TtsPlayer::New(mode);
593   }
594
595   return mTtsPlayers[mode];
596 }
597
598 bool Adaptor::AddIdle( CallbackBase* callback )
599 {
600   bool idleAdded(false);
601
602   // Only add an idle if the Adaptor is actually running
603   if( RUNNING == mState )
604   {
605     idleAdded = mCallbackManager->AddCallback( callback, CallbackManager::IDLE_PRIORITY );
606   }
607
608   return idleAdded;
609 }
610
611 bool Adaptor::CallFromMainLoop( CallbackBase* callback )
612 {
613   bool callAdded(false);
614
615   // Only allow the callback if the Adaptor is actually running
616   if ( RUNNING == mState )
617   {
618     callAdded = mCallbackManager->AddCallback( callback, CallbackManager::DEFAULT_PRIORITY );
619   }
620
621   return callAdded;
622 }
623
624 Dali::Adaptor& Adaptor::Get()
625 {
626   DALI_ASSERT_ALWAYS( gThreadLocalAdaptor.get() != NULL && "Adaptor not instantiated" );
627   return gThreadLocalAdaptor->mAdaptor;
628 }
629
630 bool Adaptor::IsAvailable()
631 {
632   return gThreadLocalAdaptor.get() != NULL;
633 }
634
635 Dali::Integration::Core& Adaptor::GetCore()
636 {
637   return *mCore;
638 }
639
640 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
641 {
642   mUpdateRenderController->SetRenderRefreshRate( numberOfVSyncsPerRender );
643 }
644
645 void Adaptor::SetUseHardwareVSync( bool useHardware )
646 {
647   mVSyncMonitor->SetUseHardwareVSync( useHardware );
648 }
649
650 EglFactory& Adaptor::GetEGLFactory() const
651 {
652   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
653   return *mEglFactory;
654 }
655
656 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
657 {
658   return *mEglFactory;
659 }
660
661 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
662 {
663   DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
664   return *mGLES;
665 }
666
667 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
668 {
669   return *mPlatformAbstraction;
670 }
671
672 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
673 {
674   return *mGLES;
675 }
676
677 TriggerEventInterface& Adaptor::GetTriggerEventInterface()
678 {
679   return *mNotificationTrigger;
680 }
681 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
682 {
683   return mTriggerEventFactory;
684 }
685 RenderSurface* Adaptor::GetRenderSurfaceInterface()
686 {
687   return mSurface;
688 }
689 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
690 {
691   return mVSyncMonitor;
692 }
693
694 KernelTraceInterface& Adaptor::GetKernelTraceInterface()
695 {
696   return mKernelTracer;
697 }
698
699 PerformanceInterface* Adaptor::GetPerformanceInterface()
700 {
701   return mPerformanceInterface;
702 }
703
704 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
705 {
706   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
707   return *mPlatformAbstraction;
708 }
709
710 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
711 {
712   mDragAndDropDetector = detector;
713
714   if ( mEventHandler )
715   {
716     mEventHandler->SetDragAndDropDetector( detector );
717   }
718 }
719
720 void Adaptor::SetRotationObserver( RotationObserver* observer )
721 {
722   if( mEventHandler )
723   {
724     mEventHandler->SetRotationObserver( observer );
725   }
726   else if( mState == READY )
727   {
728     // Set once event handler exists
729     mDeferredRotationObserver = observer;
730   }
731 }
732
733 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
734 {
735   if(mTtsPlayers[mode])
736   {
737     mTtsPlayers[mode].Reset();
738   }
739 }
740
741 void Adaptor::SetMinimumPinchDistance(float distance)
742 {
743   if( mGestureManager )
744   {
745     mGestureManager->SetMinimumPinchDistance(distance);
746   }
747 }
748
749
750 void Adaptor::AddObserver( LifeCycleObserver& observer )
751 {
752   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
753
754   if ( match == mObservers.end() )
755   {
756     mObservers.push_back( &observer );
757   }
758 }
759
760 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
761 {
762   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
763
764   if ( match != mObservers.end() )
765   {
766     mObservers.erase( match );
767   }
768 }
769
770 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
771 {
772   if( mCore )
773   {
774     mCore->QueueEvent(event);
775   }
776 }
777
778 void Adaptor::ProcessCoreEvents()
779 {
780   if( mCore )
781   {
782     if( mPerformanceInterface )
783     {
784       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
785     }
786
787     mCore->ProcessEvents();
788
789     if( mPerformanceInterface )
790     {
791       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
792     }
793   }
794 }
795
796 void Adaptor::RequestUpdate()
797 {
798   // When Dali applications are partially visible behind the lock-screen,
799   // the indicator must be updated (therefore allow updates in the PAUSED state)
800   if ( PAUSED  == mState ||
801        RUNNING == mState )
802   {
803     mUpdateRenderController->RequestUpdate();
804   }
805 }
806
807 void Adaptor::RequestProcessEventsOnIdle()
808 {
809   // Only request a notification if the Adaptor is actually running
810   // and we haven't installed the idle notification
811   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState ) )
812   {
813     mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ) );
814   }
815 }
816
817 void Adaptor::OnWindowShown()
818 {
819   if ( PAUSED_WHILE_HIDDEN == mState )
820   {
821     // Adaptor can now be resumed
822     mState = PAUSED;
823
824     Resume();
825
826     // Force a render task
827     RequestUpdateOnce();
828   }
829 }
830
831 void Adaptor::OnWindowHidden()
832 {
833   if ( STOPPED != mState )
834   {
835     Pause();
836
837     // Adaptor cannot be resumed until the window is shown
838     mState = PAUSED_WHILE_HIDDEN;
839   }
840 }
841
842 // Dali::Internal::Adaptor::Adaptor::OnDamaged
843 void Adaptor::OnDamaged( const DamageArea& area )
844 {
845   // This is needed for the case where Dali window is partially obscured
846   RequestUpdate();
847 }
848
849 void Adaptor::SurfaceSizeChanged(const PositionSize& positionSize)
850 {
851   // let the core know the surface size has changed
852   mCore->SurfaceResized(positionSize.width, positionSize.height);
853
854   mResizedSignal.Emit( mAdaptor );
855 }
856
857 void Adaptor::NotifyLanguageChanged()
858 {
859   mLanguageChangedSignal.Emit( mAdaptor );
860 }
861
862 void Adaptor::RequestUpdateOnce()
863 {
864   if( PAUSED_WHILE_HIDDEN != mState )
865   {
866     if( mUpdateRenderController )
867     {
868       mUpdateRenderController->RequestUpdateOnce();
869     }
870   }
871 }
872
873 void Adaptor::ProcessCoreEventsFromIdle()
874 {
875   ProcessCoreEvents();
876
877   // the idle handle automatically un-installs itself
878   mNotificationOnIdleInstalled = false;
879 }
880
881 Adaptor::Adaptor(Dali::Adaptor& adaptor, RenderSurface* surface, const DeviceLayout& baseLayout)
882 : mResizedSignal(),
883   mLanguageChangedSignal(),
884   mAdaptor(adaptor),
885   mState(READY),
886   mCore(NULL),
887   mUpdateRenderController(NULL),
888   mVSyncMonitor(NULL),
889   mGLES( NULL ),
890   mEglFactory( NULL ),
891   mSurface( surface ),
892   mPlatformAbstraction( NULL ),
893   mEventHandler( NULL ),
894   mCallbackManager( NULL ),
895   mNotificationOnIdleInstalled( false ),
896   mNotificationTrigger(NULL),
897   mGestureManager(NULL),
898   mDaliFeedbackPlugin(NULL),
899   mFeedbackController(NULL),
900   mObservers(),
901   mDragAndDropDetector(),
902   mDeferredRotationObserver(NULL),
903   mBaseLayout(baseLayout),
904   mEnvironmentOptions(),
905   mPerformanceInterface(NULL),
906   mObjectProfiler(NULL)
907 {
908   DALI_ASSERT_ALWAYS( gThreadLocalAdaptor.get() == NULL && "Cannot create more than one Adaptor per thread" );
909   gThreadLocalAdaptor.reset(this);
910 }
911
912 // Stereoscopy
913
914 void Adaptor::SetViewMode( ViewMode viewMode )
915 {
916   mSurface->SetViewMode( viewMode );
917   mCore->SetViewMode( viewMode );
918 }
919
920 ViewMode Adaptor::GetViewMode() const
921 {
922   return mCore->GetViewMode();
923 }
924
925 void Adaptor::SetStereoBase( float stereoBase )
926 {
927   mCore->SetStereoBase( stereoBase );
928 }
929
930 float Adaptor::GetStereoBase() const
931 {
932   return mCore->GetStereoBase();
933 }
934
935 } // namespace Adaptor
936
937 } // namespace Internal
938
939 } // namespace Dali