Merge "Add API to notify adaptor that scene has been created" 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 <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   mObjectProfiler = new ObjectProfiler();
145
146   mNotificationTrigger = new TriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ) );
147
148   mVSyncMonitor = new VSyncMonitor;
149
150   mUpdateRenderController = new UpdateRenderController( *this, *mEnvironmentOptions );
151
152   mDaliFeedbackPlugin = new FeedbackPluginProxy( FeedbackPluginProxy::DEFAULT_OBJECT_NAME );
153
154   // Should be called after Core creation
155   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
156   {
157     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
158   }
159   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
160   {
161     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
162   }
163   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
164   {
165     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
166   }
167   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
168   {
169     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
170   }
171   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
172   {
173     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
174   }
175   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
176   {
177     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
178   }
179   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
180   {
181     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
182   }
183   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
184   {
185     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
186   }
187 }
188
189 Adaptor::~Adaptor()
190 {
191   // Ensure stop status
192   Stop();
193
194   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
195   gThreadLocalAdaptor = NULL;
196
197   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
198   {
199     (*iter)->OnDestroy();
200   }
201
202   delete mUpdateRenderController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
203   delete mVSyncMonitor;
204   delete mEventHandler;
205   delete mObjectProfiler;
206
207   delete mCore;
208   delete mEglFactory;
209   // Delete feedback controller before feedback plugin & style monitor dependencies
210   delete mFeedbackController;
211   delete mDaliFeedbackPlugin;
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   // Start the update & render threads
265   mUpdateRenderController->Start();
266
267   mState = RUNNING;
268
269   ProcessCoreEvents(); // Ensure any startup messages are processed.
270
271   if ( !mFeedbackController )
272   {
273     // Start sound & haptic feedback
274     mFeedbackController = new FeedbackController( *mDaliFeedbackPlugin );
275   }
276
277   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
278   {
279     (*iter)->OnStart();
280   }
281 }
282
283 // Dali::Internal::Adaptor::Adaptor::Pause
284 void Adaptor::Pause()
285 {
286   // Only pause the adaptor if we're actually running.
287   if( RUNNING == mState )
288   {
289     // Inform observers that we are about to be paused.
290     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
291     {
292       (*iter)->OnPause();
293     }
294
295     // Reset the event handler when adaptor paused
296     if( mEventHandler )
297     {
298       mEventHandler->Reset();
299     }
300
301     mUpdateRenderController->Pause();
302     mCore->Suspend();
303     mState = PAUSED;
304   }
305 }
306
307 // Dali::Internal::Adaptor::Adaptor::Resume
308 void Adaptor::Resume()
309 {
310   // Only resume the adaptor if we are in the suspended state.
311   if( PAUSED == mState )
312   {
313     // We put ResumeFrameTime first, as this was originally called at the start of mCore->Resume()
314     // If there were events pending, mCore->Resume() will call
315     //   RenderController->RequestUpdate()
316     //     UpdateRenderController->RequestUpdate()
317     //       UpdateRenderSynchronization->RequestUpdate()
318     // and we should have reset the frame timers before allowing Core->Update() to be called.
319     //@todo Should we call UpdateRenderController->Resume before mCore->Resume()?
320
321     mUpdateRenderController->ResumeFrameTime();
322     mCore->Resume();
323     mUpdateRenderController->Resume();
324
325     mState = RUNNING;
326
327     // Reset the event handler when adaptor resumed
328     if( mEventHandler )
329     {
330       mEventHandler->Reset();
331     }
332
333     // Inform observers that we have resumed.
334     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
335     {
336       (*iter)->OnResume();
337     }
338
339     ProcessCoreEvents(); // Ensure any outstanding messages are processed
340   }
341 }
342
343 void Adaptor::Stop()
344 {
345   if( RUNNING == mState ||
346       PAUSED  == mState ||
347       PAUSED_WHILE_HIDDEN == mState )
348   {
349     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
350     {
351       (*iter)->OnStop();
352     }
353
354     mUpdateRenderController->Stop();
355     mCore->Suspend();
356
357     // Delete the TTS player
358     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
359     {
360       if(mTtsPlayers[i])
361       {
362         mTtsPlayers[i].Reset();
363       }
364     }
365
366     delete mEventHandler;
367     mEventHandler = NULL;
368
369     delete mNotificationTrigger;
370     mNotificationTrigger = NULL;
371
372     mCallbackManager->Stop();
373
374     mState = STOPPED;
375   }
376 }
377
378 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
379 {
380   mEventHandler->FeedTouchPoint( point, timeStamp );
381 }
382
383 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
384 {
385   mEventHandler->FeedWheelEvent( wheelEvent );
386 }
387
388 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
389 {
390   mEventHandler->FeedKeyEvent( keyEvent );
391 }
392
393 bool Adaptor::MoveResize( const PositionSize& positionSize )
394 {
395   PositionSize old = mSurface->GetPositionSize();
396
397   // just resize the surface. The driver should automatically resize the egl Surface (untested)
398   // EGL Spec says : EGL window surfaces need to be resized when their corresponding native window
399   // is resized. Implementations typically use hooks into the OS and native window
400   // system to perform this resizing on demand, transparently to the client.
401   mSurface->MoveResize( positionSize );
402
403   if(old.width != positionSize.width || old.height != positionSize.height)
404   {
405     SurfaceSizeChanged(positionSize);
406   }
407
408   return true;
409 }
410
411 void Adaptor::SurfaceResized( const PositionSize& positionSize )
412 {
413   PositionSize old = mSurface->GetPositionSize();
414
415   // Called by an application, when it has resized a window outside of Dali.
416   // The EGL driver automatically detects X Window resize calls, and resizes
417   // the EGL surface for us.
418   mSurface->MoveResize( positionSize );
419
420   if(old.width != positionSize.width || old.height != positionSize.height)
421   {
422     SurfaceSizeChanged(positionSize);
423   }
424 }
425
426 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
427 {
428   mNativeWindow = nativeWindow;
429   mSurface = &surface;
430
431   SurfaceSizeChanged(mSurface->GetPositionSize());
432
433   // flush the event queue to give update and render threads chance
434   // to start processing messages for new camera setup etc as soon as possible
435   ProcessCoreEvents();
436
437   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
438
439   // this method blocks until the render thread has completed the replace.
440   mUpdateRenderController->ReplaceSurface(mSurface);
441
442   // Inform core, so that texture resources can be reloaded
443   mCore->RecoverFromContextLoss();
444
445   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
446 }
447
448 RenderSurface& Adaptor::GetSurface() const
449 {
450   return *mSurface;
451 }
452
453 void Adaptor::ReleaseSurfaceLock()
454 {
455   mSurface->ReleaseLock();
456 }
457
458 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
459 {
460   if(!mTtsPlayers[mode])
461   {
462     // Create the TTS player when it needed, because it can reduce launching time.
463     mTtsPlayers[mode] = TtsPlayer::New(mode);
464   }
465
466   return mTtsPlayers[mode];
467 }
468
469 bool Adaptor::AddIdle( CallbackBase* callback )
470 {
471   bool idleAdded(false);
472
473   // Only add an idle if the Adaptor is actually running
474   if( RUNNING == mState )
475   {
476     idleAdded = mCallbackManager->AddCallback( callback, CallbackManager::IDLE_PRIORITY );
477   }
478
479   return idleAdded;
480 }
481
482 bool Adaptor::CallFromMainLoop( CallbackBase* callback )
483 {
484   bool callAdded(false);
485
486   // Only allow the callback if the Adaptor is actually running
487   if ( RUNNING == mState )
488   {
489     callAdded = mCallbackManager->AddCallback( callback, CallbackManager::DEFAULT_PRIORITY );
490   }
491
492   return callAdded;
493 }
494
495 Dali::Adaptor& Adaptor::Get()
496 {
497   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
498   return gThreadLocalAdaptor->mAdaptor;
499 }
500
501 bool Adaptor::IsAvailable()
502 {
503   return gThreadLocalAdaptor != NULL;
504 }
505
506 Dali::Integration::Core& Adaptor::GetCore()
507 {
508   return *mCore;
509 }
510
511 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
512 {
513   mUpdateRenderController->SetRenderRefreshRate( numberOfVSyncsPerRender );
514 }
515
516 void Adaptor::SetUseHardwareVSync( bool useHardware )
517 {
518   mVSyncMonitor->SetUseHardwareVSync( useHardware );
519 }
520
521 EglFactory& Adaptor::GetEGLFactory() const
522 {
523   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
524   return *mEglFactory;
525 }
526
527 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
528 {
529   return *mEglFactory;
530 }
531
532 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
533 {
534   DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
535   return *mGLES;
536 }
537
538 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
539 {
540   return *mPlatformAbstraction;
541 }
542
543 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
544 {
545   return *mGLES;
546 }
547
548 TriggerEventInterface& Adaptor::GetTriggerEventInterface()
549 {
550   return *mNotificationTrigger;
551 }
552
553 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
554 {
555   return mTriggerEventFactory;
556 }
557
558 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
559 {
560   return mSocketFactory;
561 }
562
563 RenderSurface* Adaptor::GetRenderSurfaceInterface()
564 {
565   return mSurface;
566 }
567
568 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
569 {
570   return mVSyncMonitor;
571 }
572
573 TraceInterface& Adaptor::GetKernelTraceInterface()
574 {
575   return mKernelTracer;
576 }
577
578 TraceInterface& Adaptor::GetSystemTraceInterface()
579 {
580   return mSystemTracer;
581 }
582
583 PerformanceInterface* Adaptor::GetPerformanceInterface()
584 {
585   return mPerformanceInterface;
586 }
587
588 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
589 {
590   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
591   return *mPlatformAbstraction;
592 }
593
594 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
595 {
596   mDragAndDropDetector = detector;
597
598   if ( mEventHandler )
599   {
600     mEventHandler->SetDragAndDropDetector( detector );
601   }
602 }
603
604 void Adaptor::SetRotationObserver( RotationObserver* observer )
605 {
606   if( mEventHandler )
607   {
608     mEventHandler->SetRotationObserver( observer );
609   }
610   else if( mState == READY )
611   {
612     // Set once event handler exists
613     mDeferredRotationObserver = observer;
614   }
615 }
616
617 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
618 {
619   if(mTtsPlayers[mode])
620   {
621     mTtsPlayers[mode].Reset();
622   }
623 }
624
625 void Adaptor::SetMinimumPinchDistance(float distance)
626 {
627   if( mGestureManager )
628   {
629     mGestureManager->SetMinimumPinchDistance(distance);
630   }
631 }
632
633 Any Adaptor::GetNativeWindowHandle()
634 {
635   return mNativeWindow;
636 }
637
638 void Adaptor::AddObserver( LifeCycleObserver& observer )
639 {
640   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
641
642   if ( match == mObservers.end() )
643   {
644     mObservers.push_back( &observer );
645   }
646 }
647
648 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
649 {
650   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
651
652   if ( match != mObservers.end() )
653   {
654     mObservers.erase( match );
655   }
656 }
657
658 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
659 {
660   if( mCore )
661   {
662     mCore->QueueEvent(event);
663   }
664 }
665
666 void Adaptor::ProcessCoreEvents()
667 {
668   if( mCore )
669   {
670     if( mPerformanceInterface )
671     {
672       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
673     }
674
675     mCore->ProcessEvents();
676
677     if( mPerformanceInterface )
678     {
679       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
680     }
681   }
682 }
683
684 void Adaptor::RequestUpdate()
685 {
686   // When Dali applications are partially visible behind the lock-screen,
687   // the indicator must be updated (therefore allow updates in the PAUSED state)
688   if ( PAUSED  == mState ||
689        RUNNING == mState )
690   {
691     mUpdateRenderController->RequestUpdate();
692   }
693 }
694
695 void Adaptor::RequestProcessEventsOnIdle()
696 {
697   // Only request a notification if the Adaptor is actually running
698   // and we haven't installed the idle notification
699   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState ) )
700   {
701     mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ) );
702   }
703 }
704
705 void Adaptor::OnWindowShown()
706 {
707   if ( PAUSED_WHILE_HIDDEN == mState )
708   {
709     // Adaptor can now be resumed
710     mState = PAUSED;
711
712     Resume();
713
714     // Force a render task
715     RequestUpdateOnce();
716   }
717 }
718
719 void Adaptor::OnWindowHidden()
720 {
721   if ( STOPPED != mState )
722   {
723     Pause();
724
725     // Adaptor cannot be resumed until the window is shown
726     mState = PAUSED_WHILE_HIDDEN;
727   }
728 }
729
730 // Dali::Internal::Adaptor::Adaptor::OnDamaged
731 void Adaptor::OnDamaged( const DamageArea& area )
732 {
733   // This is needed for the case where Dali window is partially obscured
734   RequestUpdate();
735 }
736
737 void Adaptor::SurfaceSizeChanged(const PositionSize& positionSize)
738 {
739   // let the core know the surface size has changed
740   mCore->SurfaceResized(positionSize.width, positionSize.height);
741
742   mResizedSignal.Emit( mAdaptor );
743 }
744
745 void Adaptor::NotifySceneCreated()
746 {
747   GetCore().SceneCreated();
748 }
749
750 void Adaptor::NotifyLanguageChanged()
751 {
752   mLanguageChangedSignal.Emit( mAdaptor );
753 }
754
755 void Adaptor::RequestUpdateOnce()
756 {
757   if( PAUSED_WHILE_HIDDEN != mState )
758   {
759     if( mUpdateRenderController )
760     {
761       mUpdateRenderController->RequestUpdateOnce();
762     }
763   }
764 }
765
766 void Adaptor::ProcessCoreEventsFromIdle()
767 {
768   ProcessCoreEvents();
769
770   // the idle handle automatically un-installs itself
771   mNotificationOnIdleInstalled = false;
772 }
773
774 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
775 : mResizedSignal(),
776   mLanguageChangedSignal(),
777   mAdaptor(adaptor),
778   mState(READY),
779   mCore(NULL),
780   mUpdateRenderController(NULL),
781   mVSyncMonitor(NULL),
782   mGLES( NULL ),
783   mEglFactory( NULL ),
784   mNativeWindow( nativeWindow ),
785   mSurface( surface ),
786   mPlatformAbstraction( NULL ),
787   mEventHandler( NULL ),
788   mCallbackManager( NULL ),
789   mNotificationOnIdleInstalled( false ),
790   mNotificationTrigger(NULL),
791   mGestureManager(NULL),
792   mDaliFeedbackPlugin(NULL),
793   mFeedbackController(NULL),
794   mObservers(),
795   mDragAndDropDetector(),
796   mDeferredRotationObserver(NULL),
797   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
798   mPerformanceInterface(NULL),
799   mObjectProfiler(NULL),
800   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ )
801 {
802   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
803   gThreadLocalAdaptor = this;
804 }
805
806 // Stereoscopy
807
808 void Adaptor::SetViewMode( ViewMode viewMode )
809 {
810   mSurface->SetViewMode( viewMode );
811   mCore->SetViewMode( viewMode );
812 }
813
814 ViewMode Adaptor::GetViewMode() const
815 {
816   return mCore->GetViewMode();
817 }
818
819 void Adaptor::SetStereoBase( float stereoBase )
820 {
821   mCore->SetStereoBase( stereoBase );
822 }
823
824 float Adaptor::GetStereoBase() const
825 {
826   return mCore->GetStereoBase();
827 }
828
829 } // namespace Adaptor
830
831 } // namespace Internal
832
833 } // namespace Dali