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