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