2 * Copyright (c) 2020 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/key-event-integ.h>
33 #include <dali/integration-api/events/touch-event-integ.h>
34 #include <dali/integration-api/events/wheel-event-integ.h>
35 #include <dali/integration-api/processor-interface.h>
38 #include <dali/public-api/dali-adaptor-common.h>
39 #include <dali/internal/system/common/thread-controller.h>
40 #include <dali/internal/system/common/performance-interface-factory.h>
41 #include <dali/internal/adaptor/common/lifecycle-observer.h>
42 #include <dali/internal/adaptor/common/thread-controller-interface.h>
44 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
45 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
47 #include <dali/devel-api/text-abstraction/font-client.h>
49 #include <dali/internal/system/common/callback-manager.h>
50 #include <dali/internal/accessibility/common/tts-player-impl.h>
51 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
52 #include <dali/internal/window-system/common/event-handler.h>
53 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
54 #include <dali/internal/graphics/gles/gl-implementation.h>
55 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
56 #include <dali/internal/graphics/common/egl-image-extensions.h>
57 #include <dali/internal/clipboard/common/clipboard-impl.h>
58 #include <dali/internal/system/common/object-profiler.h>
59 #include <dali/internal/window-system/common/display-connection.h>
60 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
61 #include <dali/internal/window-system/common/window-impl.h>
62 #include <dali/internal/window-system/common/window-render-surface.h>
64 #include <dali/internal/system/common/logging.h>
66 #include <dali/internal/system/common/locale-utils.h>
67 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
68 #include <dali/internal/imaging/common/image-loader.h>
70 #include <dali/internal/system/common/configuration-manager.h>
71 #include <dali/internal/system/common/environment-variables.h>
73 using Dali::TextAbstraction::FontClient;
75 extern std::string GetSystemCachePath();
89 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
91 } // unnamed namespace
93 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
95 Dali::Adaptor* adaptor = new Dali::Adaptor;
96 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
97 adaptor->mImpl = impl;
99 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
100 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
102 impl->Initialize( graphicsFactory, configuration );
103 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
108 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
110 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
111 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
112 windowImpl.SetAdaptor( *adaptor );
116 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
118 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
119 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
120 adaptor->mImpl = impl;
122 impl->Initialize( graphicsFactory, configuration );
127 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
129 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
130 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
131 windowImpl.SetAdaptor( *adaptor );
135 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
137 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
138 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
139 mEnvironmentOptions->SetLogFunction( logFunction );
140 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
142 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
145 GetDataStoragePath( path );
146 mPlatformAbstraction->SetDataStoragePath( path );
148 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
149 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
151 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
154 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
156 if( mEnvironmentOptions->PerformanceServerRequired() )
158 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
161 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
162 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
164 mCallbackManager = CallbackManager::New();
166 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
168 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
170 mGraphics = &( graphicsFactory.Create() );
171 mGraphics->Initialize( mEnvironmentOptions );
173 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
175 // This will only be created once
176 eglGraphics->Create();
178 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
179 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
180 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
182 mCore = Integration::Core::New( *this,
183 *mPlatformAbstraction,
186 eglContextHelperImpl,
187 dataRetentionPolicy ,
188 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
189 mGraphics->GetDepthBufferRequired(),
190 mGraphics->GetStencilBufferRequired(),
191 mGraphics->PartialUpdateAvailable() );
193 defaultWindow->SetAdaptor( Get() );
195 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
197 mWindowCreatedSignal.Emit( defaultSceneHolder );
199 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
200 if( 0u < timeInterval )
202 mObjectProfiler = new ObjectProfiler( timeInterval );
205 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
207 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
209 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
211 // Should be called after Core creation
212 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
214 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
216 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
218 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
220 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
222 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
224 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
226 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
228 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
230 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
232 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
234 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
236 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
238 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
240 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
242 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
244 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
246 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
248 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
250 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
252 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
254 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
256 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
258 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
260 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
262 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
264 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
266 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
268 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
270 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
272 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
274 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
276 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
278 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
280 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
282 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
284 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
286 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
288 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
290 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
293 std::string systemCachePath = GetSystemCachePath();
294 if( ! systemCachePath.empty() )
296 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
299 printf( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
304 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
309 // Ensure stop status
312 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
313 gThreadLocalAdaptor = NULL;
315 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
317 (*iter)->OnDestroy();
320 // Clear out all the handles to Windows
323 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
324 delete mObjectProfiler;
328 delete mDisplayConnection;
329 delete mPlatformAbstraction;
330 delete mCallbackManager;
331 delete mPerformanceInterface;
333 mGraphics->Destroy();
335 // uninstall it on this thread (main actor thread)
336 Dali::Integration::Log::UninstallLogFunction();
338 // Delete environment options if we own it
339 if( mEnvironmentOptionsOwned )
341 delete mEnvironmentOptions;
345 void Adaptor::Start()
347 // It doesn't support restart after stop at this moment to support restarting, need more testing
348 if( READY != mState )
355 SetupSystemInformation();
357 // Start the callback manager
358 mCallbackManager->Start();
360 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
362 unsigned int dpiHor, dpiVer;
365 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
367 // set the DPI value for font rendering
368 FontClient fontClient = FontClient::Get();
369 fontClient.SetDpi( dpiHor, dpiVer );
371 // Initialize the thread controller
372 mThreadController->Initialize();
374 // Set max texture size
375 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
377 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
381 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
382 setenv( DALI_ENV_MAX_TEXTURE_SIZE, std::to_string( maxTextureSize ).c_str(), 1 );
383 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
386 ProcessCoreEvents(); // Ensure any startup messages are processed.
388 // Initialize the image loader plugin
389 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
391 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
397 // Dali::Internal::Adaptor::Adaptor::Pause
398 void Adaptor::Pause()
400 // Only pause the adaptor if we're actually running.
401 if( RUNNING == mState )
403 // Inform observers that we are about to be paused.
404 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
409 // Pause all windows event handlers when adaptor paused
410 for( auto window : mWindows )
415 mThreadController->Pause();
418 // Ensure any messages queued during pause callbacks are processed by doing another update.
421 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
425 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
429 // Dali::Internal::Adaptor::Adaptor::Resume
430 void Adaptor::Resume()
432 // Only resume the adaptor if we are in the suspended state.
433 if( PAUSED == mState )
437 // Reset the event handlers when adaptor resumed
438 for( auto window : mWindows )
443 // Inform observers that we have resumed.
444 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
449 // Trigger processing of events queued up while paused
450 mCore->ProcessEvents();
452 // Do at end to ensure our first update/render after resumption includes the processed messages as well
453 mThreadController->Resume();
455 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
459 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
465 if( RUNNING == mState ||
467 PAUSED_WHILE_HIDDEN == mState )
469 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
474 mThreadController->Stop();
476 // Delete the TTS player
477 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
481 mTtsPlayers[i].Reset();
485 // Destroy the image loader plugin
486 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
488 delete mNotificationTrigger;
489 mNotificationTrigger = NULL;
491 mCallbackManager->Stop();
495 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
499 void Adaptor::ContextLost()
501 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
504 void Adaptor::ContextRegained()
506 // Inform core, so that texture resources can be reloaded
507 mCore->RecoverFromContextLoss();
509 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
512 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
514 Integration::Point convertedPoint( point );
515 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
518 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
520 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
521 mWindows.front()->FeedWheelEvent( event );
524 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
526 Integration::KeyEvent convertedEvent( keyEvent );
527 mWindows.front()->FeedKeyEvent( convertedEvent );
530 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
532 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
533 for( auto windowPtr : mWindows )
535 if( windowPtr == windowImpl ) // the window is not deleted
537 mResizedSignal.Emit( mAdaptor );
539 windowImpl->SetSurface( &newSurface );
541 // Flush the event queue to give the update-render thread chance
542 // to start processing messages for new camera setup etc as soon as possible
545 // This method blocks until the render thread has completed the replace.
546 mThreadController->ReplaceSurface( &newSurface );
552 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
554 // Flush the event queue to give the update-render thread chance
555 // to start processing messages for new camera setup etc as soon as possible
558 // This method blocks until the render thread has finished rendering the current surface.
559 mThreadController->DeleteSurface( &surface );
562 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
564 return *mWindows.front()->GetSurface();
567 void Adaptor::ReleaseSurfaceLock()
569 mWindows.front()->GetSurface()->ReleaseLock();
572 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
574 if( !mTtsPlayers[mode] )
576 // Create the TTS player when it needed, because it can reduce launching time.
577 mTtsPlayers[mode] = TtsPlayer::New(mode);
580 return mTtsPlayers[mode];
583 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
585 bool idleAdded(false);
587 // Only add an idle if the Adaptor is actually running
588 if( RUNNING == mState || READY == mState || forceAdd )
590 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
596 void Adaptor::RemoveIdle( CallbackBase* callback )
598 mCallbackManager->RemoveIdleCallback( callback );
601 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
603 mThreadController->SetPreRenderCallback( callback );
606 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
608 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
609 windowImpl.SetAdaptor( Get() );
611 // Add the new Window to the container - the order is not important
612 mWindows.push_back( &windowImpl );
614 mWindowCreatedSignal.Emit( childWindow );
619 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
621 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
622 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
624 if( *iter == &windowImpl )
626 mWindows.erase( iter );
634 bool Adaptor::RemoveWindow( std::string childWindowName )
636 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
638 if( ( *iter )->GetName() == childWindowName )
640 mWindows.erase( iter );
648 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
650 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
652 if( ( *iter )->GetId() == childWindow->GetId() )
654 mWindows.erase( iter );
662 Dali::Adaptor& Adaptor::Get()
664 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
665 return gThreadLocalAdaptor->mAdaptor;
668 bool Adaptor::IsAvailable()
670 return gThreadLocalAdaptor != NULL;
673 void Adaptor::SceneCreated()
675 mCore->SceneCreated();
678 Dali::Integration::Core& Adaptor::GetCore()
683 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
685 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
688 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
690 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
691 return *mDisplayConnection;
694 GraphicsInterface& Adaptor::GetGraphicsInterface()
696 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
700 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
702 return *mPlatformAbstraction;
705 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
707 return *mNotificationTrigger;
710 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
712 return mTriggerEventFactory;
715 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
717 return mSocketFactory;
720 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
722 if( !mWindows.empty() )
724 return mWindows.front()->GetSurface();
730 TraceInterface& Adaptor::GetKernelTraceInterface()
732 return mKernelTracer;
735 TraceInterface& Adaptor::GetSystemTraceInterface()
737 return mSystemTracer;
740 PerformanceInterface* Adaptor::GetPerformanceInterface()
742 return mPerformanceInterface;
745 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
747 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
748 return *mPlatformAbstraction;
751 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
753 if( mTtsPlayers[mode] )
755 mTtsPlayers[mode].Reset();
759 Any Adaptor::GetNativeWindowHandle()
761 return mWindows.front()->GetNativeHandle();
764 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
766 Any nativeWindowHandle;
768 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
770 for( auto sceneHolder : mWindows )
772 if ( scene == sceneHolder->GetScene() )
774 nativeWindowHandle = sceneHolder->GetNativeHandle();
779 return nativeWindowHandle;
782 Any Adaptor::GetGraphicsDisplay()
788 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
790 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
791 display = eglImpl.GetDisplay();
797 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
799 mUseRemoteSurface = useRemoteSurface;
802 void Adaptor::AddObserver( LifeCycleObserver& observer )
804 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
806 if ( match == mObservers.end() )
808 mObservers.push_back( &observer );
812 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
814 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
816 if ( match != mObservers.end() )
818 mObservers.erase( match );
822 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
826 mCore->QueueEvent(event);
830 void Adaptor::ProcessCoreEvents()
834 if( mPerformanceInterface )
836 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
839 mCore->ProcessEvents();
841 if( mPerformanceInterface )
843 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
848 void Adaptor::RequestUpdate( bool forceUpdate )
854 mThreadController->RequestUpdate();
858 case PAUSED_WHILE_HIDDEN:
862 // Update (and resource upload) without rendering
863 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
875 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
877 // Only request a notification if the Adaptor is actually running
878 // and we haven't installed the idle notification
879 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
881 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
885 void Adaptor::OnWindowShown()
887 if( PAUSED_WHILE_HIDDEN == mState )
889 // Adaptor can now be resumed
894 // Force a render task
897 else if( RUNNING == mState )
899 // Force a render task
902 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
906 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
910 void Adaptor::OnWindowHidden()
912 if( RUNNING == mState || READY == mState )
914 bool allWindowsHidden = true;
916 for( auto window : mWindows )
918 if ( window->IsVisible() )
920 allWindowsHidden = false;
925 // Only pause the adaptor when all the windows are hidden
926 if( allWindowsHidden )
928 if( mState == RUNNING )
932 // Adaptor cannot be resumed until any window is shown
933 mState = PAUSED_WHILE_HIDDEN;
935 else // mState is READY
937 // Pause the adaptor after the state gets RUNNING
938 mState = PAUSED_WHILE_INITIALIZING;
943 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
948 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
952 // Dali::Internal::Adaptor::Adaptor::OnDamaged
953 void Adaptor::OnDamaged( const DamageArea& area )
955 // This is needed for the case where Dali window is partially obscured
956 RequestUpdate( false );
959 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
961 mResizedSignal.Emit( mAdaptor );
964 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
966 // Flush the event queue to give the update-render thread chance
967 // to start processing messages for new camera setup etc as soon as possible
970 mThreadController->ResizeSurface();
973 void Adaptor::NotifySceneCreated()
975 GetCore().SceneCreated();
977 // Flush the event queue to give the update-render thread chance
978 // to start processing messages for new camera setup etc as soon as possible
981 // Start thread controller after the scene has been created
982 mThreadController->Start();
984 // Process after surface is created (registering to remote surface provider if required)
985 SurfaceInitialized();
987 if( mState != PAUSED_WHILE_INITIALIZING )
991 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
999 mState = PAUSED_WHILE_HIDDEN;
1001 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1005 void Adaptor::NotifyLanguageChanged()
1007 mLanguageChangedSignal.Emit( mAdaptor );
1010 void Adaptor::RenderOnce()
1012 RequestUpdateOnce();
1015 const LogFactoryInterface& Adaptor::GetLogFactory()
1017 return *mEnvironmentOptions;
1020 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1022 GetCore().RegisterProcessor(processor);
1025 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1027 GetCore().UnregisterProcessor(processor);
1030 bool Adaptor::IsMultipleWindowSupported() const
1032 return mConfigurationManager->IsMultipleWindowSupported();
1035 void Adaptor::RequestUpdateOnce()
1037 if( mThreadController )
1039 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1043 bool Adaptor::ProcessCoreEventsFromIdle()
1045 ProcessCoreEvents();
1047 // the idle handle automatically un-installs itself
1048 mNotificationOnIdleInstalled = false;
1053 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1055 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1057 for( auto window : mWindows )
1059 if ( scene == window->GetScene() )
1068 Dali::WindowContainer Adaptor::GetWindows() const
1070 Dali::WindowContainer windows;
1072 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1074 // Downcast to Dali::Window
1075 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1078 windows.push_back( window );
1085 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1087 Dali::SceneHolderList sceneHolderList;
1089 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1091 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1094 return sceneHolderList;
1097 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1099 mLanguageChangedSignal(),
1100 mWindowCreatedSignal(),
1101 mAdaptor( adaptor ),
1104 mThreadController( nullptr ),
1105 mGraphics( nullptr ),
1106 mDisplayConnection( nullptr ),
1108 mConfigurationManager( nullptr ),
1109 mPlatformAbstraction( nullptr ),
1110 mCallbackManager( nullptr ),
1111 mNotificationOnIdleInstalled( false ),
1112 mNotificationTrigger( nullptr ),
1113 mDaliFeedbackPlugin(),
1114 mFeedbackController( nullptr ),
1117 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1118 mPerformanceInterface( nullptr ),
1121 mTriggerEventFactory(),
1122 mObjectProfiler( nullptr ),
1124 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1125 mUseRemoteSurface( false )
1127 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1128 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1130 gThreadLocalAdaptor = this;
1133 void Adaptor::SetRootLayoutDirection( std::string locale )
1135 Dali::Stage stage = Dali::Stage::GetCurrent();
1137 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1138 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1141 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1143 bool idleAdded( false );
1145 // Only add an idle if the Adaptor is actually running
1146 if( RUNNING == mState || READY == mState || forceAdd )
1148 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1154 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1156 mCallbackManager->RemoveIdleEntererCallback( callback );
1159 } // namespace Adaptor
1161 } // namespace Internal