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