Removed GL and GL Sync implementations
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2018 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 <dali/internal/adaptor/common/adaptor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/stage.h>
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/devel-api/actors/actor-devel.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/integration-api/core.h>
27 #include <dali/integration-api/profiling.h>
28 #include <dali/integration-api/input-options.h>
29 #include <dali/integration-api/events/touch-event-integ.h>
30 #include <dali/integration-api/graphics/graphics.h>
31
32 // INTERNAL INCLUDES
33 #include <dali/public-api/dali-adaptor-common.h>
34 #include <dali/internal/system/common/thread-controller.h>
35 #include <dali/internal/system/common/performance-interface-factory.h>
36 #include <dali/internal/adaptor/common/lifecycle-observer.h>
37
38 #include <dali/devel-api/text-abstraction/font-client.h>
39
40 #include <dali/internal/system/common/callback-manager.h>
41 #include <dali/internal/accessibility/common/tts-player-impl.h>
42 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
43 #include <dali/internal/input/common/gesture-manager.h>
44 #include <dali/internal/window-system/common/event-handler.h>
45 #include <dali/internal/graphics/common/egl-image-extensions.h>
46 #include <dali/internal/graphics/gles20/egl-factory.h>
47 #include <dali/internal/graphics/vulkan/x11/vk-surface-xlib2xcb.h>
48 #include <dali/internal/clipboard/common/clipboard-impl.h>
49 #include <dali/internal/graphics/common/vsync-monitor.h>
50 #include <dali/internal/system/common/object-profiler.h>
51 #include <dali/internal/window-system/common/display-connection.h>
52 #include <dali/internal/window-system/common/window-impl.h>
53 #include <dali/internal/window-system/common/window-render-surface.h>
54 #include <dali/internal/graphics/vulkan/x11/vk-surface-xlib2xcb.h>
55
56 #include <dali/internal/system/common/logging.h>
57 #include <dali/devel-api/adaptor-framework/image-loading.h>
58
59 #include <dali/internal/system/common/locale-utils.h>
60
61 using Dali::TextAbstraction::FontClient;
62
63 namespace Dali
64 {
65
66 namespace Internal
67 {
68
69 namespace Adaptor
70 {
71
72 namespace
73 {
74 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
75 } // unnamed namespace
76
77 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
78 {
79   Dali::Adaptor* adaptor = new Dali::Adaptor;
80   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
81   adaptor->mImpl = impl;
82
83   impl->Initialize(configuration);
84
85   return adaptor;
86 }
87
88 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
89 {
90   Any winId = window.GetNativeHandle();
91
92   Window& windowImpl = Dali::GetImplementation(window);
93   Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
94   windowImpl.SetAdaptor(*adaptor);
95   return adaptor;
96 }
97
98 void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration )
99 {
100   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
101   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
102   mEnvironmentOptions->SetLogFunction( logFunction );
103   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
104
105   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
106
107   std::string path;
108   GetDataStoragePath( path );
109   mPlatformAbstraction->SetDataStoragePath( path );
110
111   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
112   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
113   {
114     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
115   }
116   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
117   // files automatically.
118
119   if( mEnvironmentOptions->PerformanceServerRequired() )
120   {
121     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
122   }
123
124   mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
125   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
126
127   mCallbackManager = CallbackManager::New();
128
129   PositionSize size = mSurface->GetPositionSize();
130
131   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
132
133   const Integration::DepthBufferAvailable depthBufferAvailable = static_cast< Integration::DepthBufferAvailable >( mEnvironmentOptions->DepthBufferRequired() );
134   const Integration::StencilBufferAvailable stencilBufferAvailable = static_cast< Integration::StencilBufferAvailable >( mEnvironmentOptions->StencilBufferRequired() );
135
136   mEglFactory = new EglFactory( mEnvironmentOptions->GetMultiSamplingLevel(), depthBufferAvailable, stencilBufferAvailable );
137
138   // @todo: add somewhere MakeUnique to make it cleaner
139   mGraphics = std::unique_ptr<Dali::Integration::Graphics::Graphics>(
140     new Dali::Integration::Graphics::Graphics()
141   );
142
143   // @todo: surface shouldn't really be create here :((((
144   auto xlibSurface = std::unique_ptr<Dali::Graphics::Vulkan::VkSurfaceXlib2Xcb>(
145     new Dali::Graphics::Vulkan::VkSurfaceXlib2Xcb( *mSurface )
146   );
147
148   mGraphics->Create( std::move(xlibSurface) );
149
150   mCore = Integration::Core::New( *this,
151                                   *mPlatformAbstraction,
152                                   *mGraphics,
153                                   *mGestureManager,
154                                   dataRetentionPolicy ,
155                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
156                                   depthBufferAvailable,
157                                   stencilBufferAvailable );
158
159   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
160   if( 0u < timeInterval )
161   {
162     mObjectProfiler = new ObjectProfiler( timeInterval );
163   }
164
165   mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
166
167   mVSyncMonitor = new VSyncMonitor;
168
169   mThreadController = new ThreadController( *this, *mEnvironmentOptions );
170
171   // Should be called after Core creation
172   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
173   {
174     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
175   }
176   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
177   {
178     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
179   }
180   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
181   {
182     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
183   }
184   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
185   {
186     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
187   }
188   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
189   {
190     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
191   }
192   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
193   {
194     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
195   }
196   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
197   {
198     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
199   }
200   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
201   {
202     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
203   }
204   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
205   {
206     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
207   }
208   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
209   {
210     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
211   }
212   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
213   {
214     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
215   }
216   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
217   {
218     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
219   }
220   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
221   {
222     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
223   }
224   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
225   {
226     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
227   }
228   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
229   {
230     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
231   }
232   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
233   {
234     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
235   }
236
237   // Set max texture size
238   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
239   {
240     Dali::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
241   }
242
243   SetupSystemInformation();
244 }
245
246 Adaptor::~Adaptor()
247 {
248   // Ensure stop status
249   Stop();
250
251   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
252   gThreadLocalAdaptor = NULL;
253
254   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
255   {
256     (*iter)->OnDestroy();
257   }
258
259   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
260   delete mVSyncMonitor;
261   delete mEventHandler;
262   delete mObjectProfiler;
263
264   delete mCore;
265   delete mEglFactory;
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   mSurface->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::FeedTouchPoint( TouchPoint& point, int timeStamp )
417 {
418   mEventHandler->FeedTouchPoint( point, timeStamp );
419 }
420
421 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
422 {
423   mEventHandler->FeedWheelEvent( wheelEvent );
424 }
425
426 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
427 {
428   mEventHandler->FeedKeyEvent( keyEvent );
429 }
430
431 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
432 {
433   PositionSize positionSize = surface.GetPositionSize();
434
435   // let the core know the surface size has changed
436   mCore->SurfaceResized( positionSize.width, positionSize.height );
437
438   mResizedSignal.Emit( mAdaptor );
439
440   mNativeWindow = nativeWindow;
441   mSurface = &surface;
442
443   // flush the event queue to give the update-render thread chance
444   // to start processing messages for new camera setup etc as soon as possible
445   ProcessCoreEvents();
446
447   // this method blocks until the render thread has completed the replace.
448   mThreadController->ReplaceSurface(mSurface);
449 }
450
451 RenderSurface& Adaptor::GetSurface() const
452 {
453   return *mSurface;
454 }
455
456 void Adaptor::ReleaseSurfaceLock()
457 {
458   mSurface->ReleaseLock();
459 }
460
461 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
462 {
463   if(!mTtsPlayers[mode])
464   {
465     // Create the TTS player when it needed, because it can reduce launching time.
466     mTtsPlayers[mode] = TtsPlayer::New(mode);
467   }
468
469   return mTtsPlayers[mode];
470 }
471
472 bool Adaptor::AddIdle( CallbackBase* callback, bool forceAdd )
473 {
474   bool idleAdded(false);
475
476   // Only add an idle if the Adaptor is actually running
477   if( RUNNING == mState || READY == mState || forceAdd )
478   {
479     idleAdded = mCallbackManager->AddIdleCallback( callback );
480   }
481
482   return idleAdded;
483 }
484
485 void Adaptor::RemoveIdle( CallbackBase* callback )
486 {
487   mCallbackManager->RemoveIdleCallback( callback );
488 }
489
490 Dali::Adaptor& Adaptor::Get()
491 {
492   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
493   return gThreadLocalAdaptor->mAdaptor;
494 }
495
496 bool Adaptor::IsAvailable()
497 {
498   return gThreadLocalAdaptor != NULL;
499 }
500
501 void Adaptor::SceneCreated()
502 {
503   mCore->SceneCreated();
504 }
505
506 Dali::Integration::Core& Adaptor::GetCore()
507 {
508   return *mCore;
509 }
510
511 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
512 {
513   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
514 }
515
516 void Adaptor::SetUseHardwareVSync( bool useHardware )
517 {
518   mVSyncMonitor->SetUseHardwareVSync( useHardware );
519 }
520
521 EglFactory& Adaptor::GetEGLFactory() const
522 {
523   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
524   return *mEglFactory;
525 }
526
527 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
528 {
529   return *mEglFactory;
530 }
531
532 Integration::Graphics::Graphics& Adaptor::GetGraphics() const
533 {
534   return *mGraphics;
535 }
536
537 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
538 {
539   return *mPlatformAbstraction;
540 }
541
542 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
543 {
544   return *mNotificationTrigger;
545 }
546
547 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
548 {
549   return mTriggerEventFactory;
550 }
551
552 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
553 {
554   return mSocketFactory;
555 }
556
557 RenderSurface* Adaptor::GetRenderSurfaceInterface()
558 {
559   return mSurface;
560 }
561
562 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
563 {
564   return mVSyncMonitor;
565 }
566
567 TraceInterface& Adaptor::GetKernelTraceInterface()
568 {
569   return mKernelTracer;
570 }
571
572 TraceInterface& Adaptor::GetSystemTraceInterface()
573 {
574   return mSystemTracer;
575 }
576
577 PerformanceInterface* Adaptor::GetPerformanceInterface()
578 {
579   return mPerformanceInterface;
580 }
581
582 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
583 {
584   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
585   return *mPlatformAbstraction;
586 }
587
588 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
589 {
590   mDragAndDropDetector = detector;
591
592   if ( mEventHandler )
593   {
594     mEventHandler->SetDragAndDropDetector( detector );
595   }
596 }
597
598 void Adaptor::SetRotationObserver( RotationObserver* observer )
599 {
600   if( mEventHandler )
601   {
602     mEventHandler->SetRotationObserver( observer );
603   }
604   else if( mState == READY )
605   {
606     // Set once event handler exists
607     mDeferredRotationObserver = observer;
608   }
609 }
610
611 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
612 {
613   if(mTtsPlayers[mode])
614   {
615     mTtsPlayers[mode].Reset();
616   }
617 }
618
619 void Adaptor::SetMinimumPinchDistance(float distance)
620 {
621   if( mGestureManager )
622   {
623     mGestureManager->SetMinimumPinchDistance(distance);
624   }
625 }
626
627 Any Adaptor::GetNativeWindowHandle()
628 {
629   return mNativeWindow;
630 }
631
632 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
633 {
634   mUseRemoteSurface = useRemoteSurface;
635 }
636
637 void Adaptor::AddObserver( LifeCycleObserver& observer )
638 {
639   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
640
641   if ( match == mObservers.end() )
642   {
643     mObservers.push_back( &observer );
644   }
645 }
646
647 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
648 {
649   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
650
651   if ( match != mObservers.end() )
652   {
653     mObservers.erase( match );
654   }
655 }
656
657 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
658 {
659   if( mCore )
660   {
661     mCore->QueueEvent(event);
662   }
663 }
664
665 void Adaptor::ProcessCoreEvents()
666 {
667   if( mCore )
668   {
669     if( mPerformanceInterface )
670     {
671       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
672     }
673
674     mCore->ProcessEvents();
675
676     if( mPerformanceInterface )
677     {
678       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
679     }
680   }
681 }
682
683 void Adaptor::RequestUpdate( bool forceUpdate )
684 {
685   switch( mState )
686   {
687     case RUNNING:
688     {
689       mThreadController->RequestUpdate();
690       break;
691     }
692     case PAUSED:
693     case PAUSED_WHILE_HIDDEN:
694     {
695       // When Dali applications are partially visible behind the lock-screen,
696       // the indicator must be updated (therefore allow updates in the PAUSED state)
697       if( forceUpdate )
698       {
699         mThreadController->RequestUpdateOnce();
700       }
701       break;
702     }
703     default:
704     {
705       // Do nothing
706       break;
707     }
708   }
709 }
710
711 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
712 {
713   // Only request a notification if the Adaptor is actually running
714   // and we haven't installed the idle notification
715   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
716   {
717     mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
718   }
719 }
720
721 void Adaptor::OnWindowShown()
722 {
723   if ( PAUSED_WHILE_HIDDEN == mState )
724   {
725     // Adaptor can now be resumed
726     mState = PAUSED;
727
728     Resume();
729
730     // Force a render task
731     RequestUpdateOnce();
732   }
733 }
734
735 void Adaptor::OnWindowHidden()
736 {
737   if ( RUNNING == mState )
738   {
739     Pause();
740
741     // Adaptor cannot be resumed until the window is shown
742     mState = PAUSED_WHILE_HIDDEN;
743   }
744 }
745
746 // Dali::Internal::Adaptor::Adaptor::OnDamaged
747 void Adaptor::OnDamaged( const DamageArea& area )
748 {
749   // This is needed for the case where Dali window is partially obscured
750   RequestUpdate( false );
751 }
752
753 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
754 {
755   // let the core know the surface size has changed
756   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
757
758   mResizedSignal.Emit( mAdaptor );
759 }
760
761 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
762 {
763   // flush the event queue to give the update-render thread chance
764   // to start processing messages for new camera setup etc as soon as possible
765   ProcessCoreEvents();
766
767   // this method blocks until the render thread has completed the resizing.
768   mThreadController->ResizeSurface();
769 }
770
771 void Adaptor::NotifySceneCreated()
772 {
773   GetCore().SceneCreated();
774
775   // Start thread controller after the scene has been created
776   mThreadController->Start();
777
778   // process after surface is created (registering to remote surface provider if required)
779   SurfaceInitialized();
780
781   mState = RUNNING;
782 }
783
784 void Adaptor::NotifyLanguageChanged()
785 {
786   mLanguageChangedSignal.Emit( mAdaptor );
787 }
788
789 void Adaptor::RenderOnce()
790 {
791   RequestUpdateOnce();
792 }
793
794 const LogFactoryInterface& Adaptor::GetLogFactory()
795 {
796   return *mEnvironmentOptions;
797 }
798
799 void Adaptor::RequestUpdateOnce()
800 {
801   if( mThreadController )
802   {
803     mThreadController->RequestUpdateOnce();
804   }
805 }
806
807 void Adaptor::IndicatorSizeChanged(int height)
808 {
809   // let the core know the indicator height is changed
810   mCore->SetTopMargin(height);
811 }
812
813 void Adaptor::ProcessCoreEventsFromIdle()
814 {
815   ProcessCoreEvents();
816
817   // the idle handle automatically un-installs itself
818   mNotificationOnIdleInstalled = false;
819 }
820
821 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
822 : mResizedSignal(),
823   mLanguageChangedSignal(),
824   mAdaptor( adaptor ),
825   mState( READY ),
826   mCore( NULL ),
827   mThreadController( NULL ),
828   mVSyncMonitor( NULL ),
829   mEglFactory( NULL ),
830   mNativeWindow( nativeWindow ),
831   mSurface( surface ),
832   mPlatformAbstraction( NULL ),
833   mEventHandler( NULL ),
834   mCallbackManager( NULL ),
835   mNotificationOnIdleInstalled( false ),
836   mNotificationTrigger( NULL ),
837   mGestureManager( NULL ),
838   mDaliFeedbackPlugin(),
839   mFeedbackController( NULL ),
840   mTtsPlayers(),
841   mObservers(),
842   mDragAndDropDetector(),
843   mDeferredRotationObserver( NULL ),
844   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
845   mPerformanceInterface( NULL ),
846   mKernelTracer(),
847   mSystemTracer(),
848   mTriggerEventFactory(),
849   mObjectProfiler( NULL ),
850   mSocketFactory(),
851   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
852   mUseRemoteSurface( false )
853 {
854   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
855   gThreadLocalAdaptor = this;
856 }
857
858 // Stereoscopy
859
860 void Adaptor::SetViewMode( ViewMode viewMode )
861 {
862   mSurface->SetViewMode( viewMode );
863   mCore->SetViewMode( viewMode );
864 }
865
866 ViewMode Adaptor::GetViewMode() const
867 {
868   return mCore->GetViewMode();
869 }
870
871 void Adaptor::SetStereoBase( float stereoBase )
872 {
873   mCore->SetStereoBase( stereoBase );
874 }
875
876 float Adaptor::GetStereoBase() const
877 {
878   return mCore->GetStereoBase();
879 }
880
881 void Adaptor::SetRootLayoutDirection( std::string locale )
882 {
883   Dali::Stage stage = Dali::Stage::GetCurrent();
884
885   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
886                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
887 }
888
889 } // namespace Adaptor
890
891 } // namespace Internal
892
893 } // namespace Dali