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