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