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