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