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