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