Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2018 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 <dali/internal/adaptor/common/adaptor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/stage.h>
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/public-api/object/any.h>
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/context-notifier.h>
29 #include <dali/integration-api/profiling.h>
30 #include <dali/integration-api/input-options.h>
31 #include <dali/integration-api/events/touch-event-integ.h>
32
33 // INTERNAL INCLUDES
34 #include <dali/public-api/dali-adaptor-common.h>
35 #include <dali/internal/system/common/thread-controller.h>
36 #include <dali/internal/system/common/performance-interface-factory.h>
37 #include <dali/internal/adaptor/common/lifecycle-observer.h>
38
39 #include <dali/devel-api/text-abstraction/font-client.h>
40
41 #include <dali/internal/system/common/callback-manager.h>
42 #include <dali/internal/accessibility/common/tts-player-impl.h>
43 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
44 #include <dali/internal/input/common/gesture-manager.h>
45 #include <dali/internal/window-system/common/event-handler.h>
46 #include <dali/internal/graphics/gles20/gl-proxy-implementation.h>
47 #include <dali/internal/graphics/gles20/gl-implementation.h>
48 #include <dali/internal/graphics/gles20/egl-sync-implementation.h>
49 #include <dali/internal/graphics/common/egl-image-extensions.h>
50 #include <dali/internal/graphics/gles20/egl-factory.h>
51 #include <dali/internal/clipboard/common/clipboard-impl.h>
52 #include <dali/internal/graphics/common/vsync-monitor.h>
53 #include <dali/internal/system/common/object-profiler.h>
54 #include <dali/internal/window-system/common/display-connection.h>
55 #include <dali/internal/window-system/common/window-impl.h>
56 #include <dali/internal/window-system/common/window-render-surface.h>
57
58 #include <dali/internal/system/common/logging.h>
59 #include <dali/devel-api/adaptor-framework/image-loading.h>
60
61 #include <dali/internal/system/common/locale-utils.h>
62
63 using Dali::TextAbstraction::FontClient;
64
65 namespace Dali
66 {
67
68 namespace Internal
69 {
70
71 namespace Adaptor
72 {
73
74 namespace
75 {
76 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
77 } // unnamed namespace
78
79 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
80 {
81   Dali::Adaptor* adaptor = new Dali::Adaptor;
82   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
83   adaptor->mImpl = impl;
84
85   impl->Initialize(configuration);
86
87   return adaptor;
88 }
89
90 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
91 {
92   Any winId = window.GetNativeHandle();
93
94   Window& windowImpl = Dali::GetImplementation(window);
95   Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
96   windowImpl.SetAdaptor(*adaptor);
97   return adaptor;
98 }
99
100 void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration )
101 {
102   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
103   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
104   mEnvironmentOptions->SetLogFunction( logFunction );
105   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
106
107   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
108
109   std::string path;
110   GetDataStoragePath( path );
111   mPlatformAbstraction->SetDataStoragePath( path );
112
113   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
114   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
115   {
116     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
117   }
118   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
119   // files automatically.
120
121   if( mEnvironmentOptions->PerformanceServerRequired() )
122   {
123     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
124   }
125
126   mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
127   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
128
129   mCallbackManager = CallbackManager::New();
130
131   PositionSize size = mSurface->GetPositionSize();
132
133   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
134
135   if( mEnvironmentOptions->GetGlesCallTime() > 0 )
136   {
137     mGLES = new GlProxyImplementation( *mEnvironmentOptions );
138   }
139   else
140   {
141     mGLES = new GlImplementation();
142   }
143
144   const Integration::DepthBufferAvailable depthBufferAvailable = static_cast< Integration::DepthBufferAvailable >( mEnvironmentOptions->DepthBufferRequired() );
145   const Integration::StencilBufferAvailable stencilBufferAvailable = static_cast< Integration::StencilBufferAvailable >( mEnvironmentOptions->StencilBufferRequired() );
146
147   mEglFactory = new EglFactory( mEnvironmentOptions->GetMultiSamplingLevel(), depthBufferAvailable, stencilBufferAvailable );
148
149   EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
150
151   mCore = Integration::Core::New( *this,
152                                   *mPlatformAbstraction,
153                                   *mGLES,
154                                   *eglSyncImpl,
155                                   *mGestureManager,
156                                   dataRetentionPolicy ,
157                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
158                                   depthBufferAvailable,
159                                   stencilBufferAvailable );
160
161   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
162   if( 0u < timeInterval )
163   {
164     mObjectProfiler = new ObjectProfiler( timeInterval );
165   }
166
167   mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
168
169   mVSyncMonitor = new VSyncMonitor;
170
171   mThreadController = new ThreadController( *this, *mEnvironmentOptions );
172
173   // Should be called after Core creation
174   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
175   {
176     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
177   }
178   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
179   {
180     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
181   }
182   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
183   {
184     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
185   }
186   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
187   {
188     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
189   }
190   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
191   {
192     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
193   }
194   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
195   {
196     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
197   }
198   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
199   {
200     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
201   }
202   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
203   {
204     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
205   }
206   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
207   {
208     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
209   }
210   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
211   {
212     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
213   }
214   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
215   {
216     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
217   }
218   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
219   {
220     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
221   }
222   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
223   {
224     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
225   }
226   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
227   {
228     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
229   }
230   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
231   {
232     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
233   }
234   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
235   {
236     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
237   }
238
239   // Set max texture size
240   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
241   {
242     Dali::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
243   }
244
245   SetupSystemInformation();
246 }
247
248 Adaptor::~Adaptor()
249 {
250   // Ensure stop status
251   Stop();
252
253   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
254   gThreadLocalAdaptor = NULL;
255
256   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
257   {
258     (*iter)->OnDestroy();
259   }
260
261   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
262   delete mVSyncMonitor;
263   delete mEventHandler;
264   delete mObjectProfiler;
265
266   delete mCore;
267   delete mEglFactory;
268   delete mGLES;
269   delete mGestureManager;
270   delete mPlatformAbstraction;
271   delete mCallbackManager;
272   delete mPerformanceInterface;
273
274   // uninstall it on this thread (main actor thread)
275   Dali::Integration::Log::UninstallLogFunction();
276
277   // Delete environment options if we own it
278   if( mEnvironmentOptionsOwned )
279   {
280     delete mEnvironmentOptions;
281   }
282 }
283
284 void Adaptor::Start()
285 {
286   // it doesn't support restart after stop at this moment
287   // to support restarting, need more testing
288   if( READY != mState )
289   {
290     return;
291   }
292
293   // Start the callback manager
294   mCallbackManager->Start();
295
296   // create event handler
297   mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
298
299   if( mDeferredRotationObserver != NULL )
300   {
301     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
302     mDeferredRotationObserver = NULL;
303   }
304
305   unsigned int dpiHor, dpiVer;
306   dpiHor = dpiVer = 0;
307   mSurface->GetDpi( dpiHor, dpiVer );
308
309   // tell core about the DPI value
310   mCore->SetDpi(dpiHor, dpiVer);
311
312   // set the DPI value for font rendering
313   FontClient fontClient = FontClient::Get();
314   fontClient.SetDpi( dpiHor, dpiVer );
315
316   // Tell the core the size of the surface just before we start the render-thread
317   PositionSize size = mSurface->GetPositionSize();
318   mCore->SurfaceResized( size.width, size.height );
319
320   // Initialize the thread controller
321   mThreadController->Initialize();
322
323   ProcessCoreEvents(); // Ensure any startup messages are processed.
324
325   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
326   {
327     (*iter)->OnStart();
328   }
329 }
330
331 // Dali::Internal::Adaptor::Adaptor::Pause
332 void Adaptor::Pause()
333 {
334   // Only pause the adaptor if we're actually running.
335   if( RUNNING == mState )
336   {
337     // Inform observers that we are about to be paused.
338     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
339     {
340       (*iter)->OnPause();
341     }
342
343     // Reset the event handler when adaptor paused
344     if( mEventHandler )
345     {
346       mEventHandler->Pause();
347     }
348
349     mThreadController->Pause();
350     mState = PAUSED;
351
352     // Ensure any messages queued during pause callbacks are processed by doing another update.
353     RequestUpdateOnce();
354   }
355 }
356
357 // Dali::Internal::Adaptor::Adaptor::Resume
358 void Adaptor::Resume()
359 {
360   // Only resume the adaptor if we are in the suspended state.
361   if( PAUSED == mState )
362   {
363     mState = RUNNING;
364
365     // Reset the event handler when adaptor resumed
366     if( mEventHandler )
367     {
368       mEventHandler->Resume();
369     }
370
371     // Inform observers that we have resumed.
372     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
373     {
374       (*iter)->OnResume();
375     }
376
377     // trigger processing of events queued up while paused
378     mCore->ProcessEvents();
379
380     // Do at end to ensure our first update/render after resumption includes the processed messages as well
381     mThreadController->Resume();
382   }
383 }
384
385 void Adaptor::Stop()
386 {
387   if( RUNNING == mState ||
388       PAUSED  == mState ||
389       PAUSED_WHILE_HIDDEN == mState )
390   {
391     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
392     {
393       (*iter)->OnStop();
394     }
395
396     mThreadController->Stop();
397
398     // Delete the TTS player
399     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
400     {
401       if(mTtsPlayers[i])
402       {
403         mTtsPlayers[i].Reset();
404       }
405     }
406
407     delete mEventHandler;
408     mEventHandler = NULL;
409
410     delete mNotificationTrigger;
411     mNotificationTrigger = NULL;
412
413     mCallbackManager->Stop();
414
415     mState = STOPPED;
416   }
417 }
418
419 void Adaptor::ContextLost()
420 {
421   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
422 }
423
424 void Adaptor::ContextRegained()
425 {
426   // Inform core, so that texture resources can be reloaded
427   mCore->RecoverFromContextLoss();
428
429   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
430 }
431
432 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
433 {
434   mEventHandler->FeedTouchPoint( point, timeStamp );
435 }
436
437 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
438 {
439   mEventHandler->FeedWheelEvent( wheelEvent );
440 }
441
442 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
443 {
444   mEventHandler->FeedKeyEvent( keyEvent );
445 }
446
447 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
448 {
449   PositionSize positionSize = surface.GetPositionSize();
450
451   // let the core know the surface size has changed
452   mCore->SurfaceResized( positionSize.width, positionSize.height );
453
454   mResizedSignal.Emit( mAdaptor );
455
456   mNativeWindow = nativeWindow;
457   mSurface = &surface;
458
459   // flush the event queue to give the update-render thread chance
460   // to start processing messages for new camera setup etc as soon as possible
461   ProcessCoreEvents();
462
463   // this method blocks until the render thread has completed the replace.
464   mThreadController->ReplaceSurface(mSurface);
465 }
466
467 RenderSurface& Adaptor::GetSurface() const
468 {
469   return *mSurface;
470 }
471
472 void Adaptor::ReleaseSurfaceLock()
473 {
474   mSurface->ReleaseLock();
475 }
476
477 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
478 {
479   if(!mTtsPlayers[mode])
480   {
481     // Create the TTS player when it needed, because it can reduce launching time.
482     mTtsPlayers[mode] = TtsPlayer::New(mode);
483   }
484
485   return mTtsPlayers[mode];
486 }
487
488 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
489 {
490   bool idleAdded(false);
491
492   // Only add an idle if the Adaptor is actually running
493   if( RUNNING == mState || READY == mState || forceAdd )
494   {
495     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
496   }
497
498   return idleAdded;
499 }
500
501 void Adaptor::RemoveIdle( CallbackBase* callback )
502 {
503   mCallbackManager->RemoveIdleCallback( callback );
504 }
505
506 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
507 {
508   mThreadController->SetPreRenderCallback( callback );
509 }
510
511 Dali::Adaptor& Adaptor::Get()
512 {
513   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
514   return gThreadLocalAdaptor->mAdaptor;
515 }
516
517 bool Adaptor::IsAvailable()
518 {
519   return gThreadLocalAdaptor != NULL;
520 }
521
522 void Adaptor::SceneCreated()
523 {
524   mCore->SceneCreated();
525 }
526
527 Dali::Integration::Core& Adaptor::GetCore()
528 {
529   return *mCore;
530 }
531
532 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
533 {
534   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
535 }
536
537 void Adaptor::SetUseHardwareVSync( bool useHardware )
538 {
539   mVSyncMonitor->SetUseHardwareVSync( useHardware );
540 }
541
542 EglFactory& Adaptor::GetEGLFactory() const
543 {
544   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
545   return *mEglFactory;
546 }
547
548 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
549 {
550   return *mEglFactory;
551 }
552
553 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
554 {
555   DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
556   return *mGLES;
557 }
558
559 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
560 {
561   return *mPlatformAbstraction;
562 }
563
564 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
565 {
566   return *mGLES;
567 }
568
569 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
570 {
571   return *mNotificationTrigger;
572 }
573
574 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
575 {
576   return mTriggerEventFactory;
577 }
578
579 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
580 {
581   return mSocketFactory;
582 }
583
584 RenderSurface* Adaptor::GetRenderSurfaceInterface()
585 {
586   return mSurface;
587 }
588
589 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
590 {
591   return mVSyncMonitor;
592 }
593
594 TraceInterface& Adaptor::GetKernelTraceInterface()
595 {
596   return mKernelTracer;
597 }
598
599 TraceInterface& Adaptor::GetSystemTraceInterface()
600 {
601   return mSystemTracer;
602 }
603
604 PerformanceInterface* Adaptor::GetPerformanceInterface()
605 {
606   return mPerformanceInterface;
607 }
608
609 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
610 {
611   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
612   return *mPlatformAbstraction;
613 }
614
615 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
616 {
617   mDragAndDropDetector = detector;
618
619   if ( mEventHandler )
620   {
621     mEventHandler->SetDragAndDropDetector( detector );
622   }
623 }
624
625 void Adaptor::SetRotationObserver( RotationObserver* observer )
626 {
627   if( mEventHandler )
628   {
629     mEventHandler->SetRotationObserver( observer );
630   }
631   else if( mState == READY )
632   {
633     // Set once event handler exists
634     mDeferredRotationObserver = observer;
635   }
636 }
637
638 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
639 {
640   if(mTtsPlayers[mode])
641   {
642     mTtsPlayers[mode].Reset();
643   }
644 }
645
646 void Adaptor::SetMinimumPinchDistance(float distance)
647 {
648   if( mGestureManager )
649   {
650     mGestureManager->SetMinimumPinchDistance(distance);
651   }
652 }
653
654 Any Adaptor::GetNativeWindowHandle()
655 {
656   return mNativeWindow;
657 }
658
659 Any Adaptor::GetGraphicsDisplay()
660 {
661   Any display;
662
663   if( mEglFactory )
664   {
665     EglInterface* egl = mEglFactory->GetImplementation();
666     if( egl )
667     {
668       auto eglImpl = static_cast<EglImplementation*>(egl);
669       display = eglImpl->GetDisplay();
670     }
671   }
672   return display;
673 }
674
675 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
676 {
677   mUseRemoteSurface = useRemoteSurface;
678 }
679
680 void Adaptor::AddObserver( LifeCycleObserver& observer )
681 {
682   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
683
684   if ( match == mObservers.end() )
685   {
686     mObservers.push_back( &observer );
687   }
688 }
689
690 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
691 {
692   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
693
694   if ( match != mObservers.end() )
695   {
696     mObservers.erase( match );
697   }
698 }
699
700 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
701 {
702   if( mCore )
703   {
704     mCore->QueueEvent(event);
705   }
706 }
707
708 void Adaptor::ProcessCoreEvents()
709 {
710   if( mCore )
711   {
712     if( mPerformanceInterface )
713     {
714       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
715     }
716
717     mCore->ProcessEvents();
718
719     if( mPerformanceInterface )
720     {
721       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
722     }
723   }
724 }
725
726 void Adaptor::RequestUpdate( bool forceUpdate )
727 {
728   switch( mState )
729   {
730     case RUNNING:
731     {
732       mThreadController->RequestUpdate();
733       break;
734     }
735     case PAUSED:
736     case PAUSED_WHILE_HIDDEN:
737     {
738       // When Dali applications are partially visible behind the lock-screen,
739       // the indicator must be updated (therefore allow updates in the PAUSED state)
740       if( forceUpdate )
741       {
742         mThreadController->RequestUpdateOnce();
743       }
744       break;
745     }
746     default:
747     {
748       // Do nothing
749       break;
750     }
751   }
752 }
753
754 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
755 {
756   // Only request a notification if the Adaptor is actually running
757   // and we haven't installed the idle notification
758   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
759   {
760     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
761   }
762 }
763
764 void Adaptor::OnWindowShown()
765 {
766   if ( PAUSED_WHILE_HIDDEN == mState )
767   {
768     // Adaptor can now be resumed
769     mState = PAUSED;
770
771     Resume();
772
773     // Force a render task
774     RequestUpdateOnce();
775   }
776 }
777
778 void Adaptor::OnWindowHidden()
779 {
780   if ( RUNNING == mState )
781   {
782     Pause();
783
784     // Adaptor cannot be resumed until the window is shown
785     mState = PAUSED_WHILE_HIDDEN;
786   }
787 }
788
789 // Dali::Internal::Adaptor::Adaptor::OnDamaged
790 void Adaptor::OnDamaged( const DamageArea& area )
791 {
792   // This is needed for the case where Dali window is partially obscured
793   RequestUpdate( false );
794 }
795
796 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
797 {
798   // let the core know the surface size has changed
799   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
800
801   mResizedSignal.Emit( mAdaptor );
802 }
803
804 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
805 {
806   // flush the event queue to give the update-render thread chance
807   // to start processing messages for new camera setup etc as soon as possible
808   ProcessCoreEvents();
809
810   mThreadController->ResizeSurface();
811 }
812
813 void Adaptor::NotifySceneCreated()
814 {
815   GetCore().SceneCreated();
816
817   // Start thread controller after the scene has been created
818   mThreadController->Start();
819
820   // process after surface is created (registering to remote surface provider if required)
821   SurfaceInitialized();
822
823   mState = RUNNING;
824 }
825
826 void Adaptor::NotifyLanguageChanged()
827 {
828   mLanguageChangedSignal.Emit( mAdaptor );
829 }
830
831 void Adaptor::RenderOnce()
832 {
833   RequestUpdateOnce();
834 }
835
836 const LogFactoryInterface& Adaptor::GetLogFactory()
837 {
838   return *mEnvironmentOptions;
839 }
840
841 void Adaptor::RequestUpdateOnce()
842 {
843   if( mThreadController )
844   {
845     mThreadController->RequestUpdateOnce();
846   }
847 }
848
849 void Adaptor::IndicatorSizeChanged(int height)
850 {
851   // let the core know the indicator height is changed
852   mCore->SetTopMargin(height);
853 }
854
855 bool Adaptor::ProcessCoreEventsFromIdle()
856 {
857   ProcessCoreEvents();
858
859   // the idle handle automatically un-installs itself
860   mNotificationOnIdleInstalled = false;
861
862   return false;
863 }
864
865 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
866 : mResizedSignal(),
867   mLanguageChangedSignal(),
868   mAdaptor( adaptor ),
869   mState( READY ),
870   mCore( NULL ),
871   mThreadController( NULL ),
872   mVSyncMonitor( NULL ),
873   mGLES( NULL ),
874   mGlSync( NULL ),
875   mEglFactory( NULL ),
876   mNativeWindow( nativeWindow ),
877   mSurface( surface ),
878   mPlatformAbstraction( NULL ),
879   mEventHandler( NULL ),
880   mCallbackManager( NULL ),
881   mNotificationOnIdleInstalled( false ),
882   mNotificationTrigger( NULL ),
883   mGestureManager( NULL ),
884   mDaliFeedbackPlugin(),
885   mFeedbackController( NULL ),
886   mTtsPlayers(),
887   mObservers(),
888   mDragAndDropDetector(),
889   mDeferredRotationObserver( NULL ),
890   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
891   mPerformanceInterface( NULL ),
892   mKernelTracer(),
893   mSystemTracer(),
894   mTriggerEventFactory(),
895   mObjectProfiler( NULL ),
896   mSocketFactory(),
897   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
898   mUseRemoteSurface( false )
899 {
900   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
901   gThreadLocalAdaptor = this;
902 }
903
904 // Stereoscopy
905
906 void Adaptor::SetViewMode( ViewMode viewMode )
907 {
908   mSurface->SetViewMode( viewMode );
909   mCore->SetViewMode( viewMode );
910 }
911
912 ViewMode Adaptor::GetViewMode() const
913 {
914   return mCore->GetViewMode();
915 }
916
917 void Adaptor::SetStereoBase( float stereoBase )
918 {
919   mCore->SetStereoBase( stereoBase );
920 }
921
922 float Adaptor::GetStereoBase() const
923 {
924   return mCore->GetStereoBase();
925 }
926
927 void Adaptor::SetRootLayoutDirection( std::string locale )
928 {
929   Dali::Stage stage = Dali::Stage::GetCurrent();
930
931   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
932                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
933 }
934
935 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
936 {
937   bool idleAdded( false );
938
939   // Only add an idle if the Adaptor is actually running
940   if( RUNNING == mState || READY == mState || forceAdd )
941   {
942     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
943   }
944
945   return idleAdded;
946 }
947
948 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
949 {
950   mCallbackManager->RemoveIdleEntererCallback( callback );
951 }
952
953 } // namespace Adaptor
954
955 } // namespace Internal
956
957 } // namespace Dali