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