Ensure last frame update when adaptor is paused
[platform/core/uifw/dali-adaptor.git] / adaptors / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2017 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/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/context-notifier.h>
29 #include <dali/integration-api/profiling.h>
30 #include <dali/integration-api/input-options.h>
31 #include <dali/integration-api/events/touch-event-integ.h>
32
33 // INTERNAL INCLUDES
34 #include <base/thread-controller.h>
35 #include <base/performance-logging/performance-interface-factory.h>
36 #include <base/lifecycle-observer.h>
37
38 #include <dali/devel-api/text-abstraction/font-client.h>
39
40 #include <callback-manager.h>
41 #include <render-surface.h>
42 #include <tts-player-impl.h>
43 #include <accessibility-adaptor-impl.h>
44 #include <events/gesture-manager.h>
45 #include <events/event-handler.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 #include <image-loading.h>
60
61 #include <locale-utils.h>
62
63 using Dali::TextAbstraction::FontClient;
64
65 namespace Dali
66 {
67
68 namespace Internal
69 {
70
71 namespace Adaptor
72 {
73
74 namespace
75 {
76 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
77 } // unnamed namespace
78
79 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
80 {
81   Dali::Adaptor* adaptor = new Dali::Adaptor;
82   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
83   adaptor->mImpl = impl;
84
85   impl->Initialize(configuration);
86
87   return adaptor;
88 }
89
90 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
91 {
92   Any winId = window.GetNativeHandle();
93
94   Window& windowImpl = Dali::GetImplementation(window);
95   Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
96   windowImpl.SetAdaptor(*adaptor);
97   return adaptor;
98 }
99
100 void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration )
101 {
102   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
103   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
104   mEnvironmentOptions->SetLogFunction( logFunction );
105   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
106
107   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
108
109   std::string path;
110   GetDataStoragePath( path );
111   mPlatformAbstraction->SetDataStoragePath( path );
112
113   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
114   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
115   {
116     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
117   }
118   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
119   // files automatically.
120
121   if( mEnvironmentOptions->PerformanceServerRequired() )
122   {
123     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
124   }
125
126   mCallbackManager = CallbackManager::New();
127
128   PositionSize size = mSurface->GetPositionSize();
129
130   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
131
132   if( mEnvironmentOptions->GetGlesCallTime() > 0 )
133   {
134     mGLES = new GlProxyImplementation( *mEnvironmentOptions );
135   }
136   else
137   {
138     mGLES = new GlImplementation();
139   }
140
141   const Integration::DepthBufferAvailable depthBufferAvailable = static_cast< Integration::DepthBufferAvailable >( mEnvironmentOptions->DepthBufferRequired() );
142   const Integration::StencilBufferAvailable stencilBufferAvailable = static_cast< Integration::StencilBufferAvailable >( mEnvironmentOptions->StencilBufferRequired() );
143
144   mEglFactory = new EglFactory( mEnvironmentOptions->GetMultiSamplingLevel(), depthBufferAvailable, stencilBufferAvailable );
145
146   EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
147
148   mCore = Integration::Core::New( *this,
149                                   *mPlatformAbstraction,
150                                   *mGLES,
151                                   *eglSyncImpl,
152                                   *mGestureManager,
153                                   dataRetentionPolicy ,
154                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
155                                   depthBufferAvailable,
156                                   stencilBufferAvailable );
157
158   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
159   if( 0u < timeInterval )
160   {
161     mObjectProfiler = new ObjectProfiler( timeInterval );
162   }
163
164   mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
165
166   mVSyncMonitor = new VSyncMonitor;
167
168   mThreadController = new ThreadController( *this, *mEnvironmentOptions );
169
170   // Should be called after Core creation
171   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
172   {
173     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
174   }
175   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
176   {
177     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
178   }
179   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
180   {
181     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
182   }
183   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
184   {
185     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
186   }
187   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
188   {
189     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
190   }
191   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
192   {
193     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
194   }
195   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
196   {
197     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
198   }
199   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
200   {
201     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
202   }
203   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
204   {
205     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
206   }
207   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
208   {
209     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
210   }
211   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
212   {
213     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
214   }
215   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
216   {
217     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
218   }
219   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
220   {
221     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
222   }
223   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
224   {
225     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
226   }
227   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
228   {
229     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
230   }
231   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
232   {
233     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
234   }
235
236   // Set max texture size
237   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
238   {
239     Dali::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
240   }
241
242   SetupSystemInformation();
243 }
244
245 Adaptor::~Adaptor()
246 {
247   // Ensure stop status
248   Stop();
249
250   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
251   gThreadLocalAdaptor = NULL;
252
253   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
254   {
255     (*iter)->OnDestroy();
256   }
257
258   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
259   delete mVSyncMonitor;
260   delete mEventHandler;
261   delete mObjectProfiler;
262
263   delete mCore;
264   delete mEglFactory;
265   delete mGLES;
266   delete mGestureManager;
267   delete mPlatformAbstraction;
268   delete mCallbackManager;
269   delete mPerformanceInterface;
270
271   // uninstall it on this thread (main actor thread)
272   Dali::Integration::Log::UninstallLogFunction();
273
274   // Delete environment options if we own it
275   if( mEnvironmentOptionsOwned )
276   {
277     delete mEnvironmentOptions;
278   }
279 }
280
281 void Adaptor::Start()
282 {
283   // it doesn't support restart after stop at this moment
284   // to support restarting, need more testing
285   if( READY != mState )
286   {
287     return;
288   }
289
290   // Start the callback manager
291   mCallbackManager->Start();
292
293   // create event handler
294   mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
295
296   if( mDeferredRotationObserver != NULL )
297   {
298     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
299     mDeferredRotationObserver = NULL;
300   }
301
302   unsigned int dpiHor, dpiVer;
303   dpiHor = dpiVer = 0;
304   Dali::DisplayConnection::GetDpi(dpiHor, dpiVer);
305
306   // tell core about the DPI value
307   mCore->SetDpi(dpiHor, dpiVer);
308
309   // set the DPI value for font rendering
310   FontClient fontClient = FontClient::Get();
311   fontClient.SetDpi( dpiHor, dpiVer );
312
313   // Tell the core the size of the surface just before we start the render-thread
314   PositionSize size = mSurface->GetPositionSize();
315   mCore->SurfaceResized( size.width, size.height );
316
317   // Initialize the thread controller
318   mThreadController->Initialize();
319
320   ProcessCoreEvents(); // Ensure any startup messages are processed.
321
322   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
323   {
324     (*iter)->OnStart();
325   }
326 }
327
328 // Dali::Internal::Adaptor::Adaptor::Pause
329 void Adaptor::Pause()
330 {
331   // Only pause the adaptor if we're actually running.
332   if( RUNNING == mState )
333   {
334     // Inform observers that we are about to be paused.
335     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
336     {
337       (*iter)->OnPause();
338     }
339
340     // Reset the event handler when adaptor paused
341     if( mEventHandler )
342     {
343       mEventHandler->Pause();
344     }
345
346     mThreadController->Pause();
347     mState = PAUSED;
348
349     // Ensure any messages queued during pause callbacks are processed by doing another update.
350     RequestUpdateOnce();
351   }
352 }
353
354 // Dali::Internal::Adaptor::Adaptor::Resume
355 void Adaptor::Resume()
356 {
357   // Only resume the adaptor if we are in the suspended state.
358   if( PAUSED == mState )
359   {
360     mState = RUNNING;
361
362     // Reset the event handler when adaptor resumed
363     if( mEventHandler )
364     {
365       mEventHandler->Resume();
366     }
367
368     // Inform observers that we have resumed.
369     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
370     {
371       (*iter)->OnResume();
372     }
373
374     // trigger processing of events queued up while paused
375     mCore->ProcessEvents();
376
377     // Do at end to ensure our first update/render after resumption includes the processed messages as well
378     mThreadController->Resume();
379   }
380 }
381
382 void Adaptor::Stop()
383 {
384   if( RUNNING == mState ||
385       PAUSED  == mState ||
386       PAUSED_WHILE_HIDDEN == mState )
387   {
388     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
389     {
390       (*iter)->OnStop();
391     }
392
393     mThreadController->Stop();
394
395     // Delete the TTS player
396     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
397     {
398       if(mTtsPlayers[i])
399       {
400         mTtsPlayers[i].Reset();
401       }
402     }
403
404     delete mEventHandler;
405     mEventHandler = NULL;
406
407     delete mNotificationTrigger;
408     mNotificationTrigger = NULL;
409
410     mCallbackManager->Stop();
411
412     mState = STOPPED;
413   }
414 }
415
416 void Adaptor::ContextLost()
417 {
418   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
419 }
420
421 void Adaptor::ContextRegained()
422 {
423   // Inform core, so that texture resources can be reloaded
424   mCore->RecoverFromContextLoss();
425
426   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
427 }
428
429 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
430 {
431   mEventHandler->FeedTouchPoint( point, timeStamp );
432 }
433
434 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
435 {
436   mEventHandler->FeedWheelEvent( wheelEvent );
437 }
438
439 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
440 {
441   mEventHandler->FeedKeyEvent( keyEvent );
442 }
443
444 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
445 {
446   PositionSize positionSize = surface.GetPositionSize();
447
448   // let the core know the surface size has changed
449   mCore->SurfaceResized( positionSize.width, positionSize.height );
450
451   mResizedSignal.Emit( mAdaptor );
452
453   mNativeWindow = nativeWindow;
454   mSurface = &surface;
455
456   // flush the event queue to give the update-render thread chance
457   // to start processing messages for new camera setup etc as soon as possible
458   ProcessCoreEvents();
459
460   // this method blocks until the render thread has completed the replace.
461   mThreadController->ReplaceSurface(mSurface);
462 }
463
464 RenderSurface& Adaptor::GetSurface() const
465 {
466   return *mSurface;
467 }
468
469 void Adaptor::ReleaseSurfaceLock()
470 {
471   mSurface->ReleaseLock();
472 }
473
474 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
475 {
476   if(!mTtsPlayers[mode])
477   {
478     // Create the TTS player when it needed, because it can reduce launching time.
479     mTtsPlayers[mode] = TtsPlayer::New(mode);
480   }
481
482   return mTtsPlayers[mode];
483 }
484
485 bool Adaptor::AddIdle( CallbackBase* callback, bool forceAdd )
486 {
487   bool idleAdded(false);
488
489   // Only add an idle if the Adaptor is actually running
490   if( RUNNING == mState || READY == mState || forceAdd )
491   {
492     idleAdded = mCallbackManager->AddIdleCallback( callback );
493   }
494
495   return idleAdded;
496 }
497
498 void Adaptor::RemoveIdle( CallbackBase* callback )
499 {
500   mCallbackManager->RemoveIdleCallback( callback );
501 }
502
503 Dali::Adaptor& Adaptor::Get()
504 {
505   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
506   return gThreadLocalAdaptor->mAdaptor;
507 }
508
509 bool Adaptor::IsAvailable()
510 {
511   return gThreadLocalAdaptor != NULL;
512 }
513
514 void Adaptor::SceneCreated()
515 {
516   mCore->SceneCreated();
517 }
518
519 Dali::Integration::Core& Adaptor::GetCore()
520 {
521   return *mCore;
522 }
523
524 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
525 {
526   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
527 }
528
529 void Adaptor::SetUseHardwareVSync( bool useHardware )
530 {
531   mVSyncMonitor->SetUseHardwareVSync( useHardware );
532 }
533
534 EglFactory& Adaptor::GetEGLFactory() const
535 {
536   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
537   return *mEglFactory;
538 }
539
540 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
541 {
542   return *mEglFactory;
543 }
544
545 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
546 {
547   DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
548   return *mGLES;
549 }
550
551 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
552 {
553   return *mPlatformAbstraction;
554 }
555
556 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
557 {
558   return *mGLES;
559 }
560
561 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
562 {
563   return *mNotificationTrigger;
564 }
565
566 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
567 {
568   return mTriggerEventFactory;
569 }
570
571 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
572 {
573   return mSocketFactory;
574 }
575
576 RenderSurface* Adaptor::GetRenderSurfaceInterface()
577 {
578   return mSurface;
579 }
580
581 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
582 {
583   return mVSyncMonitor;
584 }
585
586 TraceInterface& Adaptor::GetKernelTraceInterface()
587 {
588   return mKernelTracer;
589 }
590
591 TraceInterface& Adaptor::GetSystemTraceInterface()
592 {
593   return mSystemTracer;
594 }
595
596 PerformanceInterface* Adaptor::GetPerformanceInterface()
597 {
598   return mPerformanceInterface;
599 }
600
601 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
602 {
603   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
604   return *mPlatformAbstraction;
605 }
606
607 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
608 {
609   mDragAndDropDetector = detector;
610
611   if ( mEventHandler )
612   {
613     mEventHandler->SetDragAndDropDetector( detector );
614   }
615 }
616
617 void Adaptor::SetRotationObserver( RotationObserver* observer )
618 {
619   if( mEventHandler )
620   {
621     mEventHandler->SetRotationObserver( observer );
622   }
623   else if( mState == READY )
624   {
625     // Set once event handler exists
626     mDeferredRotationObserver = observer;
627   }
628 }
629
630 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
631 {
632   if(mTtsPlayers[mode])
633   {
634     mTtsPlayers[mode].Reset();
635   }
636 }
637
638 void Adaptor::SetMinimumPinchDistance(float distance)
639 {
640   if( mGestureManager )
641   {
642     mGestureManager->SetMinimumPinchDistance(distance);
643   }
644 }
645
646 Any Adaptor::GetNativeWindowHandle()
647 {
648   return mNativeWindow;
649 }
650
651 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
652 {
653   mUseRemoteSurface = useRemoteSurface;
654 }
655
656 void Adaptor::AddObserver( LifeCycleObserver& observer )
657 {
658   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
659
660   if ( match == mObservers.end() )
661   {
662     mObservers.push_back( &observer );
663   }
664 }
665
666 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
667 {
668   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
669
670   if ( match != mObservers.end() )
671   {
672     mObservers.erase( match );
673   }
674 }
675
676 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
677 {
678   if( mCore )
679   {
680     mCore->QueueEvent(event);
681   }
682 }
683
684 void Adaptor::ProcessCoreEvents()
685 {
686   if( mCore )
687   {
688     if( mPerformanceInterface )
689     {
690       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
691     }
692
693     mCore->ProcessEvents();
694
695     if( mPerformanceInterface )
696     {
697       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
698     }
699   }
700 }
701
702 void Adaptor::RequestUpdate( bool forceUpdate )
703 {
704   switch( mState )
705   {
706     case RUNNING:
707     {
708       mThreadController->RequestUpdate();
709       break;
710     }
711     case PAUSED:
712     case PAUSED_WHILE_HIDDEN:
713     {
714       // When Dali applications are partially visible behind the lock-screen,
715       // the indicator must be updated (therefore allow updates in the PAUSED state)
716       if( forceUpdate )
717       {
718         mThreadController->RequestUpdateOnce();
719       }
720       break;
721     }
722     default:
723     {
724       // Do nothing
725       break;
726     }
727   }
728 }
729
730 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
731 {
732   // Only request a notification if the Adaptor is actually running
733   // and we haven't installed the idle notification
734   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
735   {
736     mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
737   }
738 }
739
740 void Adaptor::OnWindowShown()
741 {
742   if ( PAUSED_WHILE_HIDDEN == mState )
743   {
744     // Adaptor can now be resumed
745     mState = PAUSED;
746
747     Resume();
748
749     // Force a render task
750     RequestUpdateOnce();
751   }
752 }
753
754 void Adaptor::OnWindowHidden()
755 {
756   if ( RUNNING == mState )
757   {
758     Pause();
759
760     // Adaptor cannot be resumed until the window is shown
761     mState = PAUSED_WHILE_HIDDEN;
762   }
763 }
764
765 // Dali::Internal::Adaptor::Adaptor::OnDamaged
766 void Adaptor::OnDamaged( const DamageArea& area )
767 {
768   // This is needed for the case where Dali window is partially obscured
769   RequestUpdate( false );
770 }
771
772 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
773 {
774   // let the core know the surface size has changed
775   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
776
777   mResizedSignal.Emit( mAdaptor );
778 }
779
780 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
781 {
782   // flush the event queue to give the update-render thread chance
783   // to start processing messages for new camera setup etc as soon as possible
784   ProcessCoreEvents();
785
786   // this method blocks until the render thread has completed the resizing.
787   mThreadController->ResizeSurface();
788 }
789
790 void Adaptor::NotifySceneCreated()
791 {
792   GetCore().SceneCreated();
793
794   // Start thread controller after the scene has been created
795   mThreadController->Start();
796
797   // process after surface is created (registering to remote surface provider if required)
798   SurfaceInitialized();
799
800   mState = RUNNING;
801 }
802
803 void Adaptor::NotifyLanguageChanged()
804 {
805   mLanguageChangedSignal.Emit( mAdaptor );
806 }
807
808 void Adaptor::RenderOnce()
809 {
810   RequestUpdateOnce();
811 }
812
813 void Adaptor::RequestUpdateOnce()
814 {
815   if( mThreadController )
816   {
817     mThreadController->RequestUpdateOnce();
818   }
819 }
820
821 void Adaptor::IndicatorSizeChanged(int height)
822 {
823   // let the core know the indicator height is changed
824   mCore->SetTopMargin(height);
825 }
826
827 void Adaptor::ProcessCoreEventsFromIdle()
828 {
829   ProcessCoreEvents();
830
831   // the idle handle automatically un-installs itself
832   mNotificationOnIdleInstalled = false;
833 }
834
835 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
836 : mResizedSignal(),
837   mLanguageChangedSignal(),
838   mAdaptor( adaptor ),
839   mState( READY ),
840   mCore( NULL ),
841   mThreadController( NULL ),
842   mVSyncMonitor( NULL ),
843   mGLES( NULL ),
844   mGlSync( NULL ),
845   mEglFactory( NULL ),
846   mNativeWindow( nativeWindow ),
847   mSurface( surface ),
848   mPlatformAbstraction( NULL ),
849   mEventHandler( NULL ),
850   mCallbackManager( NULL ),
851   mNotificationOnIdleInstalled( false ),
852   mNotificationTrigger( NULL ),
853   mGestureManager( NULL ),
854   mDaliFeedbackPlugin(),
855   mFeedbackController( NULL ),
856   mTtsPlayers(),
857   mObservers(),
858   mDragAndDropDetector(),
859   mDeferredRotationObserver( NULL ),
860   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
861   mPerformanceInterface( NULL ),
862   mKernelTracer(),
863   mSystemTracer(),
864   mTriggerEventFactory(),
865   mObjectProfiler( NULL ),
866   mSocketFactory(),
867   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
868   mUseRemoteSurface( false )
869 {
870   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
871   gThreadLocalAdaptor = this;
872 }
873
874 // Stereoscopy
875
876 void Adaptor::SetViewMode( ViewMode viewMode )
877 {
878   mSurface->SetViewMode( viewMode );
879   mCore->SetViewMode( viewMode );
880 }
881
882 ViewMode Adaptor::GetViewMode() const
883 {
884   return mCore->GetViewMode();
885 }
886
887 void Adaptor::SetStereoBase( float stereoBase )
888 {
889   mCore->SetStereoBase( stereoBase );
890 }
891
892 float Adaptor::GetStereoBase() const
893 {
894   return mCore->GetStereoBase();
895 }
896
897 void Adaptor::SetRootLayoutDirection( std::string locale )
898 {
899   Dali::Stage stage = Dali::Stage::GetCurrent();
900
901   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
902                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
903 }
904
905 } // namespace Adaptor
906
907 } // namespace Internal
908
909 } // namespace Dali