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