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