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