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