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