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