[Tizen] ecore-wl2: applying ecore-wl2
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / 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 <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   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 #ifdef ECORE_WL2
305   Dali::DisplayConnection::GetDpi( mNativeWindow, dpiHor, dpiVer );
306 #else
307   Dali::DisplayConnection::GetDpi( dpiHor, dpiVer );
308 #endif
309
310   // tell core about the DPI value
311   mCore->SetDpi(dpiHor, dpiVer);
312
313   // set the DPI value for font rendering
314   FontClient fontClient = FontClient::Get();
315   fontClient.SetDpi( dpiHor, dpiVer );
316
317   // Tell the core the size of the surface just before we start the render-thread
318   PositionSize size = mSurface->GetPositionSize();
319   mCore->SurfaceResized( size.width, size.height );
320
321   // Initialize the thread controller
322   mThreadController->Initialize();
323
324   ProcessCoreEvents(); // Ensure any startup messages are processed.
325
326   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
327   {
328     (*iter)->OnStart();
329   }
330 }
331
332 // Dali::Internal::Adaptor::Adaptor::Pause
333 void Adaptor::Pause()
334 {
335   // Only pause the adaptor if we're actually running.
336   if( RUNNING == mState )
337   {
338     // Inform observers that we are about to be paused.
339     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
340     {
341       (*iter)->OnPause();
342     }
343
344     // Reset the event handler when adaptor paused
345     if( mEventHandler )
346     {
347       mEventHandler->Pause();
348     }
349
350     mThreadController->Pause();
351     mState = PAUSED;
352
353     // Ensure any messages queued during pause callbacks are processed by doing another update.
354     RequestUpdateOnce();
355   }
356 }
357
358 // Dali::Internal::Adaptor::Adaptor::Resume
359 void Adaptor::Resume()
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   if ( PAUSED_WHILE_HIDDEN == mState )
747   {
748     // Adaptor can now be resumed
749     mState = PAUSED;
750
751     Resume();
752
753     // Force a render task
754     RequestUpdateOnce();
755   }
756 }
757
758 void Adaptor::OnWindowHidden()
759 {
760   if ( RUNNING == mState )
761   {
762     Pause();
763
764     // Adaptor cannot be resumed until the window is shown
765     mState = PAUSED_WHILE_HIDDEN;
766   }
767 }
768
769 // Dali::Internal::Adaptor::Adaptor::OnDamaged
770 void Adaptor::OnDamaged( const DamageArea& area )
771 {
772   // This is needed for the case where Dali window is partially obscured
773   RequestUpdate( false );
774 }
775
776 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
777 {
778   // let the core know the surface size has changed
779   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
780
781   mResizedSignal.Emit( mAdaptor );
782 }
783
784 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
785 {
786   // flush the event queue to give the update-render thread chance
787   // to start processing messages for new camera setup etc as soon as possible
788   ProcessCoreEvents();
789
790   // this method blocks until the render thread has completed the resizing.
791   mThreadController->ResizeSurface();
792 }
793
794 void Adaptor::NotifySceneCreated()
795 {
796   GetCore().SceneCreated();
797
798   // Start thread controller after the scene has been created
799   mThreadController->Start();
800
801   // process after surface is created (registering to remote surface provider if required)
802   SurfaceInitialized();
803
804   mState = RUNNING;
805 }
806
807 void Adaptor::NotifyLanguageChanged()
808 {
809   mLanguageChangedSignal.Emit( mAdaptor );
810 }
811
812 void Adaptor::RenderOnce()
813 {
814   RequestUpdateOnce();
815 }
816
817 const LogFactoryInterface& Adaptor::GetLogFactory()
818 {
819   return *mEnvironmentOptions;
820 }
821
822 void Adaptor::RequestUpdateOnce()
823 {
824   if( mThreadController )
825   {
826     mThreadController->RequestUpdateOnce();
827   }
828 }
829
830 void Adaptor::IndicatorSizeChanged(int height)
831 {
832   // let the core know the indicator height is changed
833   mCore->SetTopMargin(height);
834 }
835
836 void Adaptor::ProcessCoreEventsFromIdle()
837 {
838   ProcessCoreEvents();
839
840   // the idle handle automatically un-installs itself
841   mNotificationOnIdleInstalled = false;
842 }
843
844 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
845 : mResizedSignal(),
846   mLanguageChangedSignal(),
847   mAdaptor( adaptor ),
848   mState( READY ),
849   mCore( NULL ),
850   mThreadController( NULL ),
851   mVSyncMonitor( NULL ),
852   mGLES( NULL ),
853   mGlSync( NULL ),
854   mEglFactory( NULL ),
855   mNativeWindow( nativeWindow ),
856   mSurface( surface ),
857   mPlatformAbstraction( NULL ),
858   mEventHandler( NULL ),
859   mCallbackManager( NULL ),
860   mNotificationOnIdleInstalled( false ),
861   mNotificationTrigger( NULL ),
862   mGestureManager( NULL ),
863   mDaliFeedbackPlugin(),
864   mFeedbackController( NULL ),
865   mTtsPlayers(),
866   mObservers(),
867   mDragAndDropDetector(),
868   mDeferredRotationObserver( NULL ),
869   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
870   mPerformanceInterface( NULL ),
871   mKernelTracer(),
872   mSystemTracer(),
873   mTriggerEventFactory(),
874   mObjectProfiler( NULL ),
875   mSocketFactory(),
876   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
877   mUseRemoteSurface( false )
878 {
879   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
880   gThreadLocalAdaptor = this;
881 }
882
883 // Stereoscopy
884
885 void Adaptor::SetViewMode( ViewMode viewMode )
886 {
887   mSurface->SetViewMode( viewMode );
888   mCore->SetViewMode( viewMode );
889 }
890
891 ViewMode Adaptor::GetViewMode() const
892 {
893   return mCore->GetViewMode();
894 }
895
896 void Adaptor::SetStereoBase( float stereoBase )
897 {
898   mCore->SetStereoBase( stereoBase );
899 }
900
901 float Adaptor::GetStereoBase() const
902 {
903   return mCore->GetStereoBase();
904 }
905
906 void Adaptor::SetRootLayoutDirection( std::string locale )
907 {
908   Dali::Stage stage = Dali::Stage::GetCurrent();
909
910   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
911                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
912 }
913
914 } // namespace Adaptor
915
916 } // namespace Internal
917
918 } // namespace Dali