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