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