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