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