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