73c18d8193a754f0ff5e69e9614b762996641a8a
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2018 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
86 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
87 {
88   Dali::Adaptor* adaptor = new Dali::Adaptor;
89   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
90   adaptor->mImpl = impl;
91
92   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
93   auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
94
95   impl->Initialize( graphicsFactory, configuration );
96   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
97
98   return adaptor;
99 }
100
101 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
102 {
103   Any winId = window.GetNativeHandle();
104
105   Window& windowImpl = Dali::GetImplementation( window );
106   Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
107   windowImpl.SetAdaptor( *adaptor );
108   return adaptor;
109 }
110
111 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
112 {
113   Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
114   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions ); // Impl adaptor
115   adaptor->mImpl = impl;
116
117   impl->Initialize( graphicsFactory, configuration );
118
119   return adaptor;
120 } // Called second
121
122 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
123 {
124   Any winId = window.GetNativeHandle();
125
126   Window& windowImpl = Dali::GetImplementation( window );
127   Dali::Adaptor* adaptor = New( graphicsFactory, winId, windowImpl.GetSurface(), configuration, environmentOptions );
128   windowImpl.SetAdaptor( *adaptor );
129   return adaptor;
130 } // Called first
131
132 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
133 {
134   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
135   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
136   mEnvironmentOptions->SetLogFunction( logFunction );
137   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
138
139   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
140
141   std::string path;
142   GetDataStoragePath( path );
143   mPlatformAbstraction->SetDataStoragePath( path );
144
145   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
146   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
147   {
148     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
149   }
150
151   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
152
153   if( mEnvironmentOptions->PerformanceServerRequired() )
154   {
155     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
156   }
157
158   mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
159   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
160
161   mCallbackManager = CallbackManager::New();
162
163   WindowPane defaultWindow = mWindowFrame.front();
164
165   DALI_ASSERT_DEBUG( defaultWindow.surface && "Surface not initialized" );
166
167   PositionSize size = defaultWindow.surface->GetPositionSize();
168
169   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
170
171   mGraphics = &( graphicsFactory.Create() );
172   mGraphics->Initialize( mEnvironmentOptions );
173
174   auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
175
176   GlImplementation& mGLES = eglGraphics->GetGlesInterface();
177   EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
178
179   mCore = Integration::Core::New( *this,
180                                   *mPlatformAbstraction,
181                                   mGLES,
182                                   eglSyncImpl,
183                                   *mGestureManager,
184                                   dataRetentionPolicy ,
185                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
186                                   mGraphics->GetDepthBufferRequired(),
187                                   mGraphics->GetStencilBufferRequired() );
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.surface->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   SetupSystemInformation();
276 }
277
278 Adaptor::~Adaptor()
279 {
280   // Ensure stop status
281   Stop();
282
283   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
284   gThreadLocalAdaptor = NULL;
285
286   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
287   {
288     (*iter)->OnDestroy();
289   }
290
291   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
292   delete mVSyncMonitor;
293   delete mEventHandler;
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   // Start the callback manager
325   mCallbackManager->Start();
326
327   WindowPane defaultWindow = mWindowFrame.front();
328
329   // Create event handler
330   mEventHandler = new EventHandler( defaultWindow.surface, *this, *mGestureManager, *this, mDragAndDropDetector );
331
332   if( mDeferredRotationObserver != NULL )
333   {
334     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
335     mDeferredRotationObserver = NULL;
336   }
337
338   unsigned int dpiHor, dpiVer;
339   dpiHor = dpiVer = 0;
340
341   defaultWindow.surface->GetDpi( dpiHor, dpiVer );
342
343   // tell core about the DPI value
344   mCore->SetDpi(dpiHor, dpiVer);
345
346   // set the DPI value for font rendering
347   FontClient fontClient = FontClient::Get();
348   fontClient.SetDpi( dpiHor, dpiVer );
349
350   // Tell the core the size of the surface just before we start the render-thread
351   PositionSize size = defaultWindow.surface->GetPositionSize();
352
353   mCore->SurfaceResized( size.width, size.height );
354
355   // Initialize the thread controller
356   mThreadController->Initialize();
357
358   ProcessCoreEvents(); // Ensure any startup messages are processed.
359
360   // Initialize the image loader plugin
361   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
362
363   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
364   {
365     (*iter)->OnStart();
366   }
367 }
368
369 // Dali::Internal::Adaptor::Adaptor::Pause
370 void Adaptor::Pause()
371 {
372   // Only pause the adaptor if we're actually running.
373   if( RUNNING == mState )
374   {
375     // Inform observers that we are about to be paused.
376     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
377     {
378       (*iter)->OnPause();
379     }
380
381     // Reset the event handler when adaptor paused
382     if( mEventHandler )
383     {
384       mEventHandler->Pause();
385     }
386
387     mThreadController->Pause();
388     mState = PAUSED;
389
390     // Ensure any messages queued during pause callbacks are processed by doing another update.
391     RequestUpdateOnce();
392   }
393 }
394
395 // Dali::Internal::Adaptor::Adaptor::Resume
396 void Adaptor::Resume()
397 {
398   // Only resume the adaptor if we are in the suspended state.
399   if( PAUSED == mState )
400   {
401     mState = RUNNING;
402
403     // Reset the event handler when adaptor resumed
404     if( mEventHandler )
405     {
406       mEventHandler->Resume();
407     }
408
409     // Inform observers that we have resumed.
410     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
411     {
412       (*iter)->OnResume();
413     }
414
415     // Trigger processing of events queued up while paused
416     mCore->ProcessEvents();
417
418     // Do at end to ensure our first update/render after resumption includes the processed messages as well
419     mThreadController->Resume();
420   }
421 }
422
423 void Adaptor::Stop()
424 {
425   if( RUNNING == mState ||
426       PAUSED  == mState ||
427       PAUSED_WHILE_HIDDEN == mState )
428   {
429     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
430     {
431       (*iter)->OnStop();
432     }
433
434     mThreadController->Stop();
435
436     // Clear out all the handles to Windows
437     mWindowFrame.clear();
438
439     // Delete the TTS player
440     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
441     {
442       if(mTtsPlayers[i])
443       {
444         mTtsPlayers[i].Reset();
445       }
446     }
447
448     // Destroy the image loader plugin
449     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
450
451     delete mEventHandler;
452     mEventHandler = NULL;
453
454     delete mNotificationTrigger;
455     mNotificationTrigger = NULL;
456
457     mCallbackManager->Stop();
458
459     mState = STOPPED;
460   }
461 }
462
463 void Adaptor::ContextLost()
464 {
465   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
466 }
467
468 void Adaptor::ContextRegained()
469 {
470   // Inform core, so that texture resources can be reloaded
471   mCore->RecoverFromContextLoss();
472
473   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
474 }
475
476 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
477 {
478   mEventHandler->FeedTouchPoint( point, timeStamp );
479 }
480
481 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
482 {
483   mEventHandler->FeedWheelEvent( wheelEvent );
484 }
485
486 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
487 {
488   mEventHandler->FeedKeyEvent( keyEvent );
489 }
490
491 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& newSurface )
492 {
493   PositionSize positionSize = newSurface.GetPositionSize();
494
495   // Let the core know the surface size has changed
496   mCore->SurfaceResized( positionSize.width, positionSize.height );
497
498   mResizedSignal.Emit( mAdaptor );
499
500   WindowPane newDefaultWindow;
501   newDefaultWindow.nativeWindow = nativeWindow;
502   newDefaultWindow.surface = &newSurface;
503
504   WindowPane oldDefaultWindow = mWindowFrame.front();
505
506   // Update WindowFrame
507   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
508   iter = mWindowFrame.insert( iter, newDefaultWindow );
509
510   // Flush the event queue to give the update-render thread chance
511   // to start processing messages for new camera setup etc as soon as possible
512   ProcessCoreEvents();
513
514   // This method blocks until the render thread has completed the replace.
515   mThreadController->ReplaceSurface( newDefaultWindow.surface );
516
517   // Must delete the old Window only after the render thread has completed the replace
518   oldDefaultWindow.surface->DestroySurface();
519   oldDefaultWindow.surface = nullptr;
520 }
521
522 RenderSurface& Adaptor::GetSurface() const
523 {
524   WindowPane defaultWindow = mWindowFrame.front();
525   return *(defaultWindow.surface);
526 }
527
528 void Adaptor::ReleaseSurfaceLock()
529 {
530   WindowPane defaultWindow = mWindowFrame.front();
531   defaultWindow.surface->ReleaseLock();
532 }
533
534 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
535 {
536   if(!mTtsPlayers[mode])
537   {
538     // Create the TTS player when it needed, because it can reduce launching time.
539     mTtsPlayers[mode] = TtsPlayer::New(mode);
540   }
541
542   return mTtsPlayers[mode];
543 }
544
545 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
546 {
547   bool idleAdded(false);
548
549   // Only add an idle if the Adaptor is actually running
550   if( RUNNING == mState || READY == mState || forceAdd )
551   {
552     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
553   }
554
555   return idleAdded;
556 }
557
558 void Adaptor::RemoveIdle( CallbackBase* callback )
559 {
560   mCallbackManager->RemoveIdleCallback( callback );
561 }
562
563 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
564 {
565   mThreadController->SetPreRenderCallback( callback );
566 }
567
568 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
569 {
570   // This is any Window that is not the main (default) one
571   WindowPane additionalWindow;
572   additionalWindow.instance = childWindow;
573   additionalWindow.window_name = childWindowName;
574   additionalWindow.class_name = childWindowClassName;
575   additionalWindow.window_mode = childWindowMode;
576
577   // Add the new Window to the Frame - the order is not important
578   mWindowFrame.push_back( additionalWindow );
579
580   Window& windowImpl = Dali::GetImplementation( *childWindow );
581   windowImpl.SetAdaptor( Get() );
582
583   return true;
584 }
585
586 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
587 {
588   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
589   {
590     if( iter->instance == childWindow )
591     {
592       mWindowFrame.erase( iter );
593       return true;
594     }
595   }
596
597   return false;
598 }
599
600 bool Adaptor::RemoveWindow( std::string childWindowName )
601 {
602   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
603   {
604     if( iter->window_name == childWindowName )
605     {
606       mWindowFrame.erase( iter );
607       return true;
608     }
609   }
610
611   return false;
612 }
613
614 Dali::Adaptor& Adaptor::Get()
615 {
616   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
617   return gThreadLocalAdaptor->mAdaptor;
618 }
619
620 bool Adaptor::IsAvailable()
621 {
622   return gThreadLocalAdaptor != NULL;
623 }
624
625 void Adaptor::SceneCreated()
626 {
627   mCore->SceneCreated();
628 }
629
630 Dali::Integration::Core& Adaptor::GetCore()
631 {
632   return *mCore;
633 }
634
635 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
636 {
637   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
638 }
639
640 void Adaptor::SetUseHardwareVSync( bool useHardware )
641 {
642   mVSyncMonitor->SetUseHardwareVSync( useHardware );
643 }
644
645 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
646 {
647   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
648   return *mDisplayConnection;
649 }
650
651 GraphicsInterface& Adaptor::GetGraphicsInterface()
652 {
653   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
654   return *mGraphics;
655 }
656
657 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
658 {
659   return *mPlatformAbstraction;
660 }
661
662 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
663 {
664   return *mNotificationTrigger;
665 }
666
667 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
668 {
669   return mTriggerEventFactory;
670 }
671
672 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
673 {
674   return mSocketFactory;
675 }
676
677 RenderSurface* Adaptor::GetRenderSurfaceInterface()
678 {
679   if( !mWindowFrame.empty())
680   {
681     WindowPane defaultWindow = mWindowFrame.front();
682     return defaultWindow.surface;
683   }
684   else
685   {
686     return nullptr;
687   }
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   if ( mEventHandler )
721   {
722     mEventHandler->SetDragAndDropDetector( detector );
723   }
724 }
725
726 void Adaptor::SetRotationObserver( RotationObserver* observer )
727 {
728   if( mEventHandler )
729   {
730     mEventHandler->SetRotationObserver( observer );
731   }
732   else if( mState == READY )
733   {
734     // Set once event handler exists
735     mDeferredRotationObserver = observer;
736   }
737 }
738
739 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
740 {
741   if(mTtsPlayers[mode])
742   {
743     mTtsPlayers[mode].Reset();
744   }
745 }
746
747 void Adaptor::SetMinimumPinchDistance(float distance)
748 {
749   if( mGestureManager )
750   {
751     mGestureManager->SetMinimumPinchDistance(distance);
752   }
753 }
754
755 Any Adaptor::GetNativeWindowHandle()
756 {
757   WindowPane defaultWindow = mWindowFrame.front();
758   return defaultWindow.nativeWindow;
759 }
760
761 Any Adaptor::GetGraphicsDisplay()
762 {
763   Any display;
764
765   if (mGraphics)
766   {
767     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
768
769     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
770     display = eglImpl.GetDisplay();
771   }
772
773   return display;
774 }
775
776 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
777 {
778   mUseRemoteSurface = useRemoteSurface;
779 }
780
781 void Adaptor::AddObserver( LifeCycleObserver& observer )
782 {
783   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
784
785   if ( match == mObservers.end() )
786   {
787     mObservers.push_back( &observer );
788   }
789 }
790
791 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
792 {
793   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
794
795   if ( match != mObservers.end() )
796   {
797     mObservers.erase( match );
798   }
799 }
800
801 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
802 {
803   if( mCore )
804   {
805     mCore->QueueEvent(event);
806   }
807 }
808
809 void Adaptor::ProcessCoreEvents()
810 {
811   if( mCore )
812   {
813     if( mPerformanceInterface )
814     {
815       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
816     }
817
818     mCore->ProcessEvents();
819
820     if( mPerformanceInterface )
821     {
822       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
823     }
824   }
825 }
826
827 void Adaptor::RequestUpdate( bool forceUpdate )
828 {
829   switch( mState )
830   {
831     case RUNNING:
832     {
833       mThreadController->RequestUpdate();
834       break;
835     }
836     case PAUSED:
837     case PAUSED_WHILE_HIDDEN:
838     {
839       // When Dali applications are partially visible behind the lock-screen,
840       // the indicator must be updated (therefore allow updates in the PAUSED state)
841       if( forceUpdate )
842       {
843         mThreadController->RequestUpdateOnce();
844       }
845       break;
846     }
847     default:
848     {
849       // Do nothing
850       break;
851     }
852   }
853 }
854
855 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
856 {
857   // Only request a notification if the Adaptor is actually running
858   // and we haven't installed the idle notification
859   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
860   {
861     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
862   }
863 }
864
865 void Adaptor::OnWindowShown()
866 {
867   if ( PAUSED_WHILE_HIDDEN == mState )
868   {
869     // Adaptor can now be resumed
870     mState = PAUSED;
871
872     Resume();
873
874     // Force a render task
875     RequestUpdateOnce();
876   }
877 }
878
879 void Adaptor::OnWindowHidden()
880 {
881   if ( RUNNING == mState )
882   {
883     Pause();
884
885     // Adaptor cannot be resumed until the window is shown
886     mState = PAUSED_WHILE_HIDDEN;
887   }
888 }
889
890 // Dali::Internal::Adaptor::Adaptor::OnDamaged
891 void Adaptor::OnDamaged( const DamageArea& area )
892 {
893   // This is needed for the case where Dali window is partially obscured
894   RequestUpdate( false );
895 }
896
897 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
898 {
899   // Let the core know the surface size has changed
900   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
901
902   mResizedSignal.Emit( mAdaptor );
903 }
904
905 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
906 {
907   // Flush the event queue to give the update-render thread chance
908   // to start processing messages for new camera setup etc as soon as possible
909   ProcessCoreEvents();
910
911   mThreadController->ResizeSurface();
912 }
913
914 void Adaptor::NotifySceneCreated()
915 {
916   GetCore().SceneCreated();
917
918   // Start thread controller after the scene has been created
919   mThreadController->Start();
920
921   // Process after surface is created (registering to remote surface provider if required)
922   SurfaceInitialized();
923
924   mState = RUNNING;
925 }
926
927 void Adaptor::NotifyLanguageChanged()
928 {
929   mLanguageChangedSignal.Emit( mAdaptor );
930 }
931
932 void Adaptor::RenderOnce()
933 {
934   RequestUpdateOnce();
935 }
936
937 const LogFactoryInterface& Adaptor::GetLogFactory()
938 {
939   return *mEnvironmentOptions;
940 }
941
942 void Adaptor::RegisterProcessor( Integration::Processor& processor )
943 {
944   GetCore().RegisterProcessor(processor);
945 }
946
947 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
948 {
949   GetCore().UnregisterProcessor(processor);
950 }
951
952 void Adaptor::RequestUpdateOnce()
953 {
954   if( mThreadController )
955   {
956     mThreadController->RequestUpdateOnce();
957   }
958 }
959
960 void Adaptor::IndicatorSizeChanged(int height)
961 {
962   // Let the core know the indicator height is changed
963   mCore->SetTopMargin(height);
964 }
965
966 bool Adaptor::ProcessCoreEventsFromIdle()
967 {
968   ProcessCoreEvents();
969
970   // the idle handle automatically un-installs itself
971   mNotificationOnIdleInstalled = false;
972
973   return false;
974 }
975
976 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
977 : mResizedSignal(),
978   mLanguageChangedSignal(),
979   mAdaptor( adaptor ),
980   mState( READY ),
981   mCore( nullptr ),
982   mThreadController( nullptr ),
983   mVSyncMonitor( nullptr ),
984   mGraphics( nullptr ),
985   mDisplayConnection( nullptr ),
986   mWindowFrame(),
987   mPlatformAbstraction( nullptr ),
988   mEventHandler( nullptr ),
989   mCallbackManager( nullptr ),
990   mNotificationOnIdleInstalled( false ),
991   mNotificationTrigger( nullptr ),
992   mGestureManager( nullptr ),
993   mDaliFeedbackPlugin(),
994   mFeedbackController( nullptr ),
995   mTtsPlayers(),
996   mObservers(),
997   mDragAndDropDetector(),
998   mDeferredRotationObserver( nullptr ),
999   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1000   mPerformanceInterface( nullptr ),
1001   mKernelTracer(),
1002   mSystemTracer(),
1003   mTriggerEventFactory(),
1004   mObjectProfiler( nullptr ),
1005   mSocketFactory(),
1006   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1007   mUseRemoteSurface( false )
1008 {
1009   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1010
1011   WindowPane defaultWindow;
1012   defaultWindow.nativeWindow = nativeWindow;
1013   defaultWindow.surface = surface;
1014
1015   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1016   iter = mWindowFrame.insert( iter, defaultWindow );
1017
1018   gThreadLocalAdaptor = this;
1019 }
1020
1021 void Adaptor::SetRootLayoutDirection( std::string locale )
1022 {
1023   Dali::Stage stage = Dali::Stage::GetCurrent();
1024
1025   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1026                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1027 }
1028
1029 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1030 {
1031   bool idleAdded( false );
1032
1033   // Only add an idle if the Adaptor is actually running
1034   if( RUNNING == mState || READY == mState || forceAdd )
1035   {
1036     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1037   }
1038
1039   return idleAdded;
1040 }
1041
1042 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1043 {
1044   mCallbackManager->RemoveIdleEntererCallback( callback );
1045 }
1046
1047 } // namespace Adaptor
1048
1049 } // namespace Internal
1050
1051 } // namespace Dali