Merge "prevent division by zero" 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 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
527 {
528   // Flush the event queue to give the update-render thread chance
529   // to start processing messages for new camera setup etc as soon as possible
530   ProcessCoreEvents();
531
532   // This method blocks until the render thread has finished rendering the current surface.
533   mThreadController->DeleteSurface( &surface );
534 }
535
536 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
537 {
538   return *mWindows.front()->GetSurface();
539 }
540
541 void Adaptor::ReleaseSurfaceLock()
542 {
543   mWindows.front()->GetSurface()->ReleaseLock();
544 }
545
546 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
547 {
548   if( !mTtsPlayers[mode] )
549   {
550     // Create the TTS player when it needed, because it can reduce launching time.
551     mTtsPlayers[mode] = TtsPlayer::New(mode);
552   }
553
554   return mTtsPlayers[mode];
555 }
556
557 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
558 {
559   bool idleAdded(false);
560
561   // Only add an idle if the Adaptor is actually running
562   if( RUNNING == mState || READY == mState || forceAdd )
563   {
564     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
565   }
566
567   return idleAdded;
568 }
569
570 void Adaptor::RemoveIdle( CallbackBase* callback )
571 {
572   mCallbackManager->RemoveIdleCallback( callback );
573 }
574
575 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
576 {
577   mThreadController->SetPreRenderCallback( callback );
578 }
579
580 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
581 {
582   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
583   windowImpl.SetAdaptor( Get() );
584
585   // Add the new Window to the container - the order is not important
586   mWindows.push_back( &windowImpl );
587
588   Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
589   if ( window )
590   {
591     mWindowCreatedSignal.Emit( window );
592   }
593
594   return true;
595 }
596
597 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
598 {
599   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
600   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
601   {
602     if( *iter == &windowImpl )
603     {
604       mWindows.erase( iter );
605       return true;
606     }
607   }
608
609   return false;
610 }
611
612 bool Adaptor::RemoveWindow( std::string childWindowName )
613 {
614   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
615   {
616     if( ( *iter )->GetName() == childWindowName )
617     {
618       mWindows.erase( iter );
619       return true;
620     }
621   }
622
623   return false;
624 }
625
626 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
627 {
628   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
629   {
630     if( ( *iter )->GetId() == childWindow->GetId() )
631     {
632       mWindows.erase( iter );
633       return true;
634     }
635   }
636
637   return false;
638 }
639
640 Dali::Adaptor& Adaptor::Get()
641 {
642   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
643   return gThreadLocalAdaptor->mAdaptor;
644 }
645
646 bool Adaptor::IsAvailable()
647 {
648   return gThreadLocalAdaptor != NULL;
649 }
650
651 void Adaptor::SceneCreated()
652 {
653   mCore->SceneCreated();
654 }
655
656 Dali::Integration::Core& Adaptor::GetCore()
657 {
658   return *mCore;
659 }
660
661 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
662 {
663   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
664 }
665
666 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
667 {
668   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
669   return *mDisplayConnection;
670 }
671
672 GraphicsInterface& Adaptor::GetGraphicsInterface()
673 {
674   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
675   return *mGraphics;
676 }
677
678 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
679 {
680   return *mPlatformAbstraction;
681 }
682
683 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
684 {
685   return *mNotificationTrigger;
686 }
687
688 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
689 {
690   return mTriggerEventFactory;
691 }
692
693 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
694 {
695   return mSocketFactory;
696 }
697
698 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
699 {
700   if( !mWindows.empty() )
701   {
702     return mWindows.front()->GetSurface();
703   }
704
705   return nullptr;
706 }
707
708 TraceInterface& Adaptor::GetKernelTraceInterface()
709 {
710   return mKernelTracer;
711 }
712
713 TraceInterface& Adaptor::GetSystemTraceInterface()
714 {
715   return mSystemTracer;
716 }
717
718 PerformanceInterface* Adaptor::GetPerformanceInterface()
719 {
720   return mPerformanceInterface;
721 }
722
723 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
724 {
725   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
726   return *mPlatformAbstraction;
727 }
728
729 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
730 {
731   if( mTtsPlayers[mode] )
732   {
733     mTtsPlayers[mode].Reset();
734   }
735 }
736
737 Any Adaptor::GetNativeWindowHandle()
738 {
739   return mWindows.front()->GetNativeHandle();
740 }
741
742 Any Adaptor::GetGraphicsDisplay()
743 {
744   Any display;
745
746   if (mGraphics)
747   {
748     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
749
750     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
751     display = eglImpl.GetDisplay();
752   }
753
754   return display;
755 }
756
757 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
758 {
759   mUseRemoteSurface = useRemoteSurface;
760 }
761
762 void Adaptor::AddObserver( LifeCycleObserver& observer )
763 {
764   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
765
766   if ( match == mObservers.end() )
767   {
768     mObservers.push_back( &observer );
769   }
770 }
771
772 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
773 {
774   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
775
776   if ( match != mObservers.end() )
777   {
778     mObservers.erase( match );
779   }
780 }
781
782 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
783 {
784   if( mCore )
785   {
786     mCore->QueueEvent(event);
787   }
788 }
789
790 void Adaptor::ProcessCoreEvents()
791 {
792   if( mCore )
793   {
794     if( mPerformanceInterface )
795     {
796       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
797     }
798
799     mCore->ProcessEvents();
800
801     if( mPerformanceInterface )
802     {
803       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
804     }
805   }
806 }
807
808 void Adaptor::RequestUpdate( bool forceUpdate )
809 {
810   switch( mState )
811   {
812     case RUNNING:
813     {
814       mThreadController->RequestUpdate();
815       break;
816     }
817     case PAUSED:
818     case PAUSED_WHILE_HIDDEN:
819     {
820       // When Dali applications are partially visible behind the lock-screen,
821       // the indicator must be updated (therefore allow updates in the PAUSED state)
822       if( forceUpdate )
823       {
824         mThreadController->RequestUpdateOnce();
825       }
826       break;
827     }
828     default:
829     {
830       // Do nothing
831       break;
832     }
833   }
834 }
835
836 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
837 {
838   // Only request a notification if the Adaptor is actually running
839   // and we haven't installed the idle notification
840   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
841   {
842     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
843   }
844 }
845
846 void Adaptor::OnWindowShown()
847 {
848   if( PAUSED_WHILE_HIDDEN == mState )
849   {
850     // Adaptor can now be resumed
851     mState = PAUSED;
852
853     Resume();
854
855     // Force a render task
856     RequestUpdateOnce();
857   }
858   else if( RUNNING == mState )
859   {
860     // Force a render task
861     RequestUpdateOnce();
862
863     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
864   }
865   else
866   {
867     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
868   }
869 }
870
871 void Adaptor::OnWindowHidden()
872 {
873   if( RUNNING == mState || READY == mState )
874   {
875     bool allWindowsHidden = true;
876
877     for( auto window : mWindows )
878     {
879       if ( window->IsVisible() )
880       {
881         allWindowsHidden = false;
882         break;
883       }
884     }
885
886     // Only pause the adaptor when all the windows are hidden
887     if( allWindowsHidden )
888     {
889       if( mState == RUNNING )
890       {
891         Pause();
892
893         // Adaptor cannot be resumed until any window is shown
894         mState = PAUSED_WHILE_HIDDEN;
895       }
896       else  // mState is READY
897       {
898         // Pause the adaptor after the state gets RUNNING
899         mState = PAUSED_WHILE_INITIALIZING;
900       }
901     }
902     else
903     {
904       DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
905     }
906   }
907   else
908   {
909     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
910   }
911 }
912
913 // Dali::Internal::Adaptor::Adaptor::OnDamaged
914 void Adaptor::OnDamaged( const DamageArea& area )
915 {
916   // This is needed for the case where Dali window is partially obscured
917   RequestUpdate( false );
918 }
919
920 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
921 {
922   // Let the core know the surface size has changed
923   mCore->SurfaceResized( surface );
924
925   mResizedSignal.Emit( mAdaptor );
926 }
927
928 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
929 {
930   // Flush the event queue to give the update-render thread chance
931   // to start processing messages for new camera setup etc as soon as possible
932   ProcessCoreEvents();
933
934   mThreadController->ResizeSurface();
935 }
936
937 void Adaptor::NotifySceneCreated()
938 {
939   GetCore().SceneCreated();
940
941   // Flush the event queue to give the update-render thread chance
942   // to start processing messages for new camera setup etc as soon as possible
943   ProcessCoreEvents();
944
945   // Start thread controller after the scene has been created
946   mThreadController->Start();
947
948   // Process after surface is created (registering to remote surface provider if required)
949   SurfaceInitialized();
950
951   if( mState != PAUSED_WHILE_INITIALIZING )
952   {
953     mState = RUNNING;
954
955     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
956   }
957   else
958   {
959     mState = RUNNING;
960
961     Pause();
962
963     mState = PAUSED_WHILE_HIDDEN;
964
965     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
966   }
967 }
968
969 void Adaptor::NotifyLanguageChanged()
970 {
971   mLanguageChangedSignal.Emit( mAdaptor );
972 }
973
974 void Adaptor::RenderOnce()
975 {
976   RequestUpdateOnce();
977 }
978
979 const LogFactoryInterface& Adaptor::GetLogFactory()
980 {
981   return *mEnvironmentOptions;
982 }
983
984 void Adaptor::RegisterProcessor( Integration::Processor& processor )
985 {
986   GetCore().RegisterProcessor(processor);
987 }
988
989 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
990 {
991   GetCore().UnregisterProcessor(processor);
992 }
993
994 void Adaptor::RequestUpdateOnce()
995 {
996   if( mThreadController )
997   {
998     mThreadController->RequestUpdateOnce();
999   }
1000 }
1001
1002 bool Adaptor::ProcessCoreEventsFromIdle()
1003 {
1004   ProcessCoreEvents();
1005
1006   // the idle handle automatically un-installs itself
1007   mNotificationOnIdleInstalled = false;
1008
1009   return false;
1010 }
1011
1012 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1013 {
1014   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1015
1016   for( auto window : mWindows )
1017   {
1018     if ( scene == window->GetScene() )
1019     {
1020       return window;
1021     }
1022   }
1023
1024   return nullptr;
1025 }
1026
1027 Dali::WindowContainer Adaptor::GetWindows() const
1028 {
1029   Dali::WindowContainer windows;
1030
1031   for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1032   {
1033     // Downcast to Dali::Window
1034     Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1035     if ( window )
1036     {
1037       windows.push_back( window );
1038     }
1039   }
1040
1041   return windows;
1042 }
1043
1044 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1045 : mResizedSignal(),
1046   mLanguageChangedSignal(),
1047   mWindowCreatedSignal(),
1048   mAdaptor( adaptor ),
1049   mState( READY ),
1050   mCore( nullptr ),
1051   mThreadController( nullptr ),
1052   mGraphics( nullptr ),
1053   mDisplayConnection( nullptr ),
1054   mWindows(),
1055   mPlatformAbstraction( nullptr ),
1056   mCallbackManager( nullptr ),
1057   mNotificationOnIdleInstalled( false ),
1058   mNotificationTrigger( nullptr ),
1059   mDaliFeedbackPlugin(),
1060   mFeedbackController( nullptr ),
1061   mTtsPlayers(),
1062   mObservers(),
1063   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1064   mPerformanceInterface( nullptr ),
1065   mKernelTracer(),
1066   mSystemTracer(),
1067   mTriggerEventFactory(),
1068   mObjectProfiler( nullptr ),
1069   mSocketFactory(),
1070   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1071   mUseRemoteSurface( false )
1072 {
1073   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1074   mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1075
1076   gThreadLocalAdaptor = this;
1077 }
1078
1079 void Adaptor::SetRootLayoutDirection( std::string locale )
1080 {
1081   Dali::Stage stage = Dali::Stage::GetCurrent();
1082
1083   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1084                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1085 }
1086
1087 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1088 {
1089   bool idleAdded( false );
1090
1091   // Only add an idle if the Adaptor is actually running
1092   if( RUNNING == mState || READY == mState || forceAdd )
1093   {
1094     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1095   }
1096
1097   return idleAdded;
1098 }
1099
1100 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1101 {
1102   mCallbackManager->RemoveIdleEntererCallback( callback );
1103 }
1104
1105 } // namespace Adaptor
1106
1107 } // namespace Internal
1108
1109 } // namespace Dali