1b56e54a031c54f5cf6eea516905dec993dd93cc
[platform/core/uifw/dali-adaptor-legacy.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 = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
163   mGraphics->Initialize( mEnvironmentOptions );
164
165   GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
166   auto eglGraphics = static_cast<EglGraphics *>( graphics );
167
168   // This will only be created once
169   eglGraphics->Create();
170
171   GlImplementation& mGLES = eglGraphics->GetGlesInterface();
172   EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
173   EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
174
175   mCore = Integration::Core::New( *this,
176                                   *mPlatformAbstraction,
177                                   mGLES,
178                                   eglSyncImpl,
179                                   eglContextHelperImpl,
180                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
181                                   mGraphics->GetDepthBufferRequired(),
182                                   mGraphics->GetStencilBufferRequired() );
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::ProcessIdle()
609 {
610   bool idleProcessed = mCallbackManager->ProcessIdle();
611   mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
612 }
613
614 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
615 {
616   mThreadController->SetPreRenderCallback( callback );
617 }
618
619 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
620 {
621   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
622   windowImpl.SetAdaptor( Get() );
623
624   // Add the new Window to the container - the order is not important
625   mWindows.push_back( &windowImpl );
626
627   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
628
629   mThreadController->AddSurface( surface );
630
631   mWindowCreatedSignal.Emit( childWindow );
632
633   return true;
634 }
635
636 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
637 {
638   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
639   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
640   {
641     if( *iter == &windowImpl )
642     {
643       mWindows.erase( iter );
644       return true;
645     }
646   }
647
648   return false;
649 }
650
651 bool Adaptor::RemoveWindow( std::string childWindowName )
652 {
653   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
654   {
655     if( ( *iter )->GetName() == childWindowName )
656     {
657       mWindows.erase( iter );
658       return true;
659     }
660   }
661
662   return false;
663 }
664
665 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
666 {
667   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
668   {
669     if( ( *iter )->GetId() == childWindow->GetId() )
670     {
671       mWindows.erase( iter );
672       return true;
673     }
674   }
675
676   return false;
677 }
678
679 Dali::Adaptor& Adaptor::Get()
680 {
681   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
682   return gThreadLocalAdaptor->mAdaptor;
683 }
684
685 bool Adaptor::IsAvailable()
686 {
687   return gThreadLocalAdaptor != NULL;
688 }
689
690 void Adaptor::SceneCreated()
691 {
692   mCore->SceneCreated();
693 }
694
695 Dali::Integration::Core& Adaptor::GetCore()
696 {
697   return *mCore;
698 }
699
700 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
701 {
702   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
703 }
704
705 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
706 {
707   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
708   return *mDisplayConnection;
709 }
710
711 GraphicsInterface& Adaptor::GetGraphicsInterface()
712 {
713   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
714   return *( mGraphics.get() );
715 }
716
717 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
718 {
719   return *mPlatformAbstraction;
720 }
721
722 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
723 {
724   return *mNotificationTrigger;
725 }
726
727 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
728 {
729   return mSocketFactory;
730 }
731
732 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
733 {
734   if( !mWindows.empty() )
735   {
736     return mWindows.front()->GetSurface();
737   }
738
739   return nullptr;
740 }
741
742 TraceInterface& Adaptor::GetKernelTraceInterface()
743 {
744   return mKernelTracer;
745 }
746
747 TraceInterface& Adaptor::GetSystemTraceInterface()
748 {
749   return mSystemTracer;
750 }
751
752 PerformanceInterface* Adaptor::GetPerformanceInterface()
753 {
754   return mPerformanceInterface;
755 }
756
757 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
758 {
759   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
760   return *mPlatformAbstraction;
761 }
762
763 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
764 {
765   windows = mWindows;
766 }
767
768 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
769 {
770   if( mTtsPlayers[mode] )
771   {
772     mTtsPlayers[mode].Reset();
773   }
774 }
775
776 Any Adaptor::GetNativeWindowHandle()
777 {
778   return mWindows.front()->GetNativeHandle();
779 }
780
781 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
782 {
783   Any nativeWindowHandle;
784
785   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
786
787   for( auto sceneHolder : mWindows )
788   {
789     if ( scene == sceneHolder->GetScene() )
790     {
791       nativeWindowHandle = sceneHolder->GetNativeHandle();
792       break;
793     }
794   }
795
796   return nativeWindowHandle;
797 }
798
799 Any Adaptor::GetGraphicsDisplay()
800 {
801   Any display;
802
803   if (mGraphics)
804   {
805     GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
806     auto eglGraphics = static_cast<EglGraphics *>( graphics );
807
808     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
809     display = eglImpl.GetDisplay();
810   }
811
812   return display;
813 }
814
815 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
816 {
817   mUseRemoteSurface = useRemoteSurface;
818 }
819
820 void Adaptor::AddObserver( LifeCycleObserver& observer )
821 {
822   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
823
824   if ( match == mObservers.end() )
825   {
826     mObservers.push_back( &observer );
827   }
828 }
829
830 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
831 {
832   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
833
834   if ( match != mObservers.end() )
835   {
836     mObservers.erase( match );
837   }
838 }
839
840 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
841 {
842   if( mCore )
843   {
844     mCore->QueueEvent(event);
845   }
846 }
847
848 void Adaptor::ProcessCoreEvents()
849 {
850   if( mCore )
851   {
852     if( mPerformanceInterface )
853     {
854       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
855     }
856
857     mCore->ProcessEvents();
858
859     if( mPerformanceInterface )
860     {
861       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
862     }
863   }
864 }
865
866 void Adaptor::RequestUpdate( bool forceUpdate )
867 {
868   switch( mState )
869   {
870     case RUNNING:
871     {
872       mThreadController->RequestUpdate();
873       break;
874     }
875     case PAUSED:
876     case PAUSED_WHILE_HIDDEN:
877     {
878       if( forceUpdate )
879       {
880         // Update (and resource upload) without rendering
881         mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
882       }
883       break;
884     }
885     default:
886     {
887       // Do nothing
888       break;
889     }
890   }
891 }
892
893 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
894 {
895   // Only request a notification if the Adaptor is actually running
896   // and we haven't installed the idle notification
897   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
898   {
899     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
900   }
901 }
902
903 void Adaptor::OnWindowShown()
904 {
905   if( PAUSED_WHILE_HIDDEN == mState )
906   {
907     // Adaptor can now be resumed
908     mState = PAUSED;
909
910     Resume();
911
912     // Force a render task
913     RequestUpdateOnce();
914   }
915   else if( RUNNING == mState )
916   {
917     // Force a render task
918     RequestUpdateOnce();
919
920     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
921   }
922   else
923   {
924     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
925   }
926 }
927
928 void Adaptor::OnWindowHidden()
929 {
930   if( RUNNING == mState || READY == mState )
931   {
932     bool allWindowsHidden = true;
933
934     for( auto window : mWindows )
935     {
936       if ( window->IsVisible() )
937       {
938         allWindowsHidden = false;
939         break;
940       }
941     }
942
943     // Only pause the adaptor when all the windows are hidden
944     if( allWindowsHidden )
945     {
946       if( mState == RUNNING )
947       {
948         Pause();
949
950         // Adaptor cannot be resumed until any window is shown
951         mState = PAUSED_WHILE_HIDDEN;
952       }
953       else  // mState is READY
954       {
955         // Pause the adaptor after the state gets RUNNING
956         mState = PAUSED_WHILE_INITIALIZING;
957       }
958     }
959     else
960     {
961       DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
962     }
963   }
964   else
965   {
966     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
967   }
968 }
969
970 // Dali::Internal::Adaptor::Adaptor::OnDamaged
971 void Adaptor::OnDamaged( const DamageArea& area )
972 {
973   // This is needed for the case where Dali window is partially obscured
974   RequestUpdate( false );
975 }
976
977 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
978 {
979   mResizedSignal.Emit( mAdaptor );
980 }
981
982 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
983 {
984   // Nofify surface resizing before flushing event queue
985   mThreadController->ResizeSurface();
986
987   // Flush the event queue to give the update-render thread chance
988   // to start processing messages for new camera setup etc as soon as possible
989   ProcessCoreEvents();
990 }
991
992 void Adaptor::NotifySceneCreated()
993 {
994   GetCore().SceneCreated();
995
996   // Flush the event queue to give the update-render thread chance
997   // to start processing messages for new camera setup etc as soon as possible
998   ProcessCoreEvents();
999
1000   // Start thread controller after the scene has been created
1001   mThreadController->Start();
1002
1003   // Process after surface is created (registering to remote surface provider if required)
1004   SurfaceInitialized();
1005
1006   if( mState != PAUSED_WHILE_INITIALIZING )
1007   {
1008     mState = RUNNING;
1009
1010     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1011   }
1012   else
1013   {
1014     mState = RUNNING;
1015
1016     Pause();
1017
1018     mState = PAUSED_WHILE_HIDDEN;
1019
1020     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1021   }
1022 }
1023
1024 void Adaptor::NotifyLanguageChanged()
1025 {
1026   mLanguageChangedSignal.Emit( mAdaptor );
1027 }
1028
1029 void Adaptor::RenderOnce()
1030 {
1031   RequestUpdateOnce();
1032 }
1033
1034 const LogFactoryInterface& Adaptor::GetLogFactory()
1035 {
1036   return *mEnvironmentOptions;
1037 }
1038
1039 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1040 {
1041   GetCore().RegisterProcessor(processor);
1042 }
1043
1044 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1045 {
1046   GetCore().UnregisterProcessor(processor);
1047 }
1048
1049 bool Adaptor::IsMultipleWindowSupported() const
1050 {
1051   return mConfigurationManager->IsMultipleWindowSupported();
1052 }
1053
1054 void Adaptor::RequestUpdateOnce()
1055 {
1056   if( mThreadController )
1057   {
1058     mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1059   }
1060 }
1061
1062 bool Adaptor::ProcessCoreEventsFromIdle()
1063 {
1064   ProcessCoreEvents();
1065
1066   // the idle handle automatically un-installs itself
1067   mNotificationOnIdleInstalled = false;
1068
1069   return false;
1070 }
1071
1072 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1073 {
1074   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1075
1076   for( auto window : mWindows )
1077   {
1078     if ( scene == window->GetScene() )
1079     {
1080       return window;
1081     }
1082   }
1083
1084   return nullptr;
1085 }
1086
1087 Dali::WindowContainer Adaptor::GetWindows() const
1088 {
1089   Dali::WindowContainer windows;
1090
1091   for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1092   {
1093     // Downcast to Dali::Window
1094     Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1095     if ( window )
1096     {
1097       windows.push_back( window );
1098     }
1099   }
1100
1101   return windows;
1102 }
1103
1104 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1105 {
1106   Dali::SceneHolderList sceneHolderList;
1107
1108   for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1109   {
1110     sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1111   }
1112
1113   return sceneHolderList;
1114 }
1115
1116 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1117 : mResizedSignal(),
1118   mLanguageChangedSignal(),
1119   mWindowCreatedSignal(),
1120   mAdaptor( adaptor ),
1121   mState( READY ),
1122   mCore( nullptr ),
1123   mThreadController( nullptr ),
1124   mGraphics( nullptr ),
1125   mDisplayConnection( nullptr ),
1126   mWindows(),
1127   mConfigurationManager( nullptr ),
1128   mPlatformAbstraction( nullptr ),
1129   mCallbackManager( nullptr ),
1130   mNotificationOnIdleInstalled( false ),
1131   mNotificationTrigger( nullptr ),
1132   mDaliFeedbackPlugin(),
1133   mFeedbackController( nullptr ),
1134   mTtsPlayers(),
1135   mObservers(),
1136   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1137   mPerformanceInterface( nullptr ),
1138   mKernelTracer(),
1139   mSystemTracer(),
1140   mObjectProfiler( nullptr ),
1141   mSocketFactory(),
1142   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1143   mUseRemoteSurface( false )
1144 {
1145   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1146   mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1147
1148   gThreadLocalAdaptor = this;
1149 }
1150
1151 void Adaptor::SetRootLayoutDirection( std::string locale )
1152 {
1153   Dali::Stage stage = Dali::Stage::GetCurrent();
1154
1155   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1156                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1157 }
1158
1159 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1160 {
1161   bool idleAdded( false );
1162
1163   // Only add an idle if the Adaptor is actually running
1164   if( RUNNING == mState || READY == mState || forceAdd )
1165   {
1166     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1167   }
1168
1169   return idleAdded;
1170 }
1171
1172 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1173 {
1174   mCallbackManager->RemoveIdleEntererCallback( callback );
1175 }
1176
1177 } // namespace Adaptor
1178
1179 } // namespace Internal
1180
1181 } // namespace Dali