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
85 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
87 Dali::Adaptor* adaptor = new Dali::Adaptor;
88 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
89 adaptor->mImpl = impl;
91 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
92 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
94 impl->Initialize( graphicsFactory, configuration );
95 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
100 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
102 Window& windowImpl = Dali::GetImplementation( window );
103 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
104 windowImpl.SetAdaptor( *adaptor );
108 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Window window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
110 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
111 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
112 adaptor->mImpl = impl;
114 impl->Initialize( graphicsFactory, configuration );
119 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
121 Window& windowImpl = Dali::GetImplementation( window );
122 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
123 windowImpl.SetAdaptor( *adaptor );
127 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
129 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
130 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
131 mEnvironmentOptions->SetLogFunction( logFunction );
132 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
134 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
137 GetDataStoragePath( path );
138 mPlatformAbstraction->SetDataStoragePath( path );
140 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
141 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
143 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
146 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
148 if( mEnvironmentOptions->PerformanceServerRequired() )
150 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
153 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
154 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
156 mCallbackManager = CallbackManager::New();
158 WindowPtr defaultWindow = mWindows.front();
160 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
162 PositionSize size = defaultWindow->GetSurface()->GetPositionSize();
164 mGestureManager = new GestureManager(*this, Vector2(static_cast<float>(size.width), static_cast<float>(size.height)), mCallbackManager, *mEnvironmentOptions);
166 mGraphics = &( graphicsFactory.Create() );
167 mGraphics->Initialize( mEnvironmentOptions );
169 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
171 // This will only be created once
172 eglGraphics->Create();
174 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
175 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
177 mCore = Integration::Core::New( *this,
178 *mPlatformAbstraction,
182 dataRetentionPolicy ,
183 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
184 mGraphics->GetDepthBufferRequired(),
185 mGraphics->GetStencilBufferRequired() );
187 defaultWindow->SetAdaptor( *this );
189 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
190 if( 0u < timeInterval )
192 mObjectProfiler = new ObjectProfiler( timeInterval );
195 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
197 mVSyncMonitor = new VSyncMonitor;
199 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
201 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
203 // Should be called after Core creation
204 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
206 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
208 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
210 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
212 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
214 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
216 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
218 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
220 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
222 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
224 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
226 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
228 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
230 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
232 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
234 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
236 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
238 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
240 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
242 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
244 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
246 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
248 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
250 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
252 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
254 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
256 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
258 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
260 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
262 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
264 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
266 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
269 // Set max texture size
270 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
272 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
278 // Ensure stop status
281 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
282 gThreadLocalAdaptor = NULL;
284 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
286 (*iter)->OnDestroy();
289 // Clear out all the handles to Windows
292 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
293 delete mVSyncMonitor;
294 delete mObjectProfiler;
298 delete mGestureManager;
299 delete mDisplayConnection;
300 delete mPlatformAbstraction;
301 delete mCallbackManager;
302 delete mPerformanceInterface;
304 mGraphics->Destroy();
306 // uninstall it on this thread (main actor thread)
307 Dali::Integration::Log::UninstallLogFunction();
309 // Delete environment options if we own it
310 if( mEnvironmentOptionsOwned )
312 delete mEnvironmentOptions;
316 void Adaptor::Start()
318 // It doesn't support restart after stop at this moment to support restarting, need more testing
319 if( READY != mState )
326 SetupSystemInformation();
328 // Start the callback manager
329 mCallbackManager->Start();
331 WindowPtr defaultWindow = mWindows.front();
333 unsigned int dpiHor, dpiVer;
336 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
338 // set the DPI value for font rendering
339 FontClient fontClient = FontClient::Get();
340 fontClient.SetDpi( dpiHor, dpiVer );
342 // Tell the core the size of the surface just before we start the render-thread
343 mCore->SurfaceResized( defaultWindow->GetSurface() );
345 // Initialize the thread controller
346 mThreadController->Initialize();
348 ProcessCoreEvents(); // Ensure any startup messages are processed.
350 // Initialize the image loader plugin
351 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
353 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
359 // Dali::Internal::Adaptor::Adaptor::Pause
360 void Adaptor::Pause()
362 // Only pause the adaptor if we're actually running.
363 if( RUNNING == mState )
365 // Inform observers that we are about to be paused.
366 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
371 // Pause all windows event handlers when adaptor paused
372 for( WindowPtr window : mWindows )
377 mThreadController->Pause();
380 // Ensure any messages queued during pause callbacks are processed by doing another update.
383 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
387 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
391 // Dali::Internal::Adaptor::Adaptor::Resume
392 void Adaptor::Resume()
394 // Only resume the adaptor if we are in the suspended state.
395 if( PAUSED == mState )
399 // Reset the event handlers when adaptor resumed
400 for( WindowPtr window : mWindows )
405 // Inform observers that we have resumed.
406 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
411 // Trigger processing of events queued up while paused
412 mCore->ProcessEvents();
414 // Do at end to ensure our first update/render after resumption includes the processed messages as well
415 mThreadController->Resume();
417 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
421 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
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 // Delete the TTS player
439 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
443 mTtsPlayers[i].Reset();
447 // Destroy the image loader plugin
448 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
450 delete mNotificationTrigger;
451 mNotificationTrigger = NULL;
453 mCallbackManager->Stop();
457 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
461 void Adaptor::ContextLost()
463 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
466 void Adaptor::ContextRegained()
468 // Inform core, so that texture resources can be reloaded
469 mCore->RecoverFromContextLoss();
471 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
474 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
476 mWindows.front()->FeedTouchPoint( point, timeStamp );
479 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
481 mWindows.front()->FeedWheelEvent( wheelEvent );
484 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
486 mWindows.front()->FeedKeyEvent( keyEvent );
489 void Adaptor::ReplaceSurface( Dali::Window window, Dali::RenderSurfaceInterface& newSurface )
491 Window* windowImpl = &Dali::GetImplementation( window );
492 for( WindowPtr windowPtr : mWindows )
494 if( windowPtr.Get() == windowImpl ) // the window is not deleted
496 // Let the core know the surface size has changed
497 mCore->SurfaceResized( &newSurface );
499 mResizedSignal.Emit( mAdaptor );
501 windowImpl->SetSurface( static_cast<WindowRenderSurface*>( &newSurface ) );
503 // Flush the event queue to give the update-render thread chance
504 // to start processing messages for new camera setup etc as soon as possible
507 // This method blocks until the render thread has completed the replace.
508 mThreadController->ReplaceSurface( &newSurface );
514 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
516 return *mWindows.front()->GetSurface();
519 void Adaptor::ReleaseSurfaceLock()
521 mWindows.front()->GetSurface()->ReleaseLock();
524 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
526 if( !mTtsPlayers[mode] )
528 // Create the TTS player when it needed, because it can reduce launching time.
529 mTtsPlayers[mode] = TtsPlayer::New(mode);
532 return mTtsPlayers[mode];
535 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
537 bool idleAdded(false);
539 // Only add an idle if the Adaptor is actually running
540 if( RUNNING == mState || READY == mState || forceAdd )
542 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
548 void Adaptor::RemoveIdle( CallbackBase* callback )
550 mCallbackManager->RemoveIdleCallback( callback );
553 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
555 mThreadController->SetPreRenderCallback( callback );
558 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
560 Window& windowImpl = Dali::GetImplementation( *childWindow );
561 windowImpl.SetAdaptor( Get() );
563 // Add the new Window to the container - the order is not important
564 mWindows.push_back( WindowPtr( &windowImpl ) );
568 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
570 Window& windowImpl = Dali::GetImplementation( *childWindow );
571 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
573 if( *iter == &windowImpl )
575 mWindows.erase( iter );
583 bool Adaptor::RemoveWindow( std::string childWindowName )
585 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
587 if( ( *iter )->GetName() == childWindowName )
589 mWindows.erase( iter );
597 bool Adaptor::RemoveWindow( Window* childWindow )
599 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
601 if( ( *iter )->GetId() == childWindow->GetId() )
603 mWindows.erase( iter );
611 Dali::Adaptor& Adaptor::Get()
613 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
614 return gThreadLocalAdaptor->mAdaptor;
617 bool Adaptor::IsAvailable()
619 return gThreadLocalAdaptor != NULL;
622 void Adaptor::SceneCreated()
624 mCore->SceneCreated();
627 Dali::Integration::Core& Adaptor::GetCore()
632 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
634 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
637 void Adaptor::SetUseHardwareVSync( bool useHardware )
639 mVSyncMonitor->SetUseHardwareVSync( useHardware );
642 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
644 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
645 return *mDisplayConnection;
648 GraphicsInterface& Adaptor::GetGraphicsInterface()
650 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
654 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
656 return *mPlatformAbstraction;
659 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
661 return *mNotificationTrigger;
664 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
666 return mTriggerEventFactory;
669 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
671 return mSocketFactory;
674 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
676 if( !mWindows.empty() )
678 return mWindows.front()->GetSurface();
684 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
686 return mVSyncMonitor;
689 TraceInterface& Adaptor::GetKernelTraceInterface()
691 return mKernelTracer;
694 TraceInterface& Adaptor::GetSystemTraceInterface()
696 return mSystemTracer;
699 PerformanceInterface* Adaptor::GetPerformanceInterface()
701 return mPerformanceInterface;
704 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
706 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
707 return *mPlatformAbstraction;
710 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
712 mDragAndDropDetector = detector;
715 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
717 if( mTtsPlayers[mode] )
719 mTtsPlayers[mode].Reset();
723 void Adaptor::SetMinimumPinchDistance(float distance)
725 if( mGestureManager )
727 mGestureManager->SetMinimumPinchDistance(distance);
731 Any Adaptor::GetNativeWindowHandle()
733 return mWindows.front()->GetNativeHandle();
736 Any Adaptor::GetGraphicsDisplay()
742 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
744 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
745 display = eglImpl.GetDisplay();
751 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
753 mUseRemoteSurface = useRemoteSurface;
756 void Adaptor::AddObserver( LifeCycleObserver& observer )
758 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
760 if ( match == mObservers.end() )
762 mObservers.push_back( &observer );
766 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
768 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
770 if ( match != mObservers.end() )
772 mObservers.erase( match );
776 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
780 mCore->QueueEvent(event);
784 void Adaptor::ProcessCoreEvents()
788 if( mPerformanceInterface )
790 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
793 mCore->ProcessEvents();
795 if( mPerformanceInterface )
797 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
802 void Adaptor::RequestUpdate( bool forceUpdate )
808 mThreadController->RequestUpdate();
812 case PAUSED_WHILE_HIDDEN:
814 // When Dali applications are partially visible behind the lock-screen,
815 // the indicator must be updated (therefore allow updates in the PAUSED state)
818 mThreadController->RequestUpdateOnce();
830 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
832 // Only request a notification if the Adaptor is actually running
833 // and we haven't installed the idle notification
834 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
836 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
840 void Adaptor::OnWindowShown()
842 if ( PAUSED_WHILE_HIDDEN == mState )
844 // Adaptor can now be resumed
849 // Force a render task
854 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Not shown [%d]\n", mState );
858 void Adaptor::OnWindowHidden()
860 if ( RUNNING == mState )
862 bool allWindowsHidden = true;
864 for( WindowPtr window : mWindows )
866 if ( window->IsVisible() )
868 allWindowsHidden = false;
873 // Only pause the adaptor when all the windows are hidden
874 if ( allWindowsHidden )
878 // Adaptor cannot be resumed until any window is shown
879 mState = PAUSED_WHILE_HIDDEN;
884 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Not hidden [%d]\n", mState );
888 // Dali::Internal::Adaptor::Adaptor::OnDamaged
889 void Adaptor::OnDamaged( const DamageArea& area )
891 // This is needed for the case where Dali window is partially obscured
892 RequestUpdate( false );
895 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
897 // Let the core know the surface size has changed
898 mCore->SurfaceResized( surface );
900 mResizedSignal.Emit( mAdaptor );
903 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
905 // Flush the event queue to give the update-render thread chance
906 // to start processing messages for new camera setup etc as soon as possible
909 mThreadController->ResizeSurface();
912 void Adaptor::NotifySceneCreated()
914 GetCore().SceneCreated();
916 // Flush the event queue to give the update-render thread chance
917 // to start processing messages for new camera setup etc as soon as possible
920 // Start thread controller after the scene has been created
921 mThreadController->Start();
923 // Process after surface is created (registering to remote surface provider if required)
924 SurfaceInitialized();
928 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated\n" );
931 void Adaptor::NotifyLanguageChanged()
933 mLanguageChangedSignal.Emit( mAdaptor );
936 void Adaptor::RenderOnce()
941 const LogFactoryInterface& Adaptor::GetLogFactory()
943 return *mEnvironmentOptions;
946 void Adaptor::RegisterProcessor( Integration::Processor& processor )
948 GetCore().RegisterProcessor(processor);
951 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
953 GetCore().UnregisterProcessor(processor);
956 void Adaptor::RequestUpdateOnce()
958 if( mThreadController )
960 mThreadController->RequestUpdateOnce();
964 bool Adaptor::ProcessCoreEventsFromIdle()
968 // the idle handle automatically un-installs itself
969 mNotificationOnIdleInstalled = false;
974 Adaptor::Adaptor(Dali::Window window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
976 mLanguageChangedSignal(),
980 mThreadController( nullptr ),
981 mVSyncMonitor( nullptr ),
982 mGraphics( nullptr ),
983 mDisplayConnection( nullptr ),
985 mPlatformAbstraction( nullptr ),
986 mCallbackManager( nullptr ),
987 mNotificationOnIdleInstalled( false ),
988 mNotificationTrigger( nullptr ),
989 mGestureManager( nullptr ),
990 mDaliFeedbackPlugin(),
991 mFeedbackController( nullptr ),
994 mDragAndDropDetector(),
995 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
996 mPerformanceInterface( nullptr ),
999 mTriggerEventFactory(),
1000 mObjectProfiler( nullptr ),
1002 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1003 mUseRemoteSurface( false )
1005 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1006 mWindows.insert( mWindows.begin(), WindowPtr( &Dali::GetImplementation( window ) ) );
1008 gThreadLocalAdaptor = this;
1011 void Adaptor::SetRootLayoutDirection( std::string locale )
1013 Dali::Stage stage = Dali::Stage::GetCurrent();
1015 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1016 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1019 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1021 bool idleAdded( false );
1023 // Only add an idle if the Adaptor is actually running
1024 if( RUNNING == mState || READY == mState || forceAdd )
1026 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1032 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1034 mCallbackManager->RemoveIdleEntererCallback( callback );
1037 } // namespace Adaptor
1039 } // namespace Internal