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