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