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