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