67e759f26cc86480c91a2861dff1791e59ecee15
[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   DALI_LOG_RELEASE_INFO( "Adaptor::Pause: mState [%d]\n", mState );
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     // Ensure any messages queued during pause callbacks are processed by doing another update.
352     RequestUpdateOnce();
353   }
354 }
355
356 // Dali::Internal::Adaptor::Adaptor::Resume
357 void Adaptor::Resume()
358 {
359   DALI_LOG_RELEASE_INFO( "Adaptor::Resume: mState [%d]\n", mState );
360
361   // Only resume the adaptor if we are in the suspended state.
362   if( PAUSED == mState )
363   {
364     mState = RUNNING;
365
366     // Reset the event handler when adaptor resumed
367     if( mEventHandler )
368     {
369       mEventHandler->Resume();
370     }
371
372     // Inform observers that we have resumed.
373     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
374     {
375       (*iter)->OnResume();
376     }
377
378     // trigger processing of events queued up while paused
379     mCore->ProcessEvents();
380
381     // Do at end to ensure our first update/render after resumption includes the processed messages as well
382     mThreadController->Resume();
383   }
384 }
385
386 void Adaptor::Stop()
387 {
388   if( RUNNING == mState ||
389       PAUSED  == mState ||
390       PAUSED_WHILE_HIDDEN == mState )
391   {
392     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
393     {
394       (*iter)->OnStop();
395     }
396
397     mThreadController->Stop();
398
399     // Delete the TTS player
400     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
401     {
402       if(mTtsPlayers[i])
403       {
404         mTtsPlayers[i].Reset();
405       }
406     }
407
408     delete mEventHandler;
409     mEventHandler = NULL;
410
411     delete mNotificationTrigger;
412     mNotificationTrigger = NULL;
413
414     mCallbackManager->Stop();
415
416     mState = STOPPED;
417   }
418 }
419
420 void Adaptor::ContextLost()
421 {
422   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
423 }
424
425 void Adaptor::ContextRegained()
426 {
427   // Inform core, so that texture resources can be reloaded
428   mCore->RecoverFromContextLoss();
429
430   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
431 }
432
433 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
434 {
435   mEventHandler->FeedTouchPoint( point, timeStamp );
436 }
437
438 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
439 {
440   mEventHandler->FeedWheelEvent( wheelEvent );
441 }
442
443 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
444 {
445   mEventHandler->FeedKeyEvent( keyEvent );
446 }
447
448 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
449 {
450   PositionSize positionSize = surface.GetPositionSize();
451
452   // let the core know the surface size has changed
453   mCore->SurfaceResized( positionSize.width, positionSize.height );
454
455   mResizedSignal.Emit( mAdaptor );
456
457   mNativeWindow = nativeWindow;
458   mSurface = &surface;
459
460   // flush the event queue to give the update-render thread chance
461   // to start processing messages for new camera setup etc as soon as possible
462   ProcessCoreEvents();
463
464   // this method blocks until the render thread has completed the replace.
465   mThreadController->ReplaceSurface(mSurface);
466 }
467
468 RenderSurface& Adaptor::GetSurface() const
469 {
470   return *mSurface;
471 }
472
473 void Adaptor::ReleaseSurfaceLock()
474 {
475   mSurface->ReleaseLock();
476 }
477
478 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
479 {
480   if(!mTtsPlayers[mode])
481   {
482     // Create the TTS player when it needed, because it can reduce launching time.
483     mTtsPlayers[mode] = TtsPlayer::New(mode);
484   }
485
486   return mTtsPlayers[mode];
487 }
488
489 bool Adaptor::AddIdle( CallbackBase* callback, bool forceAdd )
490 {
491   bool idleAdded(false);
492
493   // Only add an idle if the Adaptor is actually running
494   if( RUNNING == mState || READY == mState || forceAdd )
495   {
496     idleAdded = mCallbackManager->AddIdleCallback( callback );
497   }
498
499   return idleAdded;
500 }
501
502 void Adaptor::RemoveIdle( CallbackBase* callback )
503 {
504   mCallbackManager->RemoveIdleCallback( callback );
505 }
506
507 Dali::Adaptor& Adaptor::Get()
508 {
509   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
510   return gThreadLocalAdaptor->mAdaptor;
511 }
512
513 bool Adaptor::IsAvailable()
514 {
515   return gThreadLocalAdaptor != NULL;
516 }
517
518 void Adaptor::SceneCreated()
519 {
520   mCore->SceneCreated();
521 }
522
523 Dali::Integration::Core& Adaptor::GetCore()
524 {
525   return *mCore;
526 }
527
528 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
529 {
530   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
531 }
532
533 void Adaptor::SetUseHardwareVSync( bool useHardware )
534 {
535   mVSyncMonitor->SetUseHardwareVSync( useHardware );
536 }
537
538 EglFactory& Adaptor::GetEGLFactory() const
539 {
540   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
541   return *mEglFactory;
542 }
543
544 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
545 {
546   return *mEglFactory;
547 }
548
549 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
550 {
551   DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
552   return *mGLES;
553 }
554
555 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
556 {
557   return *mPlatformAbstraction;
558 }
559
560 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
561 {
562   return *mGLES;
563 }
564
565 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
566 {
567   return *mNotificationTrigger;
568 }
569
570 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
571 {
572   return mTriggerEventFactory;
573 }
574
575 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
576 {
577   return mSocketFactory;
578 }
579
580 RenderSurface* Adaptor::GetRenderSurfaceInterface()
581 {
582   return mSurface;
583 }
584
585 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
586 {
587   return mVSyncMonitor;
588 }
589
590 TraceInterface& Adaptor::GetKernelTraceInterface()
591 {
592   return mKernelTracer;
593 }
594
595 TraceInterface& Adaptor::GetSystemTraceInterface()
596 {
597   return mSystemTracer;
598 }
599
600 PerformanceInterface* Adaptor::GetPerformanceInterface()
601 {
602   return mPerformanceInterface;
603 }
604
605 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
606 {
607   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
608   return *mPlatformAbstraction;
609 }
610
611 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
612 {
613   mDragAndDropDetector = detector;
614
615   if ( mEventHandler )
616   {
617     mEventHandler->SetDragAndDropDetector( detector );
618   }
619 }
620
621 void Adaptor::SetRotationObserver( RotationObserver* observer )
622 {
623   if( mEventHandler )
624   {
625     mEventHandler->SetRotationObserver( observer );
626   }
627   else if( mState == READY )
628   {
629     // Set once event handler exists
630     mDeferredRotationObserver = observer;
631   }
632 }
633
634 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
635 {
636   if(mTtsPlayers[mode])
637   {
638     mTtsPlayers[mode].Reset();
639   }
640 }
641
642 void Adaptor::SetMinimumPinchDistance(float distance)
643 {
644   if( mGestureManager )
645   {
646     mGestureManager->SetMinimumPinchDistance(distance);
647   }
648 }
649
650 Any Adaptor::GetNativeWindowHandle()
651 {
652   return mNativeWindow;
653 }
654
655 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
656 {
657   mUseRemoteSurface = useRemoteSurface;
658 }
659
660 void Adaptor::AddObserver( LifeCycleObserver& observer )
661 {
662   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
663
664   if ( match == mObservers.end() )
665   {
666     mObservers.push_back( &observer );
667   }
668 }
669
670 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
671 {
672   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
673
674   if ( match != mObservers.end() )
675   {
676     mObservers.erase( match );
677   }
678 }
679
680 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
681 {
682   if( mCore )
683   {
684     mCore->QueueEvent(event);
685   }
686 }
687
688 void Adaptor::ProcessCoreEvents()
689 {
690   if( mCore )
691   {
692     if( mPerformanceInterface )
693     {
694       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
695     }
696
697     mCore->ProcessEvents();
698
699     if( mPerformanceInterface )
700     {
701       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
702     }
703   }
704 }
705
706 void Adaptor::RequestUpdate( bool forceUpdate )
707 {
708   switch( mState )
709   {
710     case RUNNING:
711     {
712       mThreadController->RequestUpdate();
713       break;
714     }
715     case PAUSED:
716     case PAUSED_WHILE_HIDDEN:
717     {
718       // When Dali applications are partially visible behind the lock-screen,
719       // the indicator must be updated (therefore allow updates in the PAUSED state)
720       if( forceUpdate )
721       {
722         mThreadController->RequestUpdateOnce();
723       }
724       break;
725     }
726     default:
727     {
728       // Do nothing
729       break;
730     }
731   }
732 }
733
734 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
735 {
736   // Only request a notification if the Adaptor is actually running
737   // and we haven't installed the idle notification
738   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
739   {
740     mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
741   }
742 }
743
744 void Adaptor::OnWindowShown()
745 {
746   DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: mState [%d]\n", mState );
747
748   if ( PAUSED_WHILE_HIDDEN == mState )
749   {
750     // Adaptor can now be resumed
751     mState = PAUSED;
752
753     Resume();
754
755     // Force a render task
756     RequestUpdateOnce();
757   }
758 }
759
760 void Adaptor::OnWindowHidden()
761 {
762   DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: mState [%d]\n", mState );
763
764   if ( RUNNING == mState )
765   {
766     Pause();
767
768     // Adaptor cannot be resumed until the window is shown
769     mState = PAUSED_WHILE_HIDDEN;
770   }
771 }
772
773 // Dali::Internal::Adaptor::Adaptor::OnDamaged
774 void Adaptor::OnDamaged( const DamageArea& area )
775 {
776   // This is needed for the case where Dali window is partially obscured
777   RequestUpdate( false );
778 }
779
780 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize, int orientation )
781 {
782   // let the core know the surface size and orientation has changed
783   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight(), orientation );
784
785   mResizedSignal.Emit( mAdaptor );
786 }
787
788 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
789 {
790   // let the core know the surface size has changed
791   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
792
793   mResizedSignal.Emit( mAdaptor );
794 }
795
796 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
797 {
798   // flush the event queue to give the update-render thread chance
799   // to start processing messages for new camera setup etc as soon as possible
800   ProcessCoreEvents();
801
802   mThreadController->ResizeSurface();
803 }
804
805 void Adaptor::NotifySceneCreated()
806 {
807   GetCore().SceneCreated();
808
809   // Start thread controller after the scene has been created
810   mThreadController->Start();
811
812   // process after surface is created (registering to remote surface provider if required)
813   SurfaceInitialized();
814
815   mState = RUNNING;
816 }
817
818 void Adaptor::NotifyLanguageChanged()
819 {
820   mLanguageChangedSignal.Emit( mAdaptor );
821 }
822
823 void Adaptor::RenderOnce()
824 {
825   RequestUpdateOnce();
826 }
827
828 void Adaptor::RequestUpdateOnce()
829 {
830   if( mThreadController )
831   {
832     mThreadController->RequestUpdateOnce();
833   }
834 }
835
836 void Adaptor::IndicatorSizeChanged(int height)
837 {
838   // let the core know the indicator height is changed
839   mCore->SetTopMargin(height);
840 }
841
842 void Adaptor::ProcessCoreEventsFromIdle()
843 {
844   ProcessCoreEvents();
845
846   // the idle handle automatically un-installs itself
847   mNotificationOnIdleInstalled = false;
848 }
849
850 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
851 : mResizedSignal(),
852   mLanguageChangedSignal(),
853   mAdaptor( adaptor ),
854   mState( READY ),
855   mCore( NULL ),
856   mThreadController( NULL ),
857   mVSyncMonitor( NULL ),
858   mGLES( NULL ),
859   mGlSync( NULL ),
860   mEglFactory( NULL ),
861   mNativeWindow( nativeWindow ),
862   mSurface( surface ),
863   mPlatformAbstraction( NULL ),
864   mEventHandler( NULL ),
865   mCallbackManager( NULL ),
866   mNotificationOnIdleInstalled( false ),
867   mNotificationTrigger( NULL ),
868   mGestureManager( NULL ),
869   mDaliFeedbackPlugin(),
870   mFeedbackController( NULL ),
871   mTtsPlayers(),
872   mObservers(),
873   mDragAndDropDetector(),
874   mDeferredRotationObserver( NULL ),
875   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
876   mPerformanceInterface( NULL ),
877   mKernelTracer(),
878   mSystemTracer(),
879   mTriggerEventFactory(),
880   mObjectProfiler( NULL ),
881   mSocketFactory(),
882   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
883   mUseRemoteSurface( false )
884 {
885   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
886   gThreadLocalAdaptor = this;
887 }
888
889 // Stereoscopy
890
891 void Adaptor::SetViewMode( ViewMode viewMode )
892 {
893   mSurface->SetViewMode( viewMode );
894   mCore->SetViewMode( viewMode );
895 }
896
897 ViewMode Adaptor::GetViewMode() const
898 {
899   return mCore->GetViewMode();
900 }
901
902 void Adaptor::SetStereoBase( float stereoBase )
903 {
904   mCore->SetStereoBase( stereoBase );
905 }
906
907 float Adaptor::GetStereoBase() const
908 {
909   return mCore->GetStereoBase();
910 }
911
912 void Adaptor::SetRootLayoutDirection( std::string locale )
913 {
914   Dali::Stage stage = Dali::Stage::GetCurrent();
915
916   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
917                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
918 }
919
920 } // namespace Adaptor
921
922 } // namespace Internal
923
924 } // namespace Dali