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