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