2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/touch-event-integ.h>
33 #include <dali/integration-api/processor-interface.h>
36 #include <dali/public-api/dali-adaptor-common.h>
37 #include <dali/internal/system/common/thread-controller.h>
38 #include <dali/internal/system/common/performance-interface-factory.h>
39 #include <dali/internal/adaptor/common/lifecycle-observer.h>
41 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
42 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
44 #include <dali/devel-api/text-abstraction/font-client.h>
46 #include <dali/internal/system/common/callback-manager.h>
47 #include <dali/internal/accessibility/common/tts-player-impl.h>
48 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
49 #include <dali/internal/input/common/gesture-manager.h>
50 #include <dali/internal/window-system/common/event-handler.h>
51 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
52 #include <dali/internal/graphics/gles/gl-implementation.h>
53 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
54 #include <dali/internal/graphics/common/egl-image-extensions.h>
55 #include <dali/internal/clipboard/common/clipboard-impl.h>
56 #include <dali/internal/graphics/common/vsync-monitor.h>
57 #include <dali/internal/system/common/object-profiler.h>
58 #include <dali/internal/window-system/common/display-connection.h>
59 #include <dali/internal/window-system/common/window-impl.h>
60 #include <dali/internal/window-system/common/window-render-surface.h>
62 #include <dali/internal/system/common/logging.h>
64 #include <dali/internal/system/common/locale-utils.h>
65 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
66 #include <dali/internal/imaging/common/image-loader.h>
69 using Dali::TextAbstraction::FontClient;
82 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
83 } // unnamed namespace
86 Dali::Adaptor* Adaptor::New( Any nativeWindow, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
88 Dali::Adaptor* adaptor = new Dali::Adaptor;
89 Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
90 adaptor->mImpl = impl;
92 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
93 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
95 impl->Initialize( graphicsFactory, configuration );
96 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
101 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
103 Any winId = window.GetNativeHandle();
105 Window& windowImpl = Dali::GetImplementation( window );
106 Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
107 windowImpl.SetAdaptor( *adaptor );
111 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Any nativeWindow, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
113 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
114 Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions ); // Impl adaptor
115 adaptor->mImpl = impl;
117 impl->Initialize( graphicsFactory, configuration );
122 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
124 Any winId = window.GetNativeHandle();
126 Window& windowImpl = Dali::GetImplementation( window );
127 Dali::Adaptor* adaptor = New( graphicsFactory, winId, windowImpl.GetSurface(), configuration, environmentOptions );
128 windowImpl.SetAdaptor( *adaptor );
132 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
134 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
135 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
136 mEnvironmentOptions->SetLogFunction( logFunction );
137 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
139 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
142 GetDataStoragePath( path );
143 mPlatformAbstraction->SetDataStoragePath( path );
145 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
146 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
148 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
151 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
153 if( mEnvironmentOptions->PerformanceServerRequired() )
155 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
158 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
159 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
161 mCallbackManager = CallbackManager::New();
163 WindowPane defaultWindow = mWindowFrame.front();
165 DALI_ASSERT_DEBUG( defaultWindow.surface && "Surface not initialized" );
167 PositionSize size = defaultWindow.surface->GetPositionSize();
169 defaultWindow.surface->SetAdaptor(*this);
171 mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
173 mGraphics = &( graphicsFactory.Create() );
174 mGraphics->Initialize( mEnvironmentOptions );
176 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
178 // This will only be created once
179 eglGraphics->Create();
181 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
182 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
184 mCore = Integration::Core::New( *this,
185 *mPlatformAbstraction,
189 dataRetentionPolicy ,
190 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
191 mGraphics->GetDepthBufferRequired(),
192 mGraphics->GetStencilBufferRequired() );
194 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
195 if( 0u < timeInterval )
197 mObjectProfiler = new ObjectProfiler( timeInterval );
200 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
202 mVSyncMonitor = new VSyncMonitor;
204 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow.surface->GetSurfaceType() );
206 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
208 // Should be called after Core creation
209 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
211 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
213 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
215 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
217 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
219 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
221 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
223 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
225 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
227 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
229 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
231 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
233 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
235 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
237 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
239 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
241 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
243 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
245 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
247 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
249 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
251 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
253 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
255 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
257 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
259 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
261 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
263 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
265 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
267 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
269 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
271 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
274 // Set max texture size
275 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
277 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
283 // Ensure stop status
286 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
287 gThreadLocalAdaptor = NULL;
289 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
291 (*iter)->OnDestroy();
294 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
295 delete mVSyncMonitor;
296 delete mEventHandler;
297 delete mObjectProfiler;
301 delete mGestureManager;
302 delete mDisplayConnection;
303 delete mPlatformAbstraction;
304 delete mCallbackManager;
305 delete mPerformanceInterface;
307 mGraphics->Destroy();
309 // uninstall it on this thread (main actor thread)
310 Dali::Integration::Log::UninstallLogFunction();
312 // Delete environment options if we own it
313 if( mEnvironmentOptionsOwned )
315 delete mEnvironmentOptions;
319 void Adaptor::Start()
321 // It doesn't support restart after stop at this moment to support restarting, need more testing
322 if( READY != mState )
329 SetupSystemInformation();
331 // Start the callback manager
332 mCallbackManager->Start();
334 WindowPane defaultWindow = mWindowFrame.front();
336 // Create event handler
337 mEventHandler = new EventHandler( defaultWindow.surface, *this, *mGestureManager, *this, mDragAndDropDetector );
339 if( mDeferredRotationObserver != NULL )
341 mEventHandler->SetRotationObserver(mDeferredRotationObserver);
342 mDeferredRotationObserver = NULL;
345 unsigned int dpiHor, dpiVer;
348 defaultWindow.surface->GetDpi( dpiHor, dpiVer );
350 // set the DPI value for font rendering
351 FontClient fontClient = FontClient::Get();
352 fontClient.SetDpi( dpiHor, dpiVer );
354 // Tell the core the size of the surface just before we start the render-thread
355 mCore->SurfaceResized( defaultWindow.surface );
357 // Initialize the thread controller
358 mThreadController->Initialize();
360 ProcessCoreEvents(); // Ensure any startup messages are processed.
362 // Initialize the image loader plugin
363 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
365 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
371 // Dali::Internal::Adaptor::Adaptor::Pause
372 void Adaptor::Pause()
374 // Only pause the adaptor if we're actually running.
375 if( RUNNING == mState )
377 // Inform observers that we are about to be paused.
378 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
383 // Reset the event handler when adaptor paused
386 mEventHandler->Pause();
389 mThreadController->Pause();
392 // Ensure any messages queued during pause callbacks are processed by doing another update.
397 // Dali::Internal::Adaptor::Adaptor::Resume
398 void Adaptor::Resume()
400 // Only resume the adaptor if we are in the suspended state.
401 if( PAUSED == mState )
405 // Reset the event handler when adaptor resumed
408 mEventHandler->Resume();
411 // Inform observers that we have resumed.
412 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
417 // Trigger processing of events queued up while paused
418 mCore->ProcessEvents();
420 // Do at end to ensure our first update/render after resumption includes the processed messages as well
421 mThreadController->Resume();
427 if( RUNNING == mState ||
429 PAUSED_WHILE_HIDDEN == mState )
431 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
436 mThreadController->Stop();
438 // Clear out all the handles to Windows
439 mWindowFrame.clear();
441 // Delete the TTS player
442 for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
446 mTtsPlayers[i].Reset();
450 // Destroy the image loader plugin
451 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
453 delete mEventHandler;
454 mEventHandler = NULL;
456 delete mNotificationTrigger;
457 mNotificationTrigger = NULL;
459 mCallbackManager->Stop();
465 void Adaptor::ContextLost()
467 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
470 void Adaptor::ContextRegained()
472 // Inform core, so that texture resources can be reloaded
473 mCore->RecoverFromContextLoss();
475 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
478 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
480 mEventHandler->FeedTouchPoint( point, timeStamp );
483 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
485 mEventHandler->FeedWheelEvent( wheelEvent );
488 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
490 mEventHandler->FeedKeyEvent( keyEvent );
493 void Adaptor::ReplaceSurface( Any nativeWindow, Dali::RenderSurfaceInterface& newSurface )
495 // Let the core know the surface size has changed
496 mCore->SurfaceResized( &newSurface );
498 mResizedSignal.Emit( mAdaptor );
500 WindowPane newDefaultWindow;
501 newDefaultWindow.nativeWindow = nativeWindow;
502 newDefaultWindow.surface = &newSurface;
503 newDefaultWindow.surface->SetAdaptor(*this);
505 WindowPane oldDefaultWindow = mWindowFrame.front();
507 // Update WindowFrame
508 std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
509 iter = mWindowFrame.insert( iter, newDefaultWindow );
511 // Flush the event queue to give the update-render thread chance
512 // to start processing messages for new camera setup etc as soon as possible
515 // This method blocks until the render thread has completed the replace.
516 mThreadController->ReplaceSurface( newDefaultWindow.surface );
518 // Must delete the old Window only after the render thread has completed the replace
519 oldDefaultWindow.surface->DestroySurface();
520 oldDefaultWindow.surface = nullptr;
523 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
525 WindowPane defaultWindow = mWindowFrame.front();
526 return *(defaultWindow.surface);
529 void Adaptor::ReleaseSurfaceLock()
531 WindowPane defaultWindow = mWindowFrame.front();
532 defaultWindow.surface->ReleaseLock();
535 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
537 if(!mTtsPlayers[mode])
539 // Create the TTS player when it needed, because it can reduce launching time.
540 mTtsPlayers[mode] = TtsPlayer::New(mode);
543 return mTtsPlayers[mode];
546 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
548 bool idleAdded(false);
550 // Only add an idle if the Adaptor is actually running
551 if( RUNNING == mState || READY == mState || forceAdd )
553 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
559 void Adaptor::RemoveIdle( CallbackBase* callback )
561 mCallbackManager->RemoveIdleCallback( callback );
564 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
566 mThreadController->SetPreRenderCallback( callback );
569 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
571 Window& windowImpl = Dali::GetImplementation( *childWindow );
572 windowImpl.SetAdaptor( Get() );
574 // This is any Window that is not the main (default) one
575 WindowPane additionalWindow;
576 additionalWindow.instance = childWindow;
577 additionalWindow.window_name = childWindowName;
578 additionalWindow.class_name = childWindowClassName;
579 additionalWindow.window_mode = childWindowMode;
580 additionalWindow.surface = windowImpl.GetSurface();
581 additionalWindow.id = windowImpl.GetId();
583 // Add the new Window to the Frame - the order is not important
584 mWindowFrame.push_back( additionalWindow );
589 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
591 for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
593 if( iter->instance == childWindow )
595 mWindowFrame.erase( iter );
603 bool Adaptor::RemoveWindow( std::string childWindowName )
605 for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
607 if( iter->window_name == childWindowName )
609 mWindowFrame.erase( iter );
617 bool Adaptor::RemoveWindow( Window* childWindow )
619 for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
621 if( iter->id == childWindow->GetId() )
623 mWindowFrame.erase( iter );
631 Dali::Adaptor& Adaptor::Get()
633 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
634 return gThreadLocalAdaptor->mAdaptor;
637 bool Adaptor::IsAvailable()
639 return gThreadLocalAdaptor != NULL;
642 void Adaptor::SceneCreated()
644 mCore->SceneCreated();
647 Dali::Integration::Core& Adaptor::GetCore()
652 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
654 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
657 void Adaptor::SetUseHardwareVSync( bool useHardware )
659 mVSyncMonitor->SetUseHardwareVSync( useHardware );
662 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
664 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
665 return *mDisplayConnection;
668 GraphicsInterface& Adaptor::GetGraphicsInterface()
670 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
674 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
676 return *mPlatformAbstraction;
679 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
681 return *mNotificationTrigger;
684 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
686 return mTriggerEventFactory;
689 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
691 return mSocketFactory;
694 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
696 if( !mWindowFrame.empty())
698 WindowPane defaultWindow = mWindowFrame.front();
699 return defaultWindow.surface;
707 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
709 return mVSyncMonitor;
712 TraceInterface& Adaptor::GetKernelTraceInterface()
714 return mKernelTracer;
717 TraceInterface& Adaptor::GetSystemTraceInterface()
719 return mSystemTracer;
722 PerformanceInterface* Adaptor::GetPerformanceInterface()
724 return mPerformanceInterface;
727 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
729 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
730 return *mPlatformAbstraction;
733 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
735 mDragAndDropDetector = detector;
739 mEventHandler->SetDragAndDropDetector( detector );
743 void Adaptor::SetRotationObserver( RotationObserver* observer )
747 mEventHandler->SetRotationObserver( observer );
749 else if( mState == READY )
751 // Set once event handler exists
752 mDeferredRotationObserver = observer;
756 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
758 if(mTtsPlayers[mode])
760 mTtsPlayers[mode].Reset();
764 void Adaptor::SetMinimumPinchDistance(float distance)
766 if( mGestureManager )
768 mGestureManager->SetMinimumPinchDistance(distance);
772 Any Adaptor::GetNativeWindowHandle()
774 WindowPane defaultWindow = mWindowFrame.front();
775 return defaultWindow.nativeWindow;
778 Any Adaptor::GetGraphicsDisplay()
784 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
786 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
787 display = eglImpl.GetDisplay();
793 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
795 mUseRemoteSurface = useRemoteSurface;
798 void Adaptor::AddObserver( LifeCycleObserver& observer )
800 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
802 if ( match == mObservers.end() )
804 mObservers.push_back( &observer );
808 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
810 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
812 if ( match != mObservers.end() )
814 mObservers.erase( match );
818 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
822 mCore->QueueEvent(event);
826 void Adaptor::ProcessCoreEvents()
830 if( mPerformanceInterface )
832 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
835 mCore->ProcessEvents();
837 if( mPerformanceInterface )
839 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
844 void Adaptor::RequestUpdate( bool forceUpdate )
850 mThreadController->RequestUpdate();
854 case PAUSED_WHILE_HIDDEN:
856 // When Dali applications are partially visible behind the lock-screen,
857 // the indicator must be updated (therefore allow updates in the PAUSED state)
860 mThreadController->RequestUpdateOnce();
872 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
874 // Only request a notification if the Adaptor is actually running
875 // and we haven't installed the idle notification
876 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
878 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
882 void Adaptor::OnWindowShown()
884 if ( PAUSED_WHILE_HIDDEN == mState )
886 // Adaptor can now be resumed
891 // Force a render task
896 void Adaptor::OnWindowHidden()
898 if ( RUNNING == mState )
902 // Adaptor cannot be resumed until the window is shown
903 mState = PAUSED_WHILE_HIDDEN;
907 // Dali::Internal::Adaptor::Adaptor::OnDamaged
908 void Adaptor::OnDamaged( const DamageArea& area )
910 // This is needed for the case where Dali window is partially obscured
911 RequestUpdate( false );
914 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
916 // Let the core know the surface size has changed
917 mCore->SurfaceResized( surface );
919 mResizedSignal.Emit( mAdaptor );
922 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
924 // Flush the event queue to give the update-render thread chance
925 // to start processing messages for new camera setup etc as soon as possible
928 mThreadController->ResizeSurface();
931 void Adaptor::NotifySceneCreated()
933 GetCore().SceneCreated();
935 // Start thread controller after the scene has been created
936 mThreadController->Start();
938 // Process after surface is created (registering to remote surface provider if required)
939 SurfaceInitialized();
944 void Adaptor::NotifyLanguageChanged()
946 mLanguageChangedSignal.Emit( mAdaptor );
949 void Adaptor::RenderOnce()
954 const LogFactoryInterface& Adaptor::GetLogFactory()
956 return *mEnvironmentOptions;
959 void Adaptor::RegisterProcessor( Integration::Processor& processor )
961 GetCore().RegisterProcessor(processor);
964 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
966 GetCore().UnregisterProcessor(processor);
969 void Adaptor::RequestUpdateOnce()
971 if( mThreadController )
973 mThreadController->RequestUpdateOnce();
977 bool Adaptor::ProcessCoreEventsFromIdle()
981 // the idle handle automatically un-installs itself
982 mNotificationOnIdleInstalled = false;
987 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
989 mLanguageChangedSignal(),
993 mThreadController( nullptr ),
994 mVSyncMonitor( nullptr ),
995 mGraphics( nullptr ),
996 mDisplayConnection( nullptr ),
998 mPlatformAbstraction( nullptr ),
999 mEventHandler( nullptr ),
1000 mCallbackManager( nullptr ),
1001 mNotificationOnIdleInstalled( false ),
1002 mNotificationTrigger( nullptr ),
1003 mGestureManager( nullptr ),
1004 mDaliFeedbackPlugin(),
1005 mFeedbackController( nullptr ),
1008 mDragAndDropDetector(),
1009 mDeferredRotationObserver( nullptr ),
1010 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1011 mPerformanceInterface( nullptr ),
1014 mTriggerEventFactory(),
1015 mObjectProfiler( nullptr ),
1017 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1018 mUseRemoteSurface( false )
1020 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1022 WindowPane defaultWindow;
1023 defaultWindow.nativeWindow = nativeWindow;
1024 defaultWindow.surface = surface;
1025 defaultWindow.id = 0;
1027 std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1028 iter = mWindowFrame.insert( iter, defaultWindow );
1030 gThreadLocalAdaptor = this;
1033 void Adaptor::SetRootLayoutDirection( std::string locale )
1035 Dali::Stage stage = Dali::Stage::GetCurrent();
1037 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1038 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1041 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1043 bool idleAdded( false );
1045 // Only add an idle if the Adaptor is actually running
1046 if( RUNNING == mState || READY == mState || forceAdd )
1048 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1054 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1056 mCallbackManager->RemoveIdleEntererCallback( callback );
1059 } // namespace Adaptor
1061 } // namespace Internal