Fix SVACE errors
[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   // Must delete the old Window first before replacing it with the new one
504   WindowPane oldDefaultWindow = mWindowFrame.front();
505   oldDefaultWindow.surface->DestroySurface();
506
507   // Update WindowFrame
508   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
509   iter = mWindowFrame.insert( iter, newDefaultWindow );
510
511   // Flush the event queue to give the update-render thread chance
512   // to start processing messages for new camera setup etc as soon as possible
513   ProcessCoreEvents();
514
515   // This method blocks until the render thread has completed the replace.
516   mThreadController->ReplaceSurface( newDefaultWindow.surface );
517 }
518
519 RenderSurface& Adaptor::GetSurface() const
520 {
521   WindowPane defaultWindow = mWindowFrame.front();
522   return *(defaultWindow.surface);
523 }
524
525 void Adaptor::ReleaseSurfaceLock()
526 {
527   WindowPane defaultWindow = mWindowFrame.front();
528   defaultWindow.surface->ReleaseLock();
529 }
530
531 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
532 {
533   if(!mTtsPlayers[mode])
534   {
535     // Create the TTS player when it needed, because it can reduce launching time.
536     mTtsPlayers[mode] = TtsPlayer::New(mode);
537   }
538
539   return mTtsPlayers[mode];
540 }
541
542 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
543 {
544   bool idleAdded(false);
545
546   // Only add an idle if the Adaptor is actually running
547   if( RUNNING == mState || READY == mState || forceAdd )
548   {
549     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
550   }
551
552   return idleAdded;
553 }
554
555 void Adaptor::RemoveIdle( CallbackBase* callback )
556 {
557   mCallbackManager->RemoveIdleCallback( callback );
558 }
559
560 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
561 {
562   mThreadController->SetPreRenderCallback( callback );
563 }
564
565 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
566 {
567   // This is any Window that is not the main (default) one
568   WindowPane additionalWindow;
569   additionalWindow.instance = childWindow;
570   additionalWindow.window_name = childWindowName;
571   additionalWindow.class_name = childWindowClassName;
572   additionalWindow.window_mode = childWindowMode;
573
574   // Add the new Window to the Frame - the order is not important
575   mWindowFrame.push_back( additionalWindow );
576
577   Window& windowImpl = Dali::GetImplementation( *childWindow );
578   windowImpl.SetAdaptor( Get() );
579
580   return true;
581 }
582
583 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
584 {
585   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
586   {
587     if( iter->instance == childWindow )
588     {
589       mWindowFrame.erase( iter );
590       return true;
591     }
592   }
593
594   return false;
595 }
596
597 bool Adaptor::RemoveWindow( std::string childWindowName )
598 {
599   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
600   {
601     if( iter->window_name == childWindowName )
602     {
603       mWindowFrame.erase( iter );
604       return true;
605     }
606   }
607
608   return false;
609 }
610
611 Dali::Adaptor& Adaptor::Get()
612 {
613   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
614   return gThreadLocalAdaptor->mAdaptor;
615 }
616
617 bool Adaptor::IsAvailable()
618 {
619   return gThreadLocalAdaptor != NULL;
620 }
621
622 void Adaptor::SceneCreated()
623 {
624   mCore->SceneCreated();
625 }
626
627 Dali::Integration::Core& Adaptor::GetCore()
628 {
629   return *mCore;
630 }
631
632 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
633 {
634   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
635 }
636
637 void Adaptor::SetUseHardwareVSync( bool useHardware )
638 {
639   mVSyncMonitor->SetUseHardwareVSync( useHardware );
640 }
641
642 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
643 {
644   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
645   return *mDisplayConnection;
646 }
647
648 GraphicsInterface& Adaptor::GetGraphicsInterface()
649 {
650   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
651   return *mGraphics;
652 }
653
654 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
655 {
656   return *mPlatformAbstraction;
657 }
658
659 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
660 {
661   return *mNotificationTrigger;
662 }
663
664 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
665 {
666   return mTriggerEventFactory;
667 }
668
669 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
670 {
671   return mSocketFactory;
672 }
673
674 RenderSurface* Adaptor::GetRenderSurfaceInterface()
675 {
676   if( !mWindowFrame.empty())
677   {
678     WindowPane defaultWindow = mWindowFrame.front();
679     return defaultWindow.surface;
680   }
681   else
682   {
683     return nullptr;
684   }
685 }
686
687 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
688 {
689   return mVSyncMonitor;
690 }
691
692 TraceInterface& Adaptor::GetKernelTraceInterface()
693 {
694   return mKernelTracer;
695 }
696
697 TraceInterface& Adaptor::GetSystemTraceInterface()
698 {
699   return mSystemTracer;
700 }
701
702 PerformanceInterface* Adaptor::GetPerformanceInterface()
703 {
704   return mPerformanceInterface;
705 }
706
707 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
708 {
709   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
710   return *mPlatformAbstraction;
711 }
712
713 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
714 {
715   mDragAndDropDetector = detector;
716
717   if ( mEventHandler )
718   {
719     mEventHandler->SetDragAndDropDetector( detector );
720   }
721 }
722
723 void Adaptor::SetRotationObserver( RotationObserver* observer )
724 {
725   if( mEventHandler )
726   {
727     mEventHandler->SetRotationObserver( observer );
728   }
729   else if( mState == READY )
730   {
731     // Set once event handler exists
732     mDeferredRotationObserver = observer;
733   }
734 }
735
736 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
737 {
738   if(mTtsPlayers[mode])
739   {
740     mTtsPlayers[mode].Reset();
741   }
742 }
743
744 void Adaptor::SetMinimumPinchDistance(float distance)
745 {
746   if( mGestureManager )
747   {
748     mGestureManager->SetMinimumPinchDistance(distance);
749   }
750 }
751
752 Any Adaptor::GetNativeWindowHandle()
753 {
754   WindowPane defaultWindow = mWindowFrame.front();
755   return defaultWindow.nativeWindow;
756 }
757
758 Any Adaptor::GetGraphicsDisplay()
759 {
760   Any display;
761
762   if (mGraphics)
763   {
764     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
765
766     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
767     display = eglImpl.GetDisplay();
768   }
769
770   return display;
771 }
772
773 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
774 {
775   mUseRemoteSurface = useRemoteSurface;
776 }
777
778 void Adaptor::AddObserver( LifeCycleObserver& observer )
779 {
780   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
781
782   if ( match == mObservers.end() )
783   {
784     mObservers.push_back( &observer );
785   }
786 }
787
788 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
789 {
790   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
791
792   if ( match != mObservers.end() )
793   {
794     mObservers.erase( match );
795   }
796 }
797
798 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
799 {
800   if( mCore )
801   {
802     mCore->QueueEvent(event);
803   }
804 }
805
806 void Adaptor::ProcessCoreEvents()
807 {
808   if( mCore )
809   {
810     if( mPerformanceInterface )
811     {
812       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
813     }
814
815     mCore->ProcessEvents();
816
817     if( mPerformanceInterface )
818     {
819       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
820     }
821   }
822 }
823
824 void Adaptor::RequestUpdate( bool forceUpdate )
825 {
826   switch( mState )
827   {
828     case RUNNING:
829     {
830       mThreadController->RequestUpdate();
831       break;
832     }
833     case PAUSED:
834     case PAUSED_WHILE_HIDDEN:
835     {
836       // When Dali applications are partially visible behind the lock-screen,
837       // the indicator must be updated (therefore allow updates in the PAUSED state)
838       if( forceUpdate )
839       {
840         mThreadController->RequestUpdateOnce();
841       }
842       break;
843     }
844     default:
845     {
846       // Do nothing
847       break;
848     }
849   }
850 }
851
852 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
853 {
854   // Only request a notification if the Adaptor is actually running
855   // and we haven't installed the idle notification
856   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
857   {
858     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
859   }
860 }
861
862 void Adaptor::OnWindowShown()
863 {
864   if ( PAUSED_WHILE_HIDDEN == mState )
865   {
866     // Adaptor can now be resumed
867     mState = PAUSED;
868
869     Resume();
870
871     // Force a render task
872     RequestUpdateOnce();
873   }
874 }
875
876 void Adaptor::OnWindowHidden()
877 {
878   if ( RUNNING == mState )
879   {
880     Pause();
881
882     // Adaptor cannot be resumed until the window is shown
883     mState = PAUSED_WHILE_HIDDEN;
884   }
885 }
886
887 // Dali::Internal::Adaptor::Adaptor::OnDamaged
888 void Adaptor::OnDamaged( const DamageArea& area )
889 {
890   // This is needed for the case where Dali window is partially obscured
891   RequestUpdate( false );
892 }
893
894 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
895 {
896   // Let the core know the surface size has changed
897   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
898
899   mResizedSignal.Emit( mAdaptor );
900 }
901
902 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
903 {
904   // Flush the event queue to give the update-render thread chance
905   // to start processing messages for new camera setup etc as soon as possible
906   ProcessCoreEvents();
907
908   mThreadController->ResizeSurface();
909 }
910
911 void Adaptor::NotifySceneCreated()
912 {
913   GetCore().SceneCreated();
914
915   // Start thread controller after the scene has been created
916   mThreadController->Start();
917
918   // Process after surface is created (registering to remote surface provider if required)
919   SurfaceInitialized();
920
921   mState = RUNNING;
922 }
923
924 void Adaptor::NotifyLanguageChanged()
925 {
926   mLanguageChangedSignal.Emit( mAdaptor );
927 }
928
929 void Adaptor::RenderOnce()
930 {
931   RequestUpdateOnce();
932 }
933
934 const LogFactoryInterface& Adaptor::GetLogFactory()
935 {
936   return *mEnvironmentOptions;
937 }
938
939 void Adaptor::RequestUpdateOnce()
940 {
941   if( mThreadController )
942   {
943     mThreadController->RequestUpdateOnce();
944   }
945 }
946
947 void Adaptor::IndicatorSizeChanged(int height)
948 {
949   // Let the core know the indicator height is changed
950   mCore->SetTopMargin(height);
951 }
952
953 bool Adaptor::ProcessCoreEventsFromIdle()
954 {
955   ProcessCoreEvents();
956
957   // the idle handle automatically un-installs itself
958   mNotificationOnIdleInstalled = false;
959
960   return false;
961 }
962
963 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
964 : mResizedSignal(),
965   mLanguageChangedSignal(),
966   mAdaptor( adaptor ),
967   mState( READY ),
968   mCore( nullptr ),
969   mThreadController( nullptr ),
970   mVSyncMonitor( nullptr ),
971   mGraphics( nullptr ),
972   mDisplayConnection( nullptr ),
973   mWindowFrame(),
974   mPlatformAbstraction( nullptr ),
975   mEventHandler( nullptr ),
976   mCallbackManager( nullptr ),
977   mNotificationOnIdleInstalled( false ),
978   mNotificationTrigger( nullptr ),
979   mGestureManager( nullptr ),
980   mDaliFeedbackPlugin(),
981   mFeedbackController( nullptr ),
982   mTtsPlayers(),
983   mObservers(),
984   mDragAndDropDetector(),
985   mDeferredRotationObserver( nullptr ),
986   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
987   mPerformanceInterface( nullptr ),
988   mKernelTracer(),
989   mSystemTracer(),
990   mTriggerEventFactory(),
991   mObjectProfiler( nullptr ),
992   mSocketFactory(),
993   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
994   mUseRemoteSurface( false )
995 {
996   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
997
998   WindowPane defaultWindow;
999   defaultWindow.nativeWindow = nativeWindow;
1000   defaultWindow.surface = surface;
1001
1002   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1003   iter = mWindowFrame.insert( iter, defaultWindow );
1004
1005   gThreadLocalAdaptor = this;
1006 }
1007
1008 void Adaptor::SetRootLayoutDirection( std::string locale )
1009 {
1010   Dali::Stage stage = Dali::Stage::GetCurrent();
1011
1012   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1013                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1014 }
1015
1016 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1017 {
1018   bool idleAdded( false );
1019
1020   // Only add an idle if the Adaptor is actually running
1021   if( RUNNING == mState || READY == mState || forceAdd )
1022   {
1023     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1024   }
1025
1026   return idleAdded;
1027 }
1028
1029 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1030 {
1031   mCallbackManager->RemoveIdleEntererCallback( callback );
1032 }
1033
1034 } // namespace Adaptor
1035
1036 } // namespace Internal
1037
1038 } // namespace Dali