Remove Unused Retention policy
[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 = mTriggerEventFactory.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 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
721 {
722   return mTriggerEventFactory;
723 }
724
725 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
726 {
727   return mSocketFactory;
728 }
729
730 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
731 {
732   if( !mWindows.empty() )
733   {
734     return mWindows.front()->GetSurface();
735   }
736
737   return nullptr;
738 }
739
740 TraceInterface& Adaptor::GetKernelTraceInterface()
741 {
742   return mKernelTracer;
743 }
744
745 TraceInterface& Adaptor::GetSystemTraceInterface()
746 {
747   return mSystemTracer;
748 }
749
750 PerformanceInterface* Adaptor::GetPerformanceInterface()
751 {
752   return mPerformanceInterface;
753 }
754
755 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
756 {
757   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
758   return *mPlatformAbstraction;
759 }
760
761 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
762 {
763   if( mTtsPlayers[mode] )
764   {
765     mTtsPlayers[mode].Reset();
766   }
767 }
768
769 Any Adaptor::GetNativeWindowHandle()
770 {
771   return mWindows.front()->GetNativeHandle();
772 }
773
774 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
775 {
776   Any nativeWindowHandle;
777
778   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
779
780   for( auto sceneHolder : mWindows )
781   {
782     if ( scene == sceneHolder->GetScene() )
783     {
784       nativeWindowHandle = sceneHolder->GetNativeHandle();
785       break;
786     }
787   }
788
789   return nativeWindowHandle;
790 }
791
792 Any Adaptor::GetGraphicsDisplay()
793 {
794   Any display;
795
796   if (mGraphics)
797   {
798     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
799
800     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
801     display = eglImpl.GetDisplay();
802   }
803
804   return display;
805 }
806
807 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
808 {
809   mUseRemoteSurface = useRemoteSurface;
810 }
811
812 void Adaptor::AddObserver( LifeCycleObserver& observer )
813 {
814   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
815
816   if ( match == mObservers.end() )
817   {
818     mObservers.push_back( &observer );
819   }
820 }
821
822 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
823 {
824   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
825
826   if ( match != mObservers.end() )
827   {
828     mObservers.erase( match );
829   }
830 }
831
832 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
833 {
834   if( mCore )
835   {
836     mCore->QueueEvent(event);
837   }
838 }
839
840 void Adaptor::ProcessCoreEvents()
841 {
842   if( mCore )
843   {
844     if( mPerformanceInterface )
845     {
846       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
847     }
848
849     mCore->ProcessEvents();
850
851     if( mPerformanceInterface )
852     {
853       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
854     }
855   }
856 }
857
858 void Adaptor::RequestUpdate( bool forceUpdate )
859 {
860   switch( mState )
861   {
862     case RUNNING:
863     {
864       mThreadController->RequestUpdate();
865       break;
866     }
867     case PAUSED:
868     case PAUSED_WHILE_HIDDEN:
869     {
870       if( forceUpdate )
871       {
872         // Update (and resource upload) without rendering
873         mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
874       }
875       break;
876     }
877     default:
878     {
879       // Do nothing
880       break;
881     }
882   }
883 }
884
885 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
886 {
887   // Only request a notification if the Adaptor is actually running
888   // and we haven't installed the idle notification
889   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
890   {
891     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
892   }
893 }
894
895 void Adaptor::OnWindowShown()
896 {
897   if( PAUSED_WHILE_HIDDEN == mState )
898   {
899     // Adaptor can now be resumed
900     mState = PAUSED;
901
902     Resume();
903
904     // Force a render task
905     RequestUpdateOnce();
906   }
907   else if( RUNNING == mState )
908   {
909     // Force a render task
910     RequestUpdateOnce();
911
912     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
913   }
914   else
915   {
916     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
917   }
918 }
919
920 void Adaptor::OnWindowHidden()
921 {
922   if( RUNNING == mState || READY == mState )
923   {
924     bool allWindowsHidden = true;
925
926     for( auto window : mWindows )
927     {
928       if ( window->IsVisible() )
929       {
930         allWindowsHidden = false;
931         break;
932       }
933     }
934
935     // Only pause the adaptor when all the windows are hidden
936     if( allWindowsHidden )
937     {
938       if( mState == RUNNING )
939       {
940         Pause();
941
942         // Adaptor cannot be resumed until any window is shown
943         mState = PAUSED_WHILE_HIDDEN;
944       }
945       else  // mState is READY
946       {
947         // Pause the adaptor after the state gets RUNNING
948         mState = PAUSED_WHILE_INITIALIZING;
949       }
950     }
951     else
952     {
953       DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
954     }
955   }
956   else
957   {
958     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
959   }
960 }
961
962 // Dali::Internal::Adaptor::Adaptor::OnDamaged
963 void Adaptor::OnDamaged( const DamageArea& area )
964 {
965   // This is needed for the case where Dali window is partially obscured
966   RequestUpdate( false );
967 }
968
969 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
970 {
971   mResizedSignal.Emit( mAdaptor );
972 }
973
974 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
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   mThreadController->ResizeSurface();
981 }
982
983 void Adaptor::NotifySceneCreated()
984 {
985   GetCore().SceneCreated();
986
987   // Flush the event queue to give the update-render thread chance
988   // to start processing messages for new camera setup etc as soon as possible
989   ProcessCoreEvents();
990
991   // Start thread controller after the scene has been created
992   mThreadController->Start();
993
994   // Process after surface is created (registering to remote surface provider if required)
995   SurfaceInitialized();
996
997   if( mState != PAUSED_WHILE_INITIALIZING )
998   {
999     mState = RUNNING;
1000
1001     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1002   }
1003   else
1004   {
1005     mState = RUNNING;
1006
1007     Pause();
1008
1009     mState = PAUSED_WHILE_HIDDEN;
1010
1011     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1012   }
1013 }
1014
1015 void Adaptor::NotifyLanguageChanged()
1016 {
1017   mLanguageChangedSignal.Emit( mAdaptor );
1018 }
1019
1020 void Adaptor::RenderOnce()
1021 {
1022   RequestUpdateOnce();
1023 }
1024
1025 const LogFactoryInterface& Adaptor::GetLogFactory()
1026 {
1027   return *mEnvironmentOptions;
1028 }
1029
1030 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1031 {
1032   GetCore().RegisterProcessor(processor);
1033 }
1034
1035 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1036 {
1037   GetCore().UnregisterProcessor(processor);
1038 }
1039
1040 bool Adaptor::IsMultipleWindowSupported() const
1041 {
1042   return mConfigurationManager->IsMultipleWindowSupported();
1043 }
1044
1045 void Adaptor::RequestUpdateOnce()
1046 {
1047   if( mThreadController )
1048   {
1049     mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1050   }
1051 }
1052
1053 bool Adaptor::ProcessCoreEventsFromIdle()
1054 {
1055   ProcessCoreEvents();
1056
1057   // the idle handle automatically un-installs itself
1058   mNotificationOnIdleInstalled = false;
1059
1060   return false;
1061 }
1062
1063 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1064 {
1065   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1066
1067   for( auto window : mWindows )
1068   {
1069     if ( scene == window->GetScene() )
1070     {
1071       return window;
1072     }
1073   }
1074
1075   return nullptr;
1076 }
1077
1078 Dali::WindowContainer Adaptor::GetWindows() const
1079 {
1080   Dali::WindowContainer windows;
1081
1082   for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1083   {
1084     // Downcast to Dali::Window
1085     Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1086     if ( window )
1087     {
1088       windows.push_back( window );
1089     }
1090   }
1091
1092   return windows;
1093 }
1094
1095 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1096 {
1097   Dali::SceneHolderList sceneHolderList;
1098
1099   for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1100   {
1101     sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1102   }
1103
1104   return sceneHolderList;
1105 }
1106
1107 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1108 : mResizedSignal(),
1109   mLanguageChangedSignal(),
1110   mWindowCreatedSignal(),
1111   mAdaptor( adaptor ),
1112   mState( READY ),
1113   mCore( nullptr ),
1114   mThreadController( nullptr ),
1115   mGraphics( nullptr ),
1116   mDisplayConnection( nullptr ),
1117   mWindows(),
1118   mConfigurationManager( nullptr ),
1119   mPlatformAbstraction( nullptr ),
1120   mCallbackManager( nullptr ),
1121   mNotificationOnIdleInstalled( false ),
1122   mNotificationTrigger( nullptr ),
1123   mDaliFeedbackPlugin(),
1124   mFeedbackController( nullptr ),
1125   mTtsPlayers(),
1126   mObservers(),
1127   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1128   mPerformanceInterface( nullptr ),
1129   mKernelTracer(),
1130   mSystemTracer(),
1131   mTriggerEventFactory(),
1132   mObjectProfiler( nullptr ),
1133   mSocketFactory(),
1134   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1135   mUseRemoteSurface( false )
1136 {
1137   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1138   mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1139
1140   gThreadLocalAdaptor = this;
1141 }
1142
1143 void Adaptor::SetRootLayoutDirection( std::string locale )
1144 {
1145   Dali::Stage stage = Dali::Stage::GetCurrent();
1146
1147   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1148                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1149 }
1150
1151 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1152 {
1153   bool idleAdded( false );
1154
1155   // Only add an idle if the Adaptor is actually running
1156   if( RUNNING == mState || READY == mState || forceAdd )
1157   {
1158     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1159   }
1160
1161   return idleAdded;
1162 }
1163
1164 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1165 {
1166   mCallbackManager->RemoveIdleEntererCallback( callback );
1167 }
1168
1169 } // namespace Adaptor
1170
1171 } // namespace Internal
1172
1173 } // namespace Dali