3c03707d5fdb3ce6d3d20fc42cfc89c7605a28fd
[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 )
781 {
782   // let the core know the surface size has changed
783   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
784
785   mResizedSignal.Emit( mAdaptor );
786 }
787
788 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
789 {
790   // flush the event queue to give the update-render thread chance
791   // to start processing messages for new camera setup etc as soon as possible
792   ProcessCoreEvents();
793
794   mThreadController->ResizeSurface();
795 }
796
797 void Adaptor::NotifySceneCreated()
798 {
799   GetCore().SceneCreated();
800
801   // Start thread controller after the scene has been created
802   mThreadController->Start();
803
804   // process after surface is created (registering to remote surface provider if required)
805   SurfaceInitialized();
806
807   mState = RUNNING;
808 }
809
810 void Adaptor::NotifyLanguageChanged()
811 {
812   mLanguageChangedSignal.Emit( mAdaptor );
813 }
814
815 void Adaptor::RenderOnce()
816 {
817   RequestUpdateOnce();
818 }
819
820 void Adaptor::RequestUpdateOnce()
821 {
822   if( mThreadController )
823   {
824     mThreadController->RequestUpdateOnce();
825   }
826 }
827
828 void Adaptor::IndicatorSizeChanged(int height)
829 {
830   // let the core know the indicator height is changed
831   mCore->SetTopMargin(height);
832 }
833
834 void Adaptor::ProcessCoreEventsFromIdle()
835 {
836   ProcessCoreEvents();
837
838   // the idle handle automatically un-installs itself
839   mNotificationOnIdleInstalled = false;
840 }
841
842 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
843 : mResizedSignal(),
844   mLanguageChangedSignal(),
845   mAdaptor( adaptor ),
846   mState( READY ),
847   mCore( NULL ),
848   mThreadController( NULL ),
849   mVSyncMonitor( NULL ),
850   mGLES( NULL ),
851   mGlSync( NULL ),
852   mEglFactory( NULL ),
853   mNativeWindow( nativeWindow ),
854   mSurface( surface ),
855   mPlatformAbstraction( NULL ),
856   mEventHandler( NULL ),
857   mCallbackManager( NULL ),
858   mNotificationOnIdleInstalled( false ),
859   mNotificationTrigger( NULL ),
860   mGestureManager( NULL ),
861   mDaliFeedbackPlugin(),
862   mFeedbackController( NULL ),
863   mTtsPlayers(),
864   mObservers(),
865   mDragAndDropDetector(),
866   mDeferredRotationObserver( NULL ),
867   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
868   mPerformanceInterface( NULL ),
869   mKernelTracer(),
870   mSystemTracer(),
871   mTriggerEventFactory(),
872   mObjectProfiler( NULL ),
873   mSocketFactory(),
874   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
875   mUseRemoteSurface( false )
876 {
877   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
878   gThreadLocalAdaptor = this;
879 }
880
881 // Stereoscopy
882
883 void Adaptor::SetViewMode( ViewMode viewMode )
884 {
885   mSurface->SetViewMode( viewMode );
886   mCore->SetViewMode( viewMode );
887 }
888
889 ViewMode Adaptor::GetViewMode() const
890 {
891   return mCore->GetViewMode();
892 }
893
894 void Adaptor::SetStereoBase( float stereoBase )
895 {
896   mCore->SetStereoBase( stereoBase );
897 }
898
899 float Adaptor::GetStereoBase() const
900 {
901   return mCore->GetStereoBase();
902 }
903
904 void Adaptor::SetRootLayoutDirection( std::string locale )
905 {
906   Dali::Stage stage = Dali::Stage::GetCurrent();
907
908   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
909                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
910 }
911
912 } // namespace Adaptor
913
914 } // namespace Internal
915
916 } // namespace Dali