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() );
192 defaultWindow->SetAdaptor( Get() );
194 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
196 mWindowCreatedSignal.Emit( defaultSceneHolder );
198 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
199 if( 0u < timeInterval )
201 mObjectProfiler = new ObjectProfiler( timeInterval );
204 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
206 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
208 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
210 // Should be called after Core creation
211 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
213 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
215 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
217 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
219 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
221 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
223 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
225 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
227 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
229 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
231 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
233 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
235 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
237 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
239 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
241 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
243 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
245 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
247 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
249 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
251 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
253 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
255 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
257 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
259 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
261 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
263 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
265 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
267 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
269 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
271 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
273 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
275 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
277 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
279 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
281 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
283 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
285 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
287 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
289 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
291 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
293 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
295 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
297 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
299 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
301 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
303 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
305 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
308 std::string systemCachePath = GetSystemCachePath();
309 if( ! systemCachePath.empty() )
311 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
314 printf( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
319 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
324 // Ensure stop status
327 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
328 gThreadLocalAdaptor = NULL;
330 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
332 (*iter)->OnDestroy();
335 // Clear out all the handles to Windows
338 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
339 delete mObjectProfiler;
343 delete mDisplayConnection;
344 delete mPlatformAbstraction;
345 delete mCallbackManager;
346 delete mPerformanceInterface;
348 mGraphics->Destroy();
350 // uninstall it on this thread (main actor thread)
351 Dali::Integration::Log::UninstallLogFunction();
353 // Delete environment options if we own it
354 if( mEnvironmentOptionsOwned )
356 delete mEnvironmentOptions;
360 void Adaptor::Start()
362 // It doesn't support restart after stop at this moment to support restarting, need more testing
363 if( READY != mState )
370 SetupSystemInformation();
372 // Start the callback manager
373 mCallbackManager->Start();
375 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
377 unsigned int dpiHor, dpiVer;
380 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
382 // set the DPI value for font rendering
383 FontClient fontClient = FontClient::Get();
384 fontClient.SetDpi( dpiHor, dpiVer );
386 // Initialize the thread controller
387 mThreadController->Initialize();
389 // Set max texture size
390 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
392 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
396 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
397 setenv( DALI_ENV_MAX_TEXTURE_SIZE, std::to_string( maxTextureSize ).c_str(), 1 );
398 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
401 ProcessCoreEvents(); // Ensure any startup messages are processed.
403 // Initialize the image loader plugin
404 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
406 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
412 // Dali::Internal::Adaptor::Adaptor::Pause
413 void Adaptor::Pause()
415 // Only pause the adaptor if we're actually running.
416 if( RUNNING == mState )
418 // Inform observers that we are about to be paused.
419 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
424 // Pause all windows event handlers when adaptor paused
425 for( auto window : mWindows )
430 mThreadController->Pause();
433 // Ensure any messages queued during pause callbacks are processed by doing another update.
436 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
440 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
444 // Dali::Internal::Adaptor::Adaptor::Resume
445 void Adaptor::Resume()
447 // Only resume the adaptor if we are in the suspended state.
448 if( PAUSED == mState )
452 // Reset the event handlers when adaptor resumed
453 for( auto window : mWindows )
458 // Inform observers that we have resumed.
459 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
464 // Trigger processing of events queued up while paused
465 mCore->ProcessEvents();
467 // Do at end to ensure our first update/render after resumption includes the processed messages as well
468 mThreadController->Resume();
470 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
474 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
480 if( RUNNING == mState ||
482 PAUSED_WHILE_HIDDEN == mState )
484 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
489 mThreadController->Stop();
491 // Delete the TTS player
492 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
496 mTtsPlayers[i].Reset();
500 // Destroy the image loader plugin
501 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
503 delete mNotificationTrigger;
504 mNotificationTrigger = NULL;
506 mCallbackManager->Stop();
510 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
514 void Adaptor::ContextLost()
516 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
519 void Adaptor::ContextRegained()
521 // Inform core, so that texture resources can be reloaded
522 mCore->RecoverFromContextLoss();
524 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
527 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
529 Integration::Point convertedPoint( point );
530 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
533 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
535 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
536 mWindows.front()->FeedWheelEvent( event );
539 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
541 Integration::KeyEvent convertedEvent( keyEvent );
542 mWindows.front()->FeedKeyEvent( convertedEvent );
545 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
547 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
548 for( auto windowPtr : mWindows )
550 if( windowPtr == windowImpl ) // the window is not deleted
552 mResizedSignal.Emit( mAdaptor );
554 windowImpl->SetSurface( &newSurface );
556 // Flush the event queue to give the update-render thread chance
557 // to start processing messages for new camera setup etc as soon as possible
560 // This method blocks until the render thread has completed the replace.
561 mThreadController->ReplaceSurface( &newSurface );
567 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
569 // Flush the event queue to give the update-render thread chance
570 // to start processing messages for new camera setup etc as soon as possible
573 // This method blocks until the render thread has finished rendering the current surface.
574 mThreadController->DeleteSurface( &surface );
577 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
579 return *mWindows.front()->GetSurface();
582 void Adaptor::ReleaseSurfaceLock()
584 mWindows.front()->GetSurface()->ReleaseLock();
587 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
589 if( !mTtsPlayers[mode] )
591 // Create the TTS player when it needed, because it can reduce launching time.
592 mTtsPlayers[mode] = TtsPlayer::New(mode);
595 return mTtsPlayers[mode];
598 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
600 bool idleAdded(false);
602 // Only add an idle if the Adaptor is actually running
603 if( RUNNING == mState || READY == mState || forceAdd )
605 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
611 void Adaptor::RemoveIdle( CallbackBase* callback )
613 mCallbackManager->RemoveIdleCallback( callback );
616 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
618 mThreadController->SetPreRenderCallback( callback );
621 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
623 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
624 windowImpl.SetAdaptor( Get() );
626 // Add the new Window to the container - the order is not important
627 mWindows.push_back( &windowImpl );
629 mWindowCreatedSignal.Emit( childWindow );
634 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
636 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
637 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
639 if( *iter == &windowImpl )
641 mWindows.erase( iter );
649 bool Adaptor::RemoveWindow( std::string childWindowName )
651 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
653 if( ( *iter )->GetName() == childWindowName )
655 mWindows.erase( iter );
663 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
665 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
667 if( ( *iter )->GetId() == childWindow->GetId() )
669 mWindows.erase( iter );
677 Dali::Adaptor& Adaptor::Get()
679 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
680 return gThreadLocalAdaptor->mAdaptor;
683 bool Adaptor::IsAvailable()
685 return gThreadLocalAdaptor != NULL;
688 void Adaptor::SceneCreated()
690 mCore->SceneCreated();
693 Dali::Integration::Core& Adaptor::GetCore()
698 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
700 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
703 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
705 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
706 return *mDisplayConnection;
709 GraphicsInterface& Adaptor::GetGraphicsInterface()
711 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
715 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
717 return *mPlatformAbstraction;
720 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
722 return *mNotificationTrigger;
725 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
727 return mTriggerEventFactory;
730 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
732 return mSocketFactory;
735 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
737 if( !mWindows.empty() )
739 return mWindows.front()->GetSurface();
745 TraceInterface& Adaptor::GetKernelTraceInterface()
747 return mKernelTracer;
750 TraceInterface& Adaptor::GetSystemTraceInterface()
752 return mSystemTracer;
755 PerformanceInterface* Adaptor::GetPerformanceInterface()
757 return mPerformanceInterface;
760 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
762 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
763 return *mPlatformAbstraction;
766 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
768 if( mTtsPlayers[mode] )
770 mTtsPlayers[mode].Reset();
774 Any Adaptor::GetNativeWindowHandle()
776 return mWindows.front()->GetNativeHandle();
779 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
781 Any nativeWindowHandle;
783 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
785 for( auto sceneHolder : mWindows )
787 if ( scene == sceneHolder->GetScene() )
789 nativeWindowHandle = sceneHolder->GetNativeHandle();
794 return nativeWindowHandle;
797 Any Adaptor::GetGraphicsDisplay()
803 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
805 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
806 display = eglImpl.GetDisplay();
812 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
814 mUseRemoteSurface = useRemoteSurface;
817 void Adaptor::AddObserver( LifeCycleObserver& observer )
819 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
821 if ( match == mObservers.end() )
823 mObservers.push_back( &observer );
827 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
829 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
831 if ( match != mObservers.end() )
833 mObservers.erase( match );
837 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
841 mCore->QueueEvent(event);
845 void Adaptor::ProcessCoreEvents()
849 if( mPerformanceInterface )
851 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
854 mCore->ProcessEvents();
856 if( mPerformanceInterface )
858 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
863 void Adaptor::RequestUpdate( bool forceUpdate )
869 mThreadController->RequestUpdate();
873 case PAUSED_WHILE_HIDDEN:
877 // Update (and resource upload) without rendering
878 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
890 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
892 // Only request a notification if the Adaptor is actually running
893 // and we haven't installed the idle notification
894 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
896 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
900 void Adaptor::OnWindowShown()
902 if( PAUSED_WHILE_HIDDEN == mState )
904 // Adaptor can now be resumed
909 // Force a render task
912 else if( RUNNING == mState )
914 // Force a render task
917 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
921 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
925 void Adaptor::OnWindowHidden()
927 if( RUNNING == mState || READY == mState )
929 bool allWindowsHidden = true;
931 for( auto window : mWindows )
933 if ( window->IsVisible() )
935 allWindowsHidden = false;
940 // Only pause the adaptor when all the windows are hidden
941 if( allWindowsHidden )
943 if( mState == RUNNING )
947 // Adaptor cannot be resumed until any window is shown
948 mState = PAUSED_WHILE_HIDDEN;
950 else // mState is READY
952 // Pause the adaptor after the state gets RUNNING
953 mState = PAUSED_WHILE_INITIALIZING;
958 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
963 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
967 // Dali::Internal::Adaptor::Adaptor::OnDamaged
968 void Adaptor::OnDamaged( const DamageArea& area )
970 // This is needed for the case where Dali window is partially obscured
971 RequestUpdate( false );
974 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
976 mResizedSignal.Emit( mAdaptor );
979 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
981 // Flush the event queue to give the update-render thread chance
982 // to start processing messages for new camera setup etc as soon as possible
985 mThreadController->ResizeSurface();
988 void Adaptor::NotifySceneCreated()
990 GetCore().SceneCreated();
992 // Flush the event queue to give the update-render thread chance
993 // to start processing messages for new camera setup etc as soon as possible
996 // Start thread controller after the scene has been created
997 mThreadController->Start();
999 // Process after surface is created (registering to remote surface provider if required)
1000 SurfaceInitialized();
1002 if( mState != PAUSED_WHILE_INITIALIZING )
1006 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1014 mState = PAUSED_WHILE_HIDDEN;
1016 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1020 void Adaptor::NotifyLanguageChanged()
1022 mLanguageChangedSignal.Emit( mAdaptor );
1025 void Adaptor::RenderOnce()
1027 RequestUpdateOnce();
1030 const LogFactoryInterface& Adaptor::GetLogFactory()
1032 return *mEnvironmentOptions;
1035 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1037 GetCore().RegisterProcessor(processor);
1040 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1042 GetCore().UnregisterProcessor(processor);
1045 bool Adaptor::IsMultipleWindowSupported() const
1047 return mConfigurationManager->IsMultipleWindowSupported();
1050 void Adaptor::RequestUpdateOnce()
1052 if( mThreadController )
1054 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1058 bool Adaptor::ProcessCoreEventsFromIdle()
1060 ProcessCoreEvents();
1062 // the idle handle automatically un-installs itself
1063 mNotificationOnIdleInstalled = false;
1068 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1070 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1072 for( auto window : mWindows )
1074 if ( scene == window->GetScene() )
1083 Dali::WindowContainer Adaptor::GetWindows() const
1085 Dali::WindowContainer windows;
1087 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1089 // Downcast to Dali::Window
1090 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1093 windows.push_back( window );
1100 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1102 Dali::SceneHolderList sceneHolderList;
1104 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1106 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1109 return sceneHolderList;
1112 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1114 mLanguageChangedSignal(),
1115 mWindowCreatedSignal(),
1116 mAdaptor( adaptor ),
1119 mThreadController( nullptr ),
1120 mGraphics( nullptr ),
1121 mDisplayConnection( nullptr ),
1123 mConfigurationManager( nullptr ),
1124 mPlatformAbstraction( nullptr ),
1125 mCallbackManager( nullptr ),
1126 mNotificationOnIdleInstalled( false ),
1127 mNotificationTrigger( nullptr ),
1128 mDaliFeedbackPlugin(),
1129 mFeedbackController( nullptr ),
1132 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1133 mPerformanceInterface( nullptr ),
1136 mTriggerEventFactory(),
1137 mObjectProfiler( nullptr ),
1139 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1140 mUseRemoteSurface( false )
1142 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1143 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1145 gThreadLocalAdaptor = this;
1148 void Adaptor::SetRootLayoutDirection( std::string locale )
1150 Dali::Stage stage = Dali::Stage::GetCurrent();
1152 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1153 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1156 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1158 bool idleAdded( false );
1160 // Only add an idle if the Adaptor is actually running
1161 if( RUNNING == mState || READY == mState || forceAdd )
1163 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1169 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1171 mCallbackManager->RemoveIdleEntererCallback( callback );
1174 } // namespace Adaptor
1176 } // namespace Internal