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