Merge "Modified not to reload resource image on surface change" 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 <gl/gl-proxy-implementation.h>
44 #include <gl/gl-implementation.h>
45 #include <gl/egl-sync-implementation.h>
46 #include <gl/egl-image-extensions.h>
47 #include <gl/egl-factory.h>
48 #include <imf-manager-impl.h>
49 #include <clipboard-impl.h>
50 #include <vsync-monitor.h>
51 #include <object-profiler.h>
52 #include <base/display-connection.h>
53 #include <window-impl.h>
54
55 #include <tizen-logging.h>
56
57 using Dali::TextAbstraction::FontClient;
58
59 namespace Dali
60 {
61
62 namespace Internal
63 {
64
65 namespace Adaptor
66 {
67
68 namespace
69 {
70 __thread Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
71 } // unnamed namespace
72
73 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
74 {
75   Dali::Adaptor* adaptor = new Dali::Adaptor;
76   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
77   adaptor->mImpl = impl;
78
79   impl->Initialize(configuration);
80
81   return adaptor;
82 }
83
84 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
85 {
86   Any winId = window.GetNativeHandle();
87
88   Window& windowImpl = Dali::GetImplementation(window);
89   Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
90   windowImpl.SetAdaptor(*adaptor);
91   return adaptor;
92 }
93
94 void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration )
95 {
96   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
97   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
98   mEnvironmentOptions->SetLogFunction( logFunction );
99   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
100
101   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
102
103   std::string path;
104   GetDataStoragePath( path );
105   mPlatformAbstraction->SetDataStoragePath( path );
106
107   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
108   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
109   {
110     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
111   }
112   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
113   // files automatically.
114
115   if( mEnvironmentOptions->PerformanceServerRequired() )
116   {
117     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
118   }
119
120   mCallbackManager = CallbackManager::New();
121
122   PositionSize size = mSurface->GetPositionSize();
123
124   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
125
126   if( mEnvironmentOptions->GetGlesCallTime() > 0 )
127   {
128     mGLES = new GlProxyImplementation( *mEnvironmentOptions );
129   }
130   else
131   {
132     mGLES = new GlImplementation();
133   }
134
135   mEglFactory = new EglFactory();
136
137   EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
138
139   mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager, dataRetentionPolicy );
140
141   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
142   if( 0u < timeInterval )
143   {
144     mObjectProfiler = new ObjectProfiler( timeInterval );
145   }
146
147   mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
148
149   mVSyncMonitor = new VSyncMonitor;
150
151   mUpdateRenderController = new UpdateRenderController( *this, *mEnvironmentOptions );
152
153   // Should be called after Core creation
154   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
155   {
156     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
157   }
158   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
159   {
160     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
161   }
162   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
163   {
164     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
165   }
166   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
167   {
168     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
169   }
170   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
171   {
172     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
173   }
174   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
175   {
176     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
177   }
178   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
179   {
180     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
181   }
182   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
183   {
184     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
185   }
186 }
187
188 Adaptor::~Adaptor()
189 {
190   // Ensure stop status
191   Stop();
192
193   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
194   gThreadLocalAdaptor = NULL;
195
196   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
197   {
198     (*iter)->OnDestroy();
199   }
200
201   delete mUpdateRenderController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
202   delete mVSyncMonitor;
203   delete mEventHandler;
204   delete mObjectProfiler;
205
206   delete mCore;
207   delete mEglFactory;
208   delete mGLES;
209   delete mGestureManager;
210   delete mPlatformAbstraction;
211   delete mCallbackManager;
212   delete mPerformanceInterface;
213
214   // uninstall it on this thread (main actor thread)
215   Dali::Integration::Log::UninstallLogFunction();
216
217   // Delete environment options if we own it
218   if( mEnvironmentOptionsOwned )
219   {
220     delete mEnvironmentOptions;
221   }
222 }
223
224 void Adaptor::Start()
225 {
226   // it doesn't support restart after stop at this moment
227   // to support restarting, need more testing
228   if( READY != mState )
229   {
230     return;
231   }
232
233   // Start the callback manager
234   mCallbackManager->Start();
235
236   // create event handler
237   mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
238
239   if( mDeferredRotationObserver != NULL )
240   {
241     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
242     mDeferredRotationObserver = NULL;
243   }
244
245   unsigned int dpiHor, dpiVer;
246   dpiHor = dpiVer = 0;
247   Dali::DisplayConnection::GetDpi(dpiHor, dpiVer);
248
249   // tell core about the DPI value
250   mCore->SetDpi(dpiHor, dpiVer);
251
252   // set the DPI value for font rendering
253   FontClient fontClient = FontClient::Get();
254   fontClient.SetDpi( dpiHor, dpiVer );
255
256   // Tell the core the size of the surface just before we start the render-thread
257   PositionSize size = mSurface->GetPositionSize();
258   mCore->SurfaceResized( size.width, size.height );
259
260   // Start the update & render threads
261   mUpdateRenderController->Start();
262
263   mState = RUNNING;
264
265   ProcessCoreEvents(); // Ensure any startup messages are processed.
266
267   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
268   {
269     (*iter)->OnStart();
270   }
271 }
272
273 // Dali::Internal::Adaptor::Adaptor::Pause
274 void Adaptor::Pause()
275 {
276   // Only pause the adaptor if we're actually running.
277   if( RUNNING == mState )
278   {
279     // Inform observers that we are about to be paused.
280     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
281     {
282       (*iter)->OnPause();
283     }
284
285     // Reset the event handler when adaptor paused
286     if( mEventHandler )
287     {
288       mEventHandler->Pause();
289     }
290
291     mUpdateRenderController->Pause();
292     mCore->Suspend();
293     mState = PAUSED;
294   }
295 }
296
297 // Dali::Internal::Adaptor::Adaptor::Resume
298 void Adaptor::Resume()
299 {
300   // Only resume the adaptor if we are in the suspended state.
301   if( PAUSED == mState )
302   {
303     // We put ResumeFrameTime first, as this was originally called at the start of mCore->Resume()
304     // If there were events pending, mCore->Resume() will call
305     //   RenderController->RequestUpdate()
306     //     UpdateRenderController->RequestUpdate()
307     //       UpdateRenderSynchronization->RequestUpdate()
308     // and we should have reset the frame timers before allowing Core->Update() to be called.
309     //@todo Should we call UpdateRenderController->Resume before mCore->Resume()?
310
311     mUpdateRenderController->ResumeFrameTime();
312     mCore->Resume();
313     mUpdateRenderController->Resume();
314
315     mState = RUNNING;
316
317     // Reset the event handler when adaptor resumed
318     if( mEventHandler )
319     {
320       mEventHandler->Resume();
321     }
322
323     // Inform observers that we have resumed.
324     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
325     {
326       (*iter)->OnResume();
327     }
328
329     ProcessCoreEvents(); // Ensure any outstanding messages are processed
330   }
331 }
332
333 void Adaptor::Stop()
334 {
335   if( RUNNING == mState ||
336       PAUSED  == mState ||
337       PAUSED_WHILE_HIDDEN == mState )
338   {
339     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
340     {
341       (*iter)->OnStop();
342     }
343
344     mUpdateRenderController->Stop();
345     mCore->Suspend();
346
347     // Delete the TTS player
348     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
349     {
350       if(mTtsPlayers[i])
351       {
352         mTtsPlayers[i].Reset();
353       }
354     }
355
356     delete mEventHandler;
357     mEventHandler = NULL;
358
359     delete mNotificationTrigger;
360     mNotificationTrigger = NULL;
361
362     mCallbackManager->Stop();
363
364     mState = STOPPED;
365   }
366 }
367
368 void Adaptor::ContextLost()
369 {
370   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
371 }
372
373 void Adaptor::ContextRegained()
374 {
375   // Inform core, so that texture resources can be reloaded
376   mCore->RecoverFromContextLoss();
377
378   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
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   // this method blocks until the render thread has completed the replace.
441   mUpdateRenderController->ReplaceSurface(mSurface);
442 }
443
444 RenderSurface& Adaptor::GetSurface() const
445 {
446   return *mSurface;
447 }
448
449 void Adaptor::ReleaseSurfaceLock()
450 {
451   mSurface->ReleaseLock();
452 }
453
454 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
455 {
456   if(!mTtsPlayers[mode])
457   {
458     // Create the TTS player when it needed, because it can reduce launching time.
459     mTtsPlayers[mode] = TtsPlayer::New(mode);
460   }
461
462   return mTtsPlayers[mode];
463 }
464
465 bool Adaptor::AddIdle( CallbackBase* callback )
466 {
467   bool idleAdded(false);
468
469   // Only add an idle if the Adaptor is actually running
470   if( RUNNING == mState )
471   {
472     idleAdded = mCallbackManager->AddIdleCallback( callback );
473   }
474
475   return idleAdded;
476 }
477
478
479 Dali::Adaptor& Adaptor::Get()
480 {
481   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
482   return gThreadLocalAdaptor->mAdaptor;
483 }
484
485 bool Adaptor::IsAvailable()
486 {
487   return gThreadLocalAdaptor != NULL;
488 }
489
490 void Adaptor::SceneCreated()
491 {
492   mCore->SceneCreated();
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::GetProcessCoreEventsTrigger()
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::NotifySceneCreated()
735 {
736   GetCore().SceneCreated();
737 }
738
739 void Adaptor::NotifyLanguageChanged()
740 {
741   mLanguageChangedSignal.Emit( mAdaptor );
742 }
743
744 void Adaptor::RequestUpdateOnce()
745 {
746   if( PAUSED_WHILE_HIDDEN != mState )
747   {
748     if( mUpdateRenderController )
749     {
750       mUpdateRenderController->RequestUpdateOnce();
751     }
752   }
753 }
754
755 void Adaptor::ProcessCoreEventsFromIdle()
756 {
757   ProcessCoreEvents();
758
759   // the idle handle automatically un-installs itself
760   mNotificationOnIdleInstalled = false;
761 }
762
763 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
764 : mResizedSignal(),
765   mLanguageChangedSignal(),
766   mAdaptor(adaptor),
767   mState(READY),
768   mCore(NULL),
769   mUpdateRenderController(NULL),
770   mVSyncMonitor(NULL),
771   mGLES( NULL ),
772   mEglFactory( NULL ),
773   mNativeWindow( nativeWindow ),
774   mSurface( surface ),
775   mPlatformAbstraction( NULL ),
776   mEventHandler( NULL ),
777   mCallbackManager( NULL ),
778   mNotificationOnIdleInstalled( false ),
779   mNotificationTrigger(NULL),
780   mGestureManager(NULL),
781   mObservers(),
782   mDragAndDropDetector(),
783   mDeferredRotationObserver(NULL),
784   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
785   mPerformanceInterface(NULL),
786   mObjectProfiler(NULL),
787   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ )
788 {
789   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
790   gThreadLocalAdaptor = this;
791 }
792
793 // Stereoscopy
794
795 void Adaptor::SetViewMode( ViewMode viewMode )
796 {
797   mSurface->SetViewMode( viewMode );
798   mCore->SetViewMode( viewMode );
799 }
800
801 ViewMode Adaptor::GetViewMode() const
802 {
803   return mCore->GetViewMode();
804 }
805
806 void Adaptor::SetStereoBase( float stereoBase )
807 {
808   mCore->SetStereoBase( stereoBase );
809 }
810
811 float Adaptor::GetStereoBase() const
812 {
813   return mCore->GetStereoBase();
814 }
815
816 } // namespace Adaptor
817
818 } // namespace Internal
819
820 } // namespace Dali