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