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>
25 #include <dali/public-api/common/stage.h>
26 #include <dali/public-api/actors/layer.h>
27 #include <dali/public-api/object/any.h>
28 #include <dali/devel-api/actors/actor-devel.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/integration-api/core.h>
31 #include <dali/integration-api/context-notifier.h>
32 #include <dali/integration-api/profiling.h>
33 #include <dali/integration-api/input-options.h>
34 #include <dali/integration-api/events/key-event-integ.h>
35 #include <dali/integration-api/events/touch-event-integ.h>
36 #include <dali/integration-api/events/wheel-event-integ.h>
37 #include <dali/integration-api/processor-interface.h>
40 #include <dali/public-api/dali-adaptor-common.h>
41 #include <dali/internal/system/common/thread-controller.h>
42 #include <dali/internal/system/common/performance-interface-factory.h>
43 #include <dali/internal/adaptor/common/lifecycle-observer.h>
44 #include <dali/internal/adaptor/common/thread-controller-interface.h>
46 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
47 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
49 #include <dali/devel-api/text-abstraction/font-client.h>
51 #include <dali/internal/system/common/callback-manager.h>
52 #include <dali/internal/accessibility/common/tts-player-impl.h>
53 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
54 #include <dali/internal/window-system/common/event-handler.h>
55 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
56 #include <dali/internal/graphics/gles/gl-implementation.h>
57 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
58 #include <dali/internal/graphics/common/egl-image-extensions.h>
59 #include <dali/internal/clipboard/common/clipboard-impl.h>
60 #include <dali/internal/system/common/object-profiler.h>
61 #include <dali/internal/window-system/common/display-connection.h>
62 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
63 #include <dali/internal/window-system/common/window-impl.h>
64 #include <dali/internal/window-system/common/window-render-surface.h>
66 #include <dali/internal/system/common/logging.h>
68 #include <dali/internal/system/common/locale-utils.h>
69 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
70 #include <dali/internal/imaging/common/image-loader.h>
72 #include <dali/internal/system/common/configuration-manager.h>
73 #include <dali/internal/system/common/environment-variables.h>
75 using Dali::TextAbstraction::FontClient;
77 extern std::string GetSystemCachePath();
91 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
93 } // unnamed namespace
95 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
97 Dali::Adaptor* adaptor = new Dali::Adaptor;
98 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
99 adaptor->mImpl = impl;
101 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
102 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
104 impl->Initialize( graphicsFactory, configuration );
105 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
110 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
112 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
113 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
114 windowImpl.SetAdaptor( *adaptor );
118 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
120 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
121 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
122 adaptor->mImpl = impl;
124 impl->Initialize( graphicsFactory, configuration );
129 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
131 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
132 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
133 windowImpl.SetAdaptor( *adaptor );
137 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
139 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
140 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
141 mEnvironmentOptions->SetLogFunction( logFunction );
142 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
144 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
147 GetDataStoragePath( path );
148 mPlatformAbstraction->SetDataStoragePath( path );
150 if( mEnvironmentOptions->PerformanceServerRequired() )
152 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
155 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
156 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
158 mCallbackManager = CallbackManager::New();
160 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
162 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
164 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
165 mGraphics->Initialize( mEnvironmentOptions );
167 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
168 auto eglGraphics = static_cast<EglGraphics *>( graphics );
170 // This will only be created once
171 eglGraphics->Create();
173 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
174 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
175 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
177 mCore = Integration::Core::New( *this,
178 *mPlatformAbstraction,
181 eglContextHelperImpl,
182 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
183 mGraphics->GetDepthBufferRequired(),
184 mGraphics->GetStencilBufferRequired(),
185 mGraphics->GetPartialUpdateRequired() );
187 defaultWindow->SetAdaptor( Get() );
189 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
191 mWindowCreatedSignal.Emit( defaultSceneHolder );
193 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
194 if( 0u < timeInterval )
196 mObjectProfiler = new ObjectProfiler( timeInterval );
199 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
201 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
203 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
205 // Should be called after Core creation
206 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
208 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
210 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
212 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
214 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
216 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
218 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
220 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
222 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
224 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
226 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
228 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
230 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
232 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
234 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
236 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
238 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
240 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
242 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
244 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
246 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
248 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
250 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
252 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
254 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
256 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
258 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
260 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
262 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
264 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
266 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
268 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
270 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
272 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
274 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
276 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
278 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
280 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
282 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
284 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
286 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
288 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
290 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
292 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
294 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
296 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
298 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
300 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
303 std::string systemCachePath = GetSystemCachePath();
304 if( ! systemCachePath.empty() )
306 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
307 if ( 0 != dir_err && errno != EEXIST )
309 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
314 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
319 // Ensure stop status
322 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
323 gThreadLocalAdaptor = NULL;
325 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
327 (*iter)->OnDestroy();
330 // Clear out all the handles to Windows
333 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
334 delete mObjectProfiler;
338 delete mDisplayConnection;
339 delete mPlatformAbstraction;
340 delete mCallbackManager;
341 delete mPerformanceInterface;
343 mGraphics->Destroy();
345 // uninstall it on this thread (main actor thread)
346 Dali::Integration::Log::UninstallLogFunction();
348 // Delete environment options if we own it
349 if( mEnvironmentOptionsOwned )
351 delete mEnvironmentOptions;
355 void Adaptor::Start()
357 // It doesn't support restart after stop at this moment to support restarting, need more testing
358 if( READY != mState )
365 SetupSystemInformation();
367 // Start the callback manager
368 mCallbackManager->Start();
370 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
372 unsigned int dpiHor, dpiVer;
375 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
377 // set the DPI value for font rendering
378 FontClient fontClient = FontClient::Get();
379 fontClient.SetDpi( dpiHor, dpiVer );
381 // Initialize the thread controller
382 mThreadController->Initialize();
384 // Set max texture size
385 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
387 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
391 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
392 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
395 ProcessCoreEvents(); // Ensure any startup messages are processed.
397 // Initialize the image loader plugin
398 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
400 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
406 // Dali::Internal::Adaptor::Adaptor::Pause
407 void Adaptor::Pause()
409 // Only pause the adaptor if we're actually running.
410 if( RUNNING == mState )
412 // Inform observers that we are about to be paused.
413 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
418 // Pause all windows event handlers when adaptor paused
419 for( auto window : mWindows )
424 mThreadController->Pause();
427 // Ensure any messages queued during pause callbacks are processed by doing another update.
430 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
434 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
438 // Dali::Internal::Adaptor::Adaptor::Resume
439 void Adaptor::Resume()
441 // Only resume the adaptor if we are in the suspended state.
442 if( PAUSED == mState )
446 // Reset the event handlers when adaptor resumed
447 for( auto window : mWindows )
452 // Inform observers that we have resumed.
453 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
458 // Trigger processing of events queued up while paused
459 mCore->ProcessEvents();
461 // Do at end to ensure our first update/render after resumption includes the processed messages as well
462 mThreadController->Resume();
464 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
468 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
474 if( RUNNING == mState ||
476 PAUSED_WHILE_HIDDEN == mState )
478 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
483 mThreadController->Stop();
485 // Delete the TTS player
486 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
490 mTtsPlayers[i].Reset();
494 // Destroy the image loader plugin
495 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
497 delete mNotificationTrigger;
498 mNotificationTrigger = NULL;
500 mCallbackManager->Stop();
504 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
508 void Adaptor::ContextLost()
510 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
513 void Adaptor::ContextRegained()
515 // Inform core, so that texture resources can be reloaded
516 mCore->RecoverFromContextLoss();
518 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
521 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
523 Integration::Point convertedPoint( point );
524 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
527 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
529 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
530 mWindows.front()->FeedWheelEvent( event );
533 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
535 Integration::KeyEvent convertedEvent( keyEvent );
536 mWindows.front()->FeedKeyEvent( convertedEvent );
539 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
541 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
542 for( auto windowPtr : mWindows )
544 if( windowPtr == windowImpl ) // the window is not deleted
546 mResizedSignal.Emit( mAdaptor );
548 windowImpl->SetSurface( &newSurface );
550 // Flush the event queue to give the update-render thread chance
551 // to start processing messages for new camera setup etc as soon as possible
554 // This method blocks until the render thread has completed the replace.
555 mThreadController->ReplaceSurface( &newSurface );
561 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
563 // Flush the event queue to give the update-render thread chance
564 // to start processing messages for new camera setup etc as soon as possible
567 // This method blocks until the render thread has finished rendering the current surface.
568 mThreadController->DeleteSurface( &surface );
571 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
573 return *mWindows.front()->GetSurface();
576 void Adaptor::ReleaseSurfaceLock()
578 mWindows.front()->GetSurface()->ReleaseLock();
581 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
583 if( !mTtsPlayers[mode] )
585 // Create the TTS player when it needed, because it can reduce launching time.
586 mTtsPlayers[mode] = TtsPlayer::New(mode);
589 return mTtsPlayers[mode];
592 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
594 bool idleAdded(false);
596 // Only add an idle if the Adaptor is actually running
597 if( RUNNING == mState || READY == mState || forceAdd )
599 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
605 void Adaptor::RemoveIdle( CallbackBase* callback )
607 mCallbackManager->RemoveIdleCallback( callback );
610 void Adaptor::ProcessIdle()
612 bool idleProcessed = mCallbackManager->ProcessIdle();
613 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
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 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
631 mThreadController->AddSurface( surface );
633 mWindowCreatedSignal.Emit( childWindow );
638 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
640 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
641 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
643 if( *iter == &windowImpl )
645 mWindows.erase( iter );
653 bool Adaptor::RemoveWindow( std::string childWindowName )
655 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
657 if( ( *iter )->GetName() == childWindowName )
659 mWindows.erase( iter );
667 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
669 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
671 if( ( *iter )->GetId() == childWindow->GetId() )
673 mWindows.erase( iter );
681 Dali::Adaptor& Adaptor::Get()
683 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
684 return gThreadLocalAdaptor->mAdaptor;
687 bool Adaptor::IsAvailable()
689 return gThreadLocalAdaptor != NULL;
692 void Adaptor::SceneCreated()
694 mCore->SceneCreated();
697 Dali::Integration::Core& Adaptor::GetCore()
702 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
704 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
707 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
709 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
710 return *mDisplayConnection;
713 GraphicsInterface& Adaptor::GetGraphicsInterface()
715 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
716 return *( mGraphics.get() );
719 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
721 return *mPlatformAbstraction;
724 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
726 return *mNotificationTrigger;
729 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
731 return mSocketFactory;
734 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
736 if( !mWindows.empty() )
738 return mWindows.front()->GetSurface();
744 TraceInterface& Adaptor::GetKernelTraceInterface()
746 return mKernelTracer;
749 TraceInterface& Adaptor::GetSystemTraceInterface()
751 return mSystemTracer;
754 PerformanceInterface* Adaptor::GetPerformanceInterface()
756 return mPerformanceInterface;
759 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
761 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
762 return *mPlatformAbstraction;
765 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
770 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
772 if( mTtsPlayers[mode] )
774 mTtsPlayers[mode].Reset();
778 Any Adaptor::GetNativeWindowHandle()
780 return mWindows.front()->GetNativeHandle();
783 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
785 Any nativeWindowHandle;
787 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
789 for( auto sceneHolder : mWindows )
791 if ( scene == sceneHolder->GetScene() )
793 nativeWindowHandle = sceneHolder->GetNativeHandle();
798 return nativeWindowHandle;
801 Any Adaptor::GetGraphicsDisplay()
807 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
808 auto eglGraphics = static_cast<EglGraphics *>( graphics );
810 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
811 display = eglImpl.GetDisplay();
817 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
819 mUseRemoteSurface = useRemoteSurface;
822 void Adaptor::AddObserver( LifeCycleObserver& observer )
824 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
826 if ( match == mObservers.end() )
828 mObservers.push_back( &observer );
832 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
834 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
836 if ( match != mObservers.end() )
838 mObservers.erase( match );
842 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
846 mCore->QueueEvent(event);
850 void Adaptor::ProcessCoreEvents()
854 if( mPerformanceInterface )
856 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
859 mCore->ProcessEvents();
861 if( mPerformanceInterface )
863 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
868 void Adaptor::RequestUpdate( bool forceUpdate )
874 mThreadController->RequestUpdate();
878 case PAUSED_WHILE_HIDDEN:
882 // Update (and resource upload) without rendering
883 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
895 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
897 // Only request a notification if the Adaptor is actually running
898 // and we haven't installed the idle notification
899 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
901 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
905 void Adaptor::OnWindowShown()
907 if( PAUSED_WHILE_HIDDEN == mState )
909 // Adaptor can now be resumed
914 // Force a render task
917 else if( RUNNING == mState )
919 // Force a render task
922 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
926 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
930 void Adaptor::OnWindowHidden()
932 if( RUNNING == mState || READY == mState )
934 bool allWindowsHidden = true;
936 for( auto window : mWindows )
938 if ( window->IsVisible() )
940 allWindowsHidden = false;
945 // Only pause the adaptor when all the windows are hidden
946 if( allWindowsHidden )
948 if( mState == RUNNING )
952 // Adaptor cannot be resumed until any window is shown
953 mState = PAUSED_WHILE_HIDDEN;
955 else // mState is READY
957 // Pause the adaptor after the state gets RUNNING
958 mState = PAUSED_WHILE_INITIALIZING;
963 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
968 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
972 // Dali::Internal::Adaptor::Adaptor::OnDamaged
973 void Adaptor::OnDamaged( const DamageArea& area )
975 // This is needed for the case where Dali window is partially obscured
976 RequestUpdate( false );
979 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
981 mResizedSignal.Emit( mAdaptor );
984 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
986 // Nofify surface resizing before flushing event queue
987 mThreadController->ResizeSurface();
989 // Flush the event queue to give the update-render thread chance
990 // to start processing messages for new camera setup etc as soon as possible
994 void Adaptor::NotifySceneCreated()
996 GetCore().SceneCreated();
998 // Flush the event queue to give the update-render thread chance
999 // to start processing messages for new camera setup etc as soon as possible
1000 ProcessCoreEvents();
1002 // Start thread controller after the scene has been created
1003 mThreadController->Start();
1005 // Process after surface is created (registering to remote surface provider if required)
1006 SurfaceInitialized();
1008 if( mState != PAUSED_WHILE_INITIALIZING )
1012 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1020 mState = PAUSED_WHILE_HIDDEN;
1022 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1026 void Adaptor::NotifyLanguageChanged()
1028 mLanguageChangedSignal.Emit( mAdaptor );
1031 void Adaptor::RenderOnce()
1033 if( mThreadController )
1035 UpdateMode updateMode;
1036 if( mThreadMode == ThreadMode::NORMAL )
1038 updateMode = UpdateMode::NORMAL;
1042 updateMode = UpdateMode::FORCE_RENDER;
1044 ProcessCoreEvents();
1046 mThreadController->RequestUpdateOnce( updateMode );
1050 const LogFactoryInterface& Adaptor::GetLogFactory()
1052 return *mEnvironmentOptions;
1055 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1057 GetCore().RegisterProcessor(processor);
1060 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1062 GetCore().UnregisterProcessor(processor);
1065 bool Adaptor::IsMultipleWindowSupported() const
1067 return mConfigurationManager->IsMultipleWindowSupported();
1070 void Adaptor::RequestUpdateOnce()
1072 if( mThreadController )
1074 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1078 bool Adaptor::ProcessCoreEventsFromIdle()
1080 ProcessCoreEvents();
1082 // the idle handle automatically un-installs itself
1083 mNotificationOnIdleInstalled = false;
1088 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1090 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1092 for( auto window : mWindows )
1094 if ( scene == window->GetScene() )
1103 Dali::WindowContainer Adaptor::GetWindows() const
1105 Dali::WindowContainer windows;
1107 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1109 // Downcast to Dali::Window
1110 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1113 windows.push_back( window );
1120 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1122 Dali::SceneHolderList sceneHolderList;
1124 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1126 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1129 return sceneHolderList;
1132 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1134 mLanguageChangedSignal(),
1135 mWindowCreatedSignal(),
1136 mAdaptor( adaptor ),
1139 mThreadController( nullptr ),
1140 mGraphics( nullptr ),
1141 mDisplayConnection( nullptr ),
1143 mConfigurationManager( nullptr ),
1144 mPlatformAbstraction( nullptr ),
1145 mCallbackManager( nullptr ),
1146 mNotificationOnIdleInstalled( false ),
1147 mNotificationTrigger( nullptr ),
1148 mDaliFeedbackPlugin(),
1149 mFeedbackController( nullptr ),
1152 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1153 mPerformanceInterface( nullptr ),
1156 mObjectProfiler( nullptr ),
1158 mThreadMode( ThreadMode::NORMAL ),
1159 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1160 mUseRemoteSurface( false )
1162 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1163 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1165 gThreadLocalAdaptor = this;
1168 void Adaptor::SetRootLayoutDirection( std::string locale )
1170 Dali::Stage stage = Dali::Stage::GetCurrent();
1172 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1173 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1176 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1178 bool idleAdded( false );
1180 // Only add an idle if the Adaptor is actually running
1181 if( RUNNING == mState || READY == mState || forceAdd )
1183 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1189 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1191 mCallbackManager->RemoveIdleEntererCallback( callback );
1194 } // namespace Adaptor
1196 } // namespace Internal