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