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