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