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