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