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