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