[4.0] Render to Frame Buffer Object.
[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     // Process remained events and rendering in the update thread
315     RequestUpdateOnce();
316   }
317 }
318
319 // Dali::Internal::Adaptor::Adaptor::Resume
320 void Adaptor::Resume()
321 {
322   // Only resume the adaptor if we are in the suspended state.
323   if( PAUSED == mState )
324   {
325     mState = RUNNING;
326
327     // Reset the event handler when adaptor resumed
328     if( mEventHandler )
329     {
330       mEventHandler->Resume();
331     }
332
333     // Inform observers that we have resumed.
334     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
335     {
336       (*iter)->OnResume();
337     }
338
339     // trigger processing of events queued up while paused
340     mCore->ProcessEvents();
341
342     // Do at end to ensure our first update/render after resumption includes the processed messages as well
343     mThreadController->Resume();
344   }
345 }
346
347 void Adaptor::Stop()
348 {
349   if( RUNNING == mState ||
350       PAUSED  == mState ||
351       PAUSED_WHILE_HIDDEN == mState )
352   {
353     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
354     {
355       (*iter)->OnStop();
356     }
357
358     mThreadController->Stop();
359
360     // Delete the TTS player
361     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
362     {
363       if(mTtsPlayers[i])
364       {
365         mTtsPlayers[i].Reset();
366       }
367     }
368
369     delete mEventHandler;
370     mEventHandler = NULL;
371
372     delete mNotificationTrigger;
373     mNotificationTrigger = NULL;
374
375     mCallbackManager->Stop();
376
377     mState = STOPPED;
378   }
379 }
380
381 void Adaptor::ContextLost()
382 {
383   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
384 }
385
386 void Adaptor::ContextRegained()
387 {
388   // Inform core, so that texture resources can be reloaded
389   mCore->RecoverFromContextLoss();
390
391   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
392 }
393
394 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
395 {
396   mEventHandler->FeedTouchPoint( point, timeStamp );
397 }
398
399 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
400 {
401   mEventHandler->FeedWheelEvent( wheelEvent );
402 }
403
404 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
405 {
406   mEventHandler->FeedKeyEvent( keyEvent );
407 }
408
409 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
410 {
411   PositionSize positionSize = surface.GetPositionSize();
412
413   // let the core know the surface size has changed
414   mCore->SurfaceResized( positionSize.width, positionSize.height );
415
416   mResizedSignal.Emit( mAdaptor );
417
418   mNativeWindow = nativeWindow;
419   mSurface = &surface;
420
421   // flush the event queue to give the update-render thread chance
422   // to start processing messages for new camera setup etc as soon as possible
423   ProcessCoreEvents();
424
425   // this method blocks until the render thread has completed the replace.
426   mThreadController->ReplaceSurface(mSurface);
427 }
428
429 RenderSurface& Adaptor::GetSurface() const
430 {
431   return *mSurface;
432 }
433
434 void Adaptor::ReleaseSurfaceLock()
435 {
436   mSurface->ReleaseLock();
437 }
438
439 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
440 {
441   if(!mTtsPlayers[mode])
442   {
443     // Create the TTS player when it needed, because it can reduce launching time.
444     mTtsPlayers[mode] = TtsPlayer::New(mode);
445   }
446
447   return mTtsPlayers[mode];
448 }
449
450 bool Adaptor::AddIdle( CallbackBase* callback, bool forceAdd )
451 {
452   bool idleAdded(false);
453
454   // Only add an idle if the Adaptor is actually running
455   if( RUNNING == mState || forceAdd )
456   {
457     idleAdded = mCallbackManager->AddIdleCallback( callback );
458   }
459
460   return idleAdded;
461 }
462
463 void Adaptor::RemoveIdle( CallbackBase* callback )
464 {
465   mCallbackManager->RemoveIdleCallback( callback );
466 }
467
468 Dali::Adaptor& Adaptor::Get()
469 {
470   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
471   return gThreadLocalAdaptor->mAdaptor;
472 }
473
474 bool Adaptor::IsAvailable()
475 {
476   return gThreadLocalAdaptor != NULL;
477 }
478
479 void Adaptor::SceneCreated()
480 {
481   mCore->SceneCreated();
482 }
483
484 Dali::Integration::Core& Adaptor::GetCore()
485 {
486   return *mCore;
487 }
488
489 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
490 {
491   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
492 }
493
494 void Adaptor::SetUseHardwareVSync( bool useHardware )
495 {
496   mVSyncMonitor->SetUseHardwareVSync( useHardware );
497 }
498
499 EglFactory& Adaptor::GetEGLFactory() const
500 {
501   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
502   return *mEglFactory;
503 }
504
505 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
506 {
507   return *mEglFactory;
508 }
509
510 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
511 {
512   DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
513   return *mGLES;
514 }
515
516 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
517 {
518   return *mPlatformAbstraction;
519 }
520
521 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
522 {
523   return *mGLES;
524 }
525
526 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
527 {
528   return *mNotificationTrigger;
529 }
530
531 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
532 {
533   return mTriggerEventFactory;
534 }
535
536 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
537 {
538   return mSocketFactory;
539 }
540
541 RenderSurface* Adaptor::GetRenderSurfaceInterface()
542 {
543   return mSurface;
544 }
545
546 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
547 {
548   return mVSyncMonitor;
549 }
550
551 TraceInterface& Adaptor::GetKernelTraceInterface()
552 {
553   return mKernelTracer;
554 }
555
556 TraceInterface& Adaptor::GetSystemTraceInterface()
557 {
558   return mSystemTracer;
559 }
560
561 PerformanceInterface* Adaptor::GetPerformanceInterface()
562 {
563   return mPerformanceInterface;
564 }
565
566 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
567 {
568   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
569   return *mPlatformAbstraction;
570 }
571
572 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
573 {
574   mDragAndDropDetector = detector;
575
576   if ( mEventHandler )
577   {
578     mEventHandler->SetDragAndDropDetector( detector );
579   }
580 }
581
582 void Adaptor::SetRotationObserver( RotationObserver* observer )
583 {
584   if( mEventHandler )
585   {
586     mEventHandler->SetRotationObserver( observer );
587   }
588   else if( mState == READY )
589   {
590     // Set once event handler exists
591     mDeferredRotationObserver = observer;
592   }
593 }
594
595 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
596 {
597   if(mTtsPlayers[mode])
598   {
599     mTtsPlayers[mode].Reset();
600   }
601 }
602
603 void Adaptor::SetMinimumPinchDistance(float distance)
604 {
605   if( mGestureManager )
606   {
607     mGestureManager->SetMinimumPinchDistance(distance);
608   }
609 }
610
611 Any Adaptor::GetNativeWindowHandle()
612 {
613   return mNativeWindow;
614 }
615
616 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
617 {
618   mUseRemoteSurface = useRemoteSurface;
619 }
620
621 void Adaptor::AddObserver( LifeCycleObserver& observer )
622 {
623   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
624
625   if ( match == mObservers.end() )
626   {
627     mObservers.push_back( &observer );
628   }
629 }
630
631 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
632 {
633   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
634
635   if ( match != mObservers.end() )
636   {
637     mObservers.erase( match );
638   }
639 }
640
641 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
642 {
643   if( mCore )
644   {
645     mCore->QueueEvent(event);
646   }
647 }
648
649 void Adaptor::ProcessCoreEvents()
650 {
651   if( mCore )
652   {
653     if( mPerformanceInterface )
654     {
655       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
656     }
657
658     mCore->ProcessEvents();
659
660     if( mPerformanceInterface )
661     {
662       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
663     }
664   }
665 }
666
667 void Adaptor::RequestUpdate( bool forceUpdate )
668 {
669   switch( mState )
670   {
671     case RUNNING:
672     {
673       mThreadController->RequestUpdate();
674       break;
675     }
676     case PAUSED:
677     case PAUSED_WHILE_HIDDEN:
678     {
679       // When Dali applications are partially visible behind the lock-screen,
680       // the indicator must be updated (therefore allow updates in the PAUSED state)
681       if( forceUpdate )
682       {
683         mThreadController->RequestUpdateOnce();
684       }
685       break;
686     }
687     default:
688     {
689       // Do nothing
690       break;
691     }
692   }
693 }
694
695 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
696 {
697   // Only request a notification if the Adaptor is actually running
698   // and we haven't installed the idle notification
699   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || forceProcess ) )
700   {
701     mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
702   }
703 }
704
705 void Adaptor::OnWindowShown()
706 {
707   if ( PAUSED_WHILE_HIDDEN == mState )
708   {
709     // Adaptor can now be resumed
710     mState = PAUSED;
711
712     Resume();
713
714     // Force a render task
715     RequestUpdateOnce();
716   }
717 }
718
719 void Adaptor::OnWindowHidden()
720 {
721   if ( RUNNING == mState )
722   {
723     Pause();
724
725     // Adaptor cannot be resumed until the window is shown
726     mState = PAUSED_WHILE_HIDDEN;
727   }
728 }
729
730 // Dali::Internal::Adaptor::Adaptor::OnDamaged
731 void Adaptor::OnDamaged( const DamageArea& area )
732 {
733   // This is needed for the case where Dali window is partially obscured
734   RequestUpdate( false );
735 }
736
737 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
738 {
739   // let the core know the surface size has changed
740   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
741
742   mResizedSignal.Emit( mAdaptor );
743 }
744
745 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
746 {
747   // flush the event queue to give the update-render thread chance
748   // to start processing messages for new camera setup etc as soon as possible
749   ProcessCoreEvents();
750
751   // this method blocks until the render thread has completed the resizing.
752   mThreadController->ResizeSurface();
753 }
754
755 void Adaptor::NotifySceneCreated()
756 {
757   GetCore().SceneCreated();
758
759   // Start thread controller after the scene has been created
760   mThreadController->Start();
761
762   // process after surface is created (registering to remote surface provider if required)
763   SurfaceInitialized();
764
765   mState = RUNNING;
766 }
767
768 void Adaptor::NotifyLanguageChanged()
769 {
770   mLanguageChangedSignal.Emit( mAdaptor );
771 }
772
773 void Adaptor::RenderOnce()
774 {
775   RequestUpdateOnce();
776 }
777
778 void Adaptor::RequestUpdateOnce()
779 {
780   if( mThreadController )
781   {
782     mThreadController->RequestUpdateOnce();
783   }
784 }
785
786 void Adaptor::IndicatorSizeChanged(int height)
787 {
788   // let the core know the indicator height is changed
789   mCore->SetTopMargin(height);
790 }
791
792 void Adaptor::ProcessCoreEventsFromIdle()
793 {
794   ProcessCoreEvents();
795
796   // the idle handle automatically un-installs itself
797   mNotificationOnIdleInstalled = false;
798 }
799
800 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
801 : mResizedSignal(),
802   mLanguageChangedSignal(),
803   mAdaptor( adaptor ),
804   mState( READY ),
805   mCore( NULL ),
806   mThreadController( NULL ),
807   mVSyncMonitor( NULL ),
808   mGLES( NULL ),
809   mGlSync( NULL ),
810   mEglFactory( NULL ),
811   mNativeWindow( nativeWindow ),
812   mSurface( surface ),
813   mPlatformAbstraction( NULL ),
814   mEventHandler( NULL ),
815   mCallbackManager( NULL ),
816   mNotificationOnIdleInstalled( false ),
817   mNotificationTrigger( NULL ),
818   mGestureManager( NULL ),
819   mDaliFeedbackPlugin(),
820   mFeedbackController( NULL ),
821   mTtsPlayers(),
822   mObservers(),
823   mDragAndDropDetector(),
824   mDeferredRotationObserver( NULL ),
825   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
826   mPerformanceInterface( NULL ),
827   mKernelTracer(),
828   mSystemTracer(),
829   mTriggerEventFactory(),
830   mObjectProfiler( NULL ),
831   mSocketFactory(),
832   mWindow(),
833   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
834   mUseRemoteSurface( false )
835 {
836   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
837   gThreadLocalAdaptor = this;
838 }
839
840 // Stereoscopy
841
842 void Adaptor::SetViewMode( ViewMode viewMode )
843 {
844   mSurface->SetViewMode( viewMode );
845   mCore->SetViewMode( viewMode );
846 }
847
848 ViewMode Adaptor::GetViewMode() const
849 {
850   return mCore->GetViewMode();
851 }
852
853 void Adaptor::SetStereoBase( float stereoBase )
854 {
855   mCore->SetStereoBase( stereoBase );
856 }
857
858 float Adaptor::GetStereoBase() const
859 {
860   return mCore->GetStereoBase();
861 }
862
863 void Adaptor::SetRootLayoutDirection( std::string locale )
864 {
865   Dali::Stage stage = Dali::Stage::GetCurrent();
866
867   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
868                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
869 }
870
871 void Adaptor::SetWindow( Dali::Window window )
872 {
873   mWindow = window;
874 }
875
876 Dali::Window Adaptor::GetWindow()
877 {
878   return mWindow;
879 }
880
881 } // namespace Adaptor
882
883 } // namespace Internal
884
885 } // namespace Dali