Merge "Added helper function to retrieve which window a given actor is added to"...
[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::Integration::SceneHolder 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::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
101 {
102   Internal::Adaptor::SceneHolder& 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::Integration::SceneHolder 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::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
120 {
121   Internal::Adaptor::SceneHolder& 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   SceneHolderPtr 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( Get() );
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   SceneHolderPtr 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( SceneHolderPtr 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( SceneHolderPtr 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::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
490 {
491   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
492   for( SceneHolderPtr 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( &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::Integration::SceneHolder* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
559 {
560   Internal::Adaptor::SceneHolder& 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( SceneHolderPtr( &windowImpl ) );
565   return true;
566 }
567
568 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
569 {
570   Internal::Adaptor::SceneHolder& 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( Internal::Adaptor::SceneHolder* 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::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
711 {
712   if( mTtsPlayers[mode] )
713   {
714     mTtsPlayers[mode].Reset();
715   }
716 }
717
718 void Adaptor::SetMinimumPinchDistance(float distance)
719 {
720   if( mGestureManager )
721   {
722     mGestureManager->SetMinimumPinchDistance(distance);
723   }
724 }
725
726 Any Adaptor::GetNativeWindowHandle()
727 {
728   return mWindows.front()->GetNativeHandle();
729 }
730
731 Any Adaptor::GetGraphicsDisplay()
732 {
733   Any display;
734
735   if (mGraphics)
736   {
737     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
738
739     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
740     display = eglImpl.GetDisplay();
741   }
742
743   return display;
744 }
745
746 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
747 {
748   mUseRemoteSurface = useRemoteSurface;
749 }
750
751 void Adaptor::AddObserver( LifeCycleObserver& observer )
752 {
753   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
754
755   if ( match == mObservers.end() )
756   {
757     mObservers.push_back( &observer );
758   }
759 }
760
761 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
762 {
763   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
764
765   if ( match != mObservers.end() )
766   {
767     mObservers.erase( match );
768   }
769 }
770
771 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
772 {
773   if( mCore )
774   {
775     mCore->QueueEvent(event);
776   }
777 }
778
779 void Adaptor::ProcessCoreEvents()
780 {
781   if( mCore )
782   {
783     if( mPerformanceInterface )
784     {
785       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
786     }
787
788     mCore->ProcessEvents();
789
790     if( mPerformanceInterface )
791     {
792       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
793     }
794   }
795 }
796
797 void Adaptor::RequestUpdate( bool forceUpdate )
798 {
799   switch( mState )
800   {
801     case RUNNING:
802     {
803       mThreadController->RequestUpdate();
804       break;
805     }
806     case PAUSED:
807     case PAUSED_WHILE_HIDDEN:
808     {
809       // When Dali applications are partially visible behind the lock-screen,
810       // the indicator must be updated (therefore allow updates in the PAUSED state)
811       if( forceUpdate )
812       {
813         mThreadController->RequestUpdateOnce();
814       }
815       break;
816     }
817     default:
818     {
819       // Do nothing
820       break;
821     }
822   }
823 }
824
825 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
826 {
827   // Only request a notification if the Adaptor is actually running
828   // and we haven't installed the idle notification
829   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
830   {
831     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
832   }
833 }
834
835 void Adaptor::OnWindowShown()
836 {
837   if ( PAUSED_WHILE_HIDDEN == mState )
838   {
839     // Adaptor can now be resumed
840     mState = PAUSED;
841
842     Resume();
843
844     // Force a render task
845     RequestUpdateOnce();
846   }
847   else
848   {
849     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Not shown [%d]\n", mState );
850   }
851 }
852
853 void Adaptor::OnWindowHidden()
854 {
855   if ( RUNNING == mState )
856   {
857     bool allWindowsHidden = true;
858
859     for( SceneHolderPtr window : mWindows )
860     {
861       if ( window->IsVisible() )
862       {
863         allWindowsHidden = false;
864         break;
865       }
866     }
867
868     // Only pause the adaptor when all the windows are hidden
869     if ( allWindowsHidden )
870     {
871       Pause();
872
873       // Adaptor cannot be resumed until any window is shown
874       mState = PAUSED_WHILE_HIDDEN;
875     }
876   }
877   else
878   {
879     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Not hidden [%d]\n", mState );
880   }
881 }
882
883 // Dali::Internal::Adaptor::Adaptor::OnDamaged
884 void Adaptor::OnDamaged( const DamageArea& area )
885 {
886   // This is needed for the case where Dali window is partially obscured
887   RequestUpdate( false );
888 }
889
890 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
891 {
892   // Let the core know the surface size has changed
893   mCore->SurfaceResized( surface );
894
895   mResizedSignal.Emit( mAdaptor );
896 }
897
898 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
899 {
900   // Flush the event queue to give the update-render thread chance
901   // to start processing messages for new camera setup etc as soon as possible
902   ProcessCoreEvents();
903
904   mThreadController->ResizeSurface();
905 }
906
907 void Adaptor::NotifySceneCreated()
908 {
909   GetCore().SceneCreated();
910
911   // Flush the event queue to give the update-render thread chance
912   // to start processing messages for new camera setup etc as soon as possible
913   ProcessCoreEvents();
914
915   // Start thread controller after the scene has been created
916   mThreadController->Start();
917
918   // Process after surface is created (registering to remote surface provider if required)
919   SurfaceInitialized();
920
921   mState = RUNNING;
922
923   DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated\n" );
924 }
925
926 void Adaptor::NotifyLanguageChanged()
927 {
928   mLanguageChangedSignal.Emit( mAdaptor );
929 }
930
931 void Adaptor::RenderOnce()
932 {
933   RequestUpdateOnce();
934 }
935
936 const LogFactoryInterface& Adaptor::GetLogFactory()
937 {
938   return *mEnvironmentOptions;
939 }
940
941 void Adaptor::RegisterProcessor( Integration::Processor& processor )
942 {
943   GetCore().RegisterProcessor(processor);
944 }
945
946 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
947 {
948   GetCore().UnregisterProcessor(processor);
949 }
950
951 void Adaptor::RequestUpdateOnce()
952 {
953   if( mThreadController )
954   {
955     mThreadController->RequestUpdateOnce();
956   }
957 }
958
959 bool Adaptor::ProcessCoreEventsFromIdle()
960 {
961   ProcessCoreEvents();
962
963   // the idle handle automatically un-installs itself
964   mNotificationOnIdleInstalled = false;
965
966   return false;
967 }
968
969 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
970 {
971   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
972
973   for( auto window : mWindows )
974   {
975     if ( scene == window->GetScene() )
976     {
977       return window.Get();
978     }
979   }
980
981   return nullptr;
982 }
983
984 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
985 : mResizedSignal(),
986   mLanguageChangedSignal(),
987   mAdaptor( adaptor ),
988   mState( READY ),
989   mCore( nullptr ),
990   mThreadController( nullptr ),
991   mVSyncMonitor( nullptr ),
992   mGraphics( nullptr ),
993   mDisplayConnection( nullptr ),
994   mWindows(),
995   mPlatformAbstraction( nullptr ),
996   mCallbackManager( nullptr ),
997   mNotificationOnIdleInstalled( false ),
998   mNotificationTrigger( nullptr ),
999   mGestureManager( nullptr ),
1000   mDaliFeedbackPlugin(),
1001   mFeedbackController( nullptr ),
1002   mTtsPlayers(),
1003   mObservers(),
1004   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1005   mPerformanceInterface( nullptr ),
1006   mKernelTracer(),
1007   mSystemTracer(),
1008   mTriggerEventFactory(),
1009   mObjectProfiler( nullptr ),
1010   mSocketFactory(),
1011   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1012   mUseRemoteSurface( false )
1013 {
1014   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1015   mWindows.insert( mWindows.begin(), SceneHolderPtr( &Dali::GetImplementation( window ) ) );
1016
1017   gThreadLocalAdaptor = this;
1018 }
1019
1020 void Adaptor::SetRootLayoutDirection( std::string locale )
1021 {
1022   Dali::Stage stage = Dali::Stage::GetCurrent();
1023
1024   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1025                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1026 }
1027
1028 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1029 {
1030   bool idleAdded( false );
1031
1032   // Only add an idle if the Adaptor is actually running
1033   if( RUNNING == mState || READY == mState || forceAdd )
1034   {
1035     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1036   }
1037
1038   return idleAdded;
1039 }
1040
1041 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1042 {
1043   mCallbackManager->RemoveIdleEntererCallback( callback );
1044 }
1045
1046 } // namespace Adaptor
1047
1048 } // namespace Internal
1049
1050 } // namespace Dali