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