Revert "[Tizen] To get MaxTextureSize by using glGetIntegerv not by using environment...
[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   // Initialize the thread controller
354   mThreadController->Initialize();
355
356   ProcessCoreEvents(); // Ensure any startup messages are processed.
357
358   // Initialize the image loader plugin
359   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
360
361   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
362   {
363     (*iter)->OnStart();
364   }
365 }
366
367 // Dali::Internal::Adaptor::Adaptor::Pause
368 void Adaptor::Pause()
369 {
370   // Only pause the adaptor if we're actually running.
371   if( RUNNING == mState )
372   {
373     // Inform observers that we are about to be paused.
374     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
375     {
376       (*iter)->OnPause();
377     }
378
379     // Pause all windows event handlers when adaptor paused
380     for( auto window : mWindows )
381     {
382       window->Pause();
383     }
384
385     mThreadController->Pause();
386     mState = PAUSED;
387
388     // Ensure any messages queued during pause callbacks are processed by doing another update.
389     RequestUpdateOnce();
390
391     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
392   }
393   else
394   {
395     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
396   }
397 }
398
399 // Dali::Internal::Adaptor::Adaptor::Resume
400 void Adaptor::Resume()
401 {
402   // Only resume the adaptor if we are in the suspended state.
403   if( PAUSED == mState )
404   {
405     mState = RUNNING;
406
407     // Reset the event handlers when adaptor resumed
408     for( auto window : mWindows )
409     {
410       window->Resume();
411     }
412
413     // Inform observers that we have resumed.
414     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
415     {
416       (*iter)->OnResume();
417     }
418
419     // Trigger processing of events queued up while paused
420     mCore->ProcessEvents();
421
422     // Do at end to ensure our first update/render after resumption includes the processed messages as well
423     mThreadController->Resume();
424
425     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
426   }
427   else
428   {
429     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
430   }
431 }
432
433 void Adaptor::Stop()
434 {
435   if( RUNNING == mState ||
436       PAUSED  == mState ||
437       PAUSED_WHILE_HIDDEN == mState )
438   {
439     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
440     {
441       (*iter)->OnStop();
442     }
443
444     mThreadController->Stop();
445
446     // Delete the TTS player
447     for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
448     {
449       if( mTtsPlayers[i] )
450       {
451         mTtsPlayers[i].Reset();
452       }
453     }
454
455     // Destroy the image loader plugin
456     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
457
458     delete mNotificationTrigger;
459     mNotificationTrigger = NULL;
460
461     mCallbackManager->Stop();
462
463     mState = STOPPED;
464
465     DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
466   }
467 }
468
469 void Adaptor::ContextLost()
470 {
471   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
472 }
473
474 void Adaptor::ContextRegained()
475 {
476   // Inform core, so that texture resources can be reloaded
477   mCore->RecoverFromContextLoss();
478
479   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
480 }
481
482 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
483 {
484   Integration::Point convertedPoint( point );
485   mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
486 }
487
488 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
489 {
490   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
491   mWindows.front()->FeedWheelEvent( event );
492 }
493
494 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
495 {
496   Integration::KeyEvent convertedEvent( keyEvent );
497   mWindows.front()->FeedKeyEvent( convertedEvent );
498 }
499
500 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
501 {
502   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
503   for( auto windowPtr : mWindows )
504   {
505     if( windowPtr == windowImpl ) // the window is not deleted
506     {
507       mResizedSignal.Emit( mAdaptor );
508
509       windowImpl->SetSurface( &newSurface );
510
511       // Flush the event queue to give the update-render thread chance
512       // to start processing messages for new camera setup etc as soon as possible
513       ProcessCoreEvents();
514
515       // This method blocks until the render thread has completed the replace.
516       mThreadController->ReplaceSurface( &newSurface );
517       break;
518     }
519   }
520 }
521
522 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
523 {
524   // Flush the event queue to give the update-render thread chance
525   // to start processing messages for new camera setup etc as soon as possible
526   ProcessCoreEvents();
527
528   // This method blocks until the render thread has finished rendering the current surface.
529   mThreadController->DeleteSurface( &surface );
530 }
531
532 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
533 {
534   return *mWindows.front()->GetSurface();
535 }
536
537 void Adaptor::ReleaseSurfaceLock()
538 {
539   mWindows.front()->GetSurface()->ReleaseLock();
540 }
541
542 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
543 {
544   if( !mTtsPlayers[mode] )
545   {
546     // Create the TTS player when it needed, because it can reduce launching time.
547     mTtsPlayers[mode] = TtsPlayer::New(mode);
548   }
549
550   return mTtsPlayers[mode];
551 }
552
553 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
554 {
555   bool idleAdded(false);
556
557   // Only add an idle if the Adaptor is actually running
558   if( RUNNING == mState || READY == mState || forceAdd )
559   {
560     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
561   }
562
563   return idleAdded;
564 }
565
566 void Adaptor::RemoveIdle( CallbackBase* callback )
567 {
568   mCallbackManager->RemoveIdleCallback( callback );
569 }
570
571 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
572 {
573   mThreadController->SetPreRenderCallback( callback );
574 }
575
576 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
577 {
578   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
579   windowImpl.SetAdaptor( Get() );
580
581   // Add the new Window to the container - the order is not important
582   mWindows.push_back( &windowImpl );
583
584   Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
585   if ( window )
586   {
587     mWindowCreatedSignal.Emit( window );
588   }
589
590   return true;
591 }
592
593 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
594 {
595   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
596   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
597   {
598     if( *iter == &windowImpl )
599     {
600       mWindows.erase( iter );
601       return true;
602     }
603   }
604
605   return false;
606 }
607
608 bool Adaptor::RemoveWindow( std::string childWindowName )
609 {
610   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
611   {
612     if( ( *iter )->GetName() == childWindowName )
613     {
614       mWindows.erase( iter );
615       return true;
616     }
617   }
618
619   return false;
620 }
621
622 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
623 {
624   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
625   {
626     if( ( *iter )->GetId() == childWindow->GetId() )
627     {
628       mWindows.erase( iter );
629       return true;
630     }
631   }
632
633   return false;
634 }
635
636 Dali::Adaptor& Adaptor::Get()
637 {
638   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
639   return gThreadLocalAdaptor->mAdaptor;
640 }
641
642 bool Adaptor::IsAvailable()
643 {
644   return gThreadLocalAdaptor != NULL;
645 }
646
647 void Adaptor::SceneCreated()
648 {
649   mCore->SceneCreated();
650 }
651
652 Dali::Integration::Core& Adaptor::GetCore()
653 {
654   return *mCore;
655 }
656
657 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
658 {
659   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
660 }
661
662 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
663 {
664   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
665   return *mDisplayConnection;
666 }
667
668 GraphicsInterface& Adaptor::GetGraphicsInterface()
669 {
670   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
671   return *mGraphics;
672 }
673
674 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
675 {
676   return *mPlatformAbstraction;
677 }
678
679 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
680 {
681   return *mNotificationTrigger;
682 }
683
684 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
685 {
686   return mTriggerEventFactory;
687 }
688
689 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
690 {
691   return mSocketFactory;
692 }
693
694 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
695 {
696   if( !mWindows.empty() )
697   {
698     return mWindows.front()->GetSurface();
699   }
700
701   return nullptr;
702 }
703
704 TraceInterface& Adaptor::GetKernelTraceInterface()
705 {
706   return mKernelTracer;
707 }
708
709 TraceInterface& Adaptor::GetSystemTraceInterface()
710 {
711   return mSystemTracer;
712 }
713
714 PerformanceInterface* Adaptor::GetPerformanceInterface()
715 {
716   return mPerformanceInterface;
717 }
718
719 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
720 {
721   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
722   return *mPlatformAbstraction;
723 }
724
725 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
726 {
727   if( mTtsPlayers[mode] )
728   {
729     mTtsPlayers[mode].Reset();
730   }
731 }
732
733 Any Adaptor::GetNativeWindowHandle()
734 {
735   return mWindows.front()->GetNativeHandle();
736 }
737
738 Any Adaptor::GetGraphicsDisplay()
739 {
740   Any display;
741
742   if (mGraphics)
743   {
744     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
745
746     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
747     display = eglImpl.GetDisplay();
748   }
749
750   return display;
751 }
752
753 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
754 {
755   mUseRemoteSurface = useRemoteSurface;
756 }
757
758 void Adaptor::AddObserver( LifeCycleObserver& observer )
759 {
760   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
761
762   if ( match == mObservers.end() )
763   {
764     mObservers.push_back( &observer );
765   }
766 }
767
768 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
769 {
770   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
771
772   if ( match != mObservers.end() )
773   {
774     mObservers.erase( match );
775   }
776 }
777
778 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
779 {
780   if( mCore )
781   {
782     mCore->QueueEvent(event);
783   }
784 }
785
786 void Adaptor::ProcessCoreEvents()
787 {
788   if( mCore )
789   {
790     if( mPerformanceInterface )
791     {
792       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
793     }
794
795     mCore->ProcessEvents();
796
797     if( mPerformanceInterface )
798     {
799       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
800     }
801   }
802 }
803
804 void Adaptor::RequestUpdate( bool forceUpdate )
805 {
806   switch( mState )
807   {
808     case RUNNING:
809     {
810       mThreadController->RequestUpdate();
811       break;
812     }
813     case PAUSED:
814     case PAUSED_WHILE_HIDDEN:
815     {
816       // When Dali applications are partially visible behind the lock-screen,
817       // the indicator must be updated (therefore allow updates in the PAUSED state)
818       if( forceUpdate )
819       {
820         mThreadController->RequestUpdateOnce();
821       }
822       break;
823     }
824     default:
825     {
826       // Do nothing
827       break;
828     }
829   }
830 }
831
832 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
833 {
834   // Only request a notification if the Adaptor is actually running
835   // and we haven't installed the idle notification
836   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
837   {
838     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
839   }
840 }
841
842 void Adaptor::OnWindowShown()
843 {
844   if( PAUSED_WHILE_HIDDEN == mState )
845   {
846     // Adaptor can now be resumed
847     mState = PAUSED;
848
849     Resume();
850
851     // Force a render task
852     RequestUpdateOnce();
853   }
854   else if( RUNNING == mState )
855   {
856     // Force a render task
857     RequestUpdateOnce();
858
859     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
860   }
861   else
862   {
863     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
864   }
865 }
866
867 void Adaptor::OnWindowHidden()
868 {
869   if( RUNNING == mState || READY == mState )
870   {
871     bool allWindowsHidden = true;
872
873     for( auto window : mWindows )
874     {
875       if ( window->IsVisible() )
876       {
877         allWindowsHidden = false;
878         break;
879       }
880     }
881
882     // Only pause the adaptor when all the windows are hidden
883     if( allWindowsHidden )
884     {
885       if( mState == RUNNING )
886       {
887         Pause();
888
889         // Adaptor cannot be resumed until any window is shown
890         mState = PAUSED_WHILE_HIDDEN;
891       }
892       else  // mState is READY
893       {
894         // Pause the adaptor after the state gets RUNNING
895         mState = PAUSED_WHILE_INITIALIZING;
896       }
897     }
898     else
899     {
900       DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
901     }
902   }
903   else
904   {
905     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
906   }
907 }
908
909 // Dali::Internal::Adaptor::Adaptor::OnDamaged
910 void Adaptor::OnDamaged( const DamageArea& area )
911 {
912   // This is needed for the case where Dali window is partially obscured
913   RequestUpdate( false );
914 }
915
916 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
917 {
918   mResizedSignal.Emit( mAdaptor );
919 }
920
921 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
922 {
923   // Flush the event queue to give the update-render thread chance
924   // to start processing messages for new camera setup etc as soon as possible
925   ProcessCoreEvents();
926
927   mThreadController->ResizeSurface();
928 }
929
930 void Adaptor::NotifySceneCreated()
931 {
932   GetCore().SceneCreated();
933
934   // Flush the event queue to give the update-render thread chance
935   // to start processing messages for new camera setup etc as soon as possible
936   ProcessCoreEvents();
937
938   // Start thread controller after the scene has been created
939   mThreadController->Start();
940
941   // Process after surface is created (registering to remote surface provider if required)
942   SurfaceInitialized();
943
944   if( mState != PAUSED_WHILE_INITIALIZING )
945   {
946     mState = RUNNING;
947
948     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
949   }
950   else
951   {
952     mState = RUNNING;
953
954     Pause();
955
956     mState = PAUSED_WHILE_HIDDEN;
957
958     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
959   }
960 }
961
962 void Adaptor::NotifyLanguageChanged()
963 {
964   mLanguageChangedSignal.Emit( mAdaptor );
965 }
966
967 void Adaptor::RenderOnce()
968 {
969   RequestUpdateOnce();
970 }
971
972 const LogFactoryInterface& Adaptor::GetLogFactory()
973 {
974   return *mEnvironmentOptions;
975 }
976
977 void Adaptor::RegisterProcessor( Integration::Processor& processor )
978 {
979   GetCore().RegisterProcessor(processor);
980 }
981
982 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
983 {
984   GetCore().UnregisterProcessor(processor);
985 }
986
987 void Adaptor::RequestUpdateOnce()
988 {
989   if( mThreadController )
990   {
991     mThreadController->RequestUpdateOnce();
992   }
993 }
994
995 bool Adaptor::ProcessCoreEventsFromIdle()
996 {
997   ProcessCoreEvents();
998
999   // the idle handle automatically un-installs itself
1000   mNotificationOnIdleInstalled = false;
1001
1002   return false;
1003 }
1004
1005 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1006 {
1007   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1008
1009   for( auto window : mWindows )
1010   {
1011     if ( scene == window->GetScene() )
1012     {
1013       return window;
1014     }
1015   }
1016
1017   return nullptr;
1018 }
1019
1020 Dali::WindowContainer Adaptor::GetWindows() const
1021 {
1022   Dali::WindowContainer windows;
1023
1024   for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1025   {
1026     // Downcast to Dali::Window
1027     Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1028     if ( window )
1029     {
1030       windows.push_back( window );
1031     }
1032   }
1033
1034   return windows;
1035 }
1036
1037 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1038 : mResizedSignal(),
1039   mLanguageChangedSignal(),
1040   mWindowCreatedSignal(),
1041   mAdaptor( adaptor ),
1042   mState( READY ),
1043   mCore( nullptr ),
1044   mThreadController( nullptr ),
1045   mGraphics( nullptr ),
1046   mDisplayConnection( nullptr ),
1047   mWindows(),
1048   mPlatformAbstraction( nullptr ),
1049   mCallbackManager( nullptr ),
1050   mNotificationOnIdleInstalled( false ),
1051   mNotificationTrigger( nullptr ),
1052   mDaliFeedbackPlugin(),
1053   mFeedbackController( nullptr ),
1054   mTtsPlayers(),
1055   mObservers(),
1056   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1057   mPerformanceInterface( nullptr ),
1058   mKernelTracer(),
1059   mSystemTracer(),
1060   mTriggerEventFactory(),
1061   mObjectProfiler( nullptr ),
1062   mSocketFactory(),
1063   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1064   mUseRemoteSurface( false )
1065 {
1066   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1067   mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1068
1069   gThreadLocalAdaptor = this;
1070 }
1071
1072 void Adaptor::SetRootLayoutDirection( std::string locale )
1073 {
1074   Dali::Stage stage = Dali::Stage::GetCurrent();
1075
1076   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1077                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1078 }
1079
1080 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1081 {
1082   bool idleAdded( false );
1083
1084   // Only add an idle if the Adaptor is actually running
1085   if( RUNNING == mState || READY == mState || forceAdd )
1086   {
1087     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1088   }
1089
1090   return idleAdded;
1091 }
1092
1093 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1094 {
1095   mCallbackManager->RemoveIdleEntererCallback( callback );
1096 }
1097
1098 } // namespace Adaptor
1099
1100 } // namespace Internal
1101
1102 } // namespace Dali