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