[Tizen] remove setenv() that can cause Seg fault
[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/actors/layer.h>
26 #include <dali/public-api/object/any.h>
27 #include <dali/public-api/object/object-registry.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                                   mGraphics->GetPartialUpdateRequired() );
186
187   defaultWindow->SetAdaptor( Get() );
188
189   Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
190
191   mWindowCreatedSignal.Emit( defaultSceneHolder );
192
193   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
194   if( 0u < timeInterval )
195   {
196     mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
197   }
198
199   mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
200
201   mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
202
203   mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
204
205   // Should be called after Core creation
206   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
207   {
208     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
209   }
210   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
211   {
212     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
213   }
214   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
215   {
216     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
217   }
218   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
219   {
220     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
221   }
222   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
223   {
224     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
225   }
226   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
227   {
228     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
229   }
230   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
231   {
232     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
233   }
234   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
235   {
236     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
237   }
238   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
239   {
240     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
241   }
242   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
243   {
244     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
245   }
246   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
247   {
248     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
249   }
250   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
251   {
252     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
253   }
254   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
255   {
256     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
257   }
258   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
259   {
260     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
261   }
262   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
263   {
264     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
265   }
266   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
267   {
268     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
269   }
270   if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
271   {
272     Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
273   }
274   if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
275   {
276     Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
277   }
278   if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
279   {
280     Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
281   }
282   if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
283   {
284     Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
285   }
286   if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
287   {
288     Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
289   }
290   if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
291   {
292     Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
293   }
294   if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
295   {
296     Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
297   }
298   if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
299   {
300     Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
301   }
302
303   std::string systemCachePath = GetSystemCachePath();
304   if( ! systemCachePath.empty() )
305   {
306     const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
307     if ( 0 != dir_err && errno != EEXIST )
308     {
309       DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
310       exit( 1 );
311     }
312   }
313
314   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
315 }
316
317 Adaptor::~Adaptor()
318 {
319   // Ensure stop status
320   Stop();
321
322   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
323   gThreadLocalAdaptor = NULL;
324
325   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
326   {
327     (*iter)->OnDestroy();
328   }
329
330   // Clear out all the handles to Windows
331   mWindows.clear();
332
333   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
334   delete mObjectProfiler;
335
336   delete mCore;
337
338   delete mDisplayConnection;
339   delete mPlatformAbstraction;
340   delete mCallbackManager;
341   delete mPerformanceInterface;
342
343   mGraphics->Destroy();
344
345   // uninstall it on this thread (main actor thread)
346   Dali::Integration::Log::UninstallLogFunction();
347
348   // Delete environment options if we own it
349   if( mEnvironmentOptionsOwned )
350   {
351     delete mEnvironmentOptions;
352   }
353 }
354
355 void Adaptor::Start()
356 {
357   // It doesn't support restart after stop at this moment to support restarting, need more testing
358   if( READY != mState )
359   {
360     return;
361   }
362
363   mCore->Initialize();
364
365   SetupSystemInformation();
366
367   // Start the callback manager
368   mCallbackManager->Start();
369
370   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
371
372   unsigned int dpiHor, dpiVer;
373   dpiHor = dpiVer = 0;
374
375   defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
376
377   // set the DPI value for font rendering
378   FontClient fontClient = FontClient::Get();
379   fontClient.SetDpi( dpiHor, dpiVer );
380
381   // Initialize the thread controller
382   mThreadController->Initialize();
383
384   // Set max texture size
385   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
386   {
387     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
388   }
389   else
390   {
391     unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
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   if( mThreadController )
1034   {
1035     UpdateMode updateMode;
1036     if( mThreadMode == ThreadMode::NORMAL )
1037     {
1038       updateMode = UpdateMode::NORMAL;
1039     }
1040     else
1041     {
1042       updateMode = UpdateMode::FORCE_RENDER;
1043
1044       ProcessCoreEvents();
1045     }
1046     mThreadController->RequestUpdateOnce( updateMode );
1047   }
1048 }
1049
1050 const LogFactoryInterface& Adaptor::GetLogFactory()
1051 {
1052   return *mEnvironmentOptions;
1053 }
1054
1055 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1056 {
1057   GetCore().RegisterProcessor(processor);
1058 }
1059
1060 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1061 {
1062   GetCore().UnregisterProcessor(processor);
1063 }
1064
1065 bool Adaptor::IsMultipleWindowSupported() const
1066 {
1067   return mConfigurationManager->IsMultipleWindowSupported();
1068 }
1069
1070 void Adaptor::RequestUpdateOnce()
1071 {
1072   if( mThreadController )
1073   {
1074     mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1075   }
1076 }
1077
1078 bool Adaptor::ProcessCoreEventsFromIdle()
1079 {
1080   ProcessCoreEvents();
1081
1082   // the idle handle automatically un-installs itself
1083   mNotificationOnIdleInstalled = false;
1084
1085   return false;
1086 }
1087
1088 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1089 {
1090   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1091
1092   for( auto window : mWindows )
1093   {
1094     if ( scene == window->GetScene() )
1095     {
1096       return window;
1097     }
1098   }
1099
1100   return nullptr;
1101 }
1102
1103 Dali::WindowContainer Adaptor::GetWindows() const
1104 {
1105   Dali::WindowContainer windows;
1106
1107   for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1108   {
1109     // Downcast to Dali::Window
1110     Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1111     if ( window )
1112     {
1113       windows.push_back( window );
1114     }
1115   }
1116
1117   return windows;
1118 }
1119
1120 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1121 {
1122   Dali::SceneHolderList sceneHolderList;
1123
1124   for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1125   {
1126     sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1127   }
1128
1129   return sceneHolderList;
1130 }
1131
1132 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1133 {
1134   Dali::ObjectRegistry registry;
1135   if( mCore )
1136   {
1137     registry = mCore->GetObjectRegistry();
1138   }
1139   return registry;
1140 }
1141
1142 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1143 : mResizedSignal(),
1144   mLanguageChangedSignal(),
1145   mWindowCreatedSignal(),
1146   mAdaptor( adaptor ),
1147   mState( READY ),
1148   mCore( nullptr ),
1149   mThreadController( nullptr ),
1150   mGraphics( nullptr ),
1151   mDisplayConnection( nullptr ),
1152   mWindows(),
1153   mConfigurationManager( nullptr ),
1154   mPlatformAbstraction( nullptr ),
1155   mCallbackManager( nullptr ),
1156   mNotificationOnIdleInstalled( false ),
1157   mNotificationTrigger( nullptr ),
1158   mDaliFeedbackPlugin(),
1159   mFeedbackController( nullptr ),
1160   mTtsPlayers(),
1161   mObservers(),
1162   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1163   mPerformanceInterface( nullptr ),
1164   mKernelTracer(),
1165   mSystemTracer(),
1166   mObjectProfiler( nullptr ),
1167   mSocketFactory(),
1168   mThreadMode( ThreadMode::NORMAL ),
1169   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1170   mUseRemoteSurface( false )
1171 {
1172   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1173   mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1174
1175   gThreadLocalAdaptor = this;
1176 }
1177
1178 void Adaptor::SetRootLayoutDirection( std::string locale )
1179 {
1180   for ( auto& window : mWindows )
1181   {
1182     Dali::Actor root = window->GetRootLayer();
1183     root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1184                       static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1185   }
1186 }
1187
1188 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1189 {
1190   bool idleAdded( false );
1191
1192   // Only add an idle if the Adaptor is actually running
1193   if( RUNNING == mState || READY == mState || forceAdd )
1194   {
1195     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1196   }
1197
1198   return idleAdded;
1199 }
1200
1201 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1202 {
1203   mCallbackManager->RemoveIdleEntererCallback( callback );
1204 }
1205
1206 } // namespace Adaptor
1207
1208 } // namespace Internal
1209
1210 } // namespace Dali