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