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