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