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