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