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 if( mEnvironmentOptions->PerformanceServerRequired() )
150 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
153 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
154 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
156 mCallbackManager = CallbackManager::New();
158 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
160 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
162 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
163 mGraphics->Initialize( mEnvironmentOptions );
165 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
166 auto eglGraphics = static_cast<EglGraphics *>( graphics );
168 // This will only be created once
169 eglGraphics->Create();
171 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
172 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
173 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
175 mCore = Integration::Core::New( *this,
176 *mPlatformAbstraction,
179 eglContextHelperImpl,
180 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
181 mGraphics->GetDepthBufferRequired(),
182 mGraphics->GetStencilBufferRequired() );
184 defaultWindow->SetAdaptor( Get() );
186 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
188 mWindowCreatedSignal.Emit( defaultSceneHolder );
190 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
191 if( 0u < timeInterval )
193 mObjectProfiler = new ObjectProfiler( timeInterval );
196 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
198 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
200 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
202 // Should be called after Core creation
203 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
205 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
207 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
209 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
211 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
213 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
215 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
217 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
219 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
221 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
223 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
225 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
227 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
229 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
231 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
233 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
235 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
237 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
239 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
241 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
243 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
245 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
247 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
249 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
251 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
253 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
255 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
257 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
259 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
261 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
263 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
265 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
267 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
269 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
271 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
273 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
275 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
277 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
279 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
281 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
283 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
285 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
287 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
289 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
291 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
293 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
295 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
297 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
300 std::string systemCachePath = GetSystemCachePath();
301 if( ! systemCachePath.empty() )
303 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
306 printf( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
311 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
316 // Ensure stop status
319 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
320 gThreadLocalAdaptor = NULL;
322 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
324 (*iter)->OnDestroy();
327 // Clear out all the handles to Windows
330 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
331 delete mObjectProfiler;
335 delete mDisplayConnection;
336 delete mPlatformAbstraction;
337 delete mCallbackManager;
338 delete mPerformanceInterface;
340 mGraphics->Destroy();
342 // uninstall it on this thread (main actor thread)
343 Dali::Integration::Log::UninstallLogFunction();
345 // Delete environment options if we own it
346 if( mEnvironmentOptionsOwned )
348 delete mEnvironmentOptions;
352 void Adaptor::Start()
354 // It doesn't support restart after stop at this moment to support restarting, need more testing
355 if( READY != mState )
362 SetupSystemInformation();
364 // Start the callback manager
365 mCallbackManager->Start();
367 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
369 unsigned int dpiHor, dpiVer;
372 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
374 // set the DPI value for font rendering
375 FontClient fontClient = FontClient::Get();
376 fontClient.SetDpi( dpiHor, dpiVer );
378 // Initialize the thread controller
379 mThreadController->Initialize();
381 // Set max texture size
382 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
384 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
388 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
389 setenv( DALI_ENV_MAX_TEXTURE_SIZE, std::to_string( maxTextureSize ).c_str(), 1 );
390 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
393 ProcessCoreEvents(); // Ensure any startup messages are processed.
395 // Initialize the image loader plugin
396 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
398 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
404 // Dali::Internal::Adaptor::Adaptor::Pause
405 void Adaptor::Pause()
407 // Only pause the adaptor if we're actually running.
408 if( RUNNING == mState )
410 // Inform observers that we are about to be paused.
411 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
416 // Pause all windows event handlers when adaptor paused
417 for( auto window : mWindows )
422 mThreadController->Pause();
425 // Ensure any messages queued during pause callbacks are processed by doing another update.
428 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
432 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
436 // Dali::Internal::Adaptor::Adaptor::Resume
437 void Adaptor::Resume()
439 // Only resume the adaptor if we are in the suspended state.
440 if( PAUSED == mState )
444 // Reset the event handlers when adaptor resumed
445 for( auto window : mWindows )
450 // Inform observers that we have resumed.
451 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
456 // Trigger processing of events queued up while paused
457 mCore->ProcessEvents();
459 // Do at end to ensure our first update/render after resumption includes the processed messages as well
460 mThreadController->Resume();
462 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
466 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
472 if( RUNNING == mState ||
474 PAUSED_WHILE_HIDDEN == mState )
476 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
481 mThreadController->Stop();
483 // Delete the TTS player
484 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
488 mTtsPlayers[i].Reset();
492 // Destroy the image loader plugin
493 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
495 delete mNotificationTrigger;
496 mNotificationTrigger = NULL;
498 mCallbackManager->Stop();
502 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
506 void Adaptor::ContextLost()
508 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
511 void Adaptor::ContextRegained()
513 // Inform core, so that texture resources can be reloaded
514 mCore->RecoverFromContextLoss();
516 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
519 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
521 Integration::Point convertedPoint( point );
522 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
525 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
527 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
528 mWindows.front()->FeedWheelEvent( event );
531 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
533 Integration::KeyEvent convertedEvent( keyEvent );
534 mWindows.front()->FeedKeyEvent( convertedEvent );
537 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
539 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
540 for( auto windowPtr : mWindows )
542 if( windowPtr == windowImpl ) // the window is not deleted
544 mResizedSignal.Emit( mAdaptor );
546 windowImpl->SetSurface( &newSurface );
548 // Flush the event queue to give the update-render thread chance
549 // to start processing messages for new camera setup etc as soon as possible
552 // This method blocks until the render thread has completed the replace.
553 mThreadController->ReplaceSurface( &newSurface );
559 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
561 // Flush the event queue to give the update-render thread chance
562 // to start processing messages for new camera setup etc as soon as possible
565 // This method blocks until the render thread has finished rendering the current surface.
566 mThreadController->DeleteSurface( &surface );
569 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
571 return *mWindows.front()->GetSurface();
574 void Adaptor::ReleaseSurfaceLock()
576 mWindows.front()->GetSurface()->ReleaseLock();
579 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
581 if( !mTtsPlayers[mode] )
583 // Create the TTS player when it needed, because it can reduce launching time.
584 mTtsPlayers[mode] = TtsPlayer::New(mode);
587 return mTtsPlayers[mode];
590 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
592 bool idleAdded(false);
594 // Only add an idle if the Adaptor is actually running
595 if( RUNNING == mState || READY == mState || forceAdd )
597 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
603 void Adaptor::RemoveIdle( CallbackBase* callback )
605 mCallbackManager->RemoveIdleCallback( callback );
608 void Adaptor::ProcessIdle()
610 bool idleProcessed = mCallbackManager->ProcessIdle();
611 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
614 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
616 mThreadController->SetPreRenderCallback( callback );
619 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
621 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
622 windowImpl.SetAdaptor( Get() );
624 // Add the new Window to the container - the order is not important
625 mWindows.push_back( &windowImpl );
627 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
629 mThreadController->AddSurface( surface );
631 mWindowCreatedSignal.Emit( childWindow );
636 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
638 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
639 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
641 if( *iter == &windowImpl )
643 mWindows.erase( iter );
651 bool Adaptor::RemoveWindow( std::string childWindowName )
653 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
655 if( ( *iter )->GetName() == childWindowName )
657 mWindows.erase( iter );
665 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
667 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
669 if( ( *iter )->GetId() == childWindow->GetId() )
671 mWindows.erase( iter );
679 Dali::Adaptor& Adaptor::Get()
681 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
682 return gThreadLocalAdaptor->mAdaptor;
685 bool Adaptor::IsAvailable()
687 return gThreadLocalAdaptor != NULL;
690 void Adaptor::SceneCreated()
692 mCore->SceneCreated();
695 Dali::Integration::Core& Adaptor::GetCore()
700 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
702 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
705 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
707 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
708 return *mDisplayConnection;
711 GraphicsInterface& Adaptor::GetGraphicsInterface()
713 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
714 return *( mGraphics.get() );
717 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
719 return *mPlatformAbstraction;
722 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
724 return *mNotificationTrigger;
727 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
729 return mSocketFactory;
732 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
734 if( !mWindows.empty() )
736 return mWindows.front()->GetSurface();
742 TraceInterface& Adaptor::GetKernelTraceInterface()
744 return mKernelTracer;
747 TraceInterface& Adaptor::GetSystemTraceInterface()
749 return mSystemTracer;
752 PerformanceInterface* Adaptor::GetPerformanceInterface()
754 return mPerformanceInterface;
757 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
759 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
760 return *mPlatformAbstraction;
763 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
768 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
770 if( mTtsPlayers[mode] )
772 mTtsPlayers[mode].Reset();
776 Any Adaptor::GetNativeWindowHandle()
778 return mWindows.front()->GetNativeHandle();
781 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
783 Any nativeWindowHandle;
785 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
787 for( auto sceneHolder : mWindows )
789 if ( scene == sceneHolder->GetScene() )
791 nativeWindowHandle = sceneHolder->GetNativeHandle();
796 return nativeWindowHandle;
799 Any Adaptor::GetGraphicsDisplay()
805 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
806 auto eglGraphics = static_cast<EglGraphics *>( graphics );
808 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
809 display = eglImpl.GetDisplay();
815 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
817 mUseRemoteSurface = useRemoteSurface;
820 void Adaptor::AddObserver( LifeCycleObserver& observer )
822 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
824 if ( match == mObservers.end() )
826 mObservers.push_back( &observer );
830 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
832 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
834 if ( match != mObservers.end() )
836 mObservers.erase( match );
840 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
844 mCore->QueueEvent(event);
848 void Adaptor::ProcessCoreEvents()
852 if( mPerformanceInterface )
854 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
857 mCore->ProcessEvents();
859 if( mPerformanceInterface )
861 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
866 void Adaptor::RequestUpdate( bool forceUpdate )
872 mThreadController->RequestUpdate();
876 case PAUSED_WHILE_HIDDEN:
880 // Update (and resource upload) without rendering
881 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
893 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
895 // Only request a notification if the Adaptor is actually running
896 // and we haven't installed the idle notification
897 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
899 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
903 void Adaptor::OnWindowShown()
905 if( PAUSED_WHILE_HIDDEN == mState )
907 // Adaptor can now be resumed
912 // Force a render task
915 else if( RUNNING == mState )
917 // Force a render task
920 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
924 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
928 void Adaptor::OnWindowHidden()
930 if( RUNNING == mState || READY == mState )
932 bool allWindowsHidden = true;
934 for( auto window : mWindows )
936 if ( window->IsVisible() )
938 allWindowsHidden = false;
943 // Only pause the adaptor when all the windows are hidden
944 if( allWindowsHidden )
946 if( mState == RUNNING )
950 // Adaptor cannot be resumed until any window is shown
951 mState = PAUSED_WHILE_HIDDEN;
953 else // mState is READY
955 // Pause the adaptor after the state gets RUNNING
956 mState = PAUSED_WHILE_INITIALIZING;
961 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
966 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
970 // Dali::Internal::Adaptor::Adaptor::OnDamaged
971 void Adaptor::OnDamaged( const DamageArea& area )
973 // This is needed for the case where Dali window is partially obscured
974 RequestUpdate( false );
977 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
979 mResizedSignal.Emit( mAdaptor );
982 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
984 // Nofify surface resizing before flushing event queue
985 mThreadController->ResizeSurface();
987 // Flush the event queue to give the update-render thread chance
988 // to start processing messages for new camera setup etc as soon as possible
992 void Adaptor::NotifySceneCreated()
994 GetCore().SceneCreated();
996 // Flush the event queue to give the update-render thread chance
997 // to start processing messages for new camera setup etc as soon as possible
1000 // Start thread controller after the scene has been created
1001 mThreadController->Start();
1003 // Process after surface is created (registering to remote surface provider if required)
1004 SurfaceInitialized();
1006 if( mState != PAUSED_WHILE_INITIALIZING )
1010 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1018 mState = PAUSED_WHILE_HIDDEN;
1020 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1024 void Adaptor::NotifyLanguageChanged()
1026 mLanguageChangedSignal.Emit( mAdaptor );
1029 void Adaptor::RenderOnce()
1031 RequestUpdateOnce();
1034 const LogFactoryInterface& Adaptor::GetLogFactory()
1036 return *mEnvironmentOptions;
1039 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1041 GetCore().RegisterProcessor(processor);
1044 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1046 GetCore().UnregisterProcessor(processor);
1049 bool Adaptor::IsMultipleWindowSupported() const
1051 return mConfigurationManager->IsMultipleWindowSupported();
1054 void Adaptor::RequestUpdateOnce()
1056 if( mThreadController )
1058 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1062 bool Adaptor::ProcessCoreEventsFromIdle()
1064 ProcessCoreEvents();
1066 // the idle handle automatically un-installs itself
1067 mNotificationOnIdleInstalled = false;
1072 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1074 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1076 for( auto window : mWindows )
1078 if ( scene == window->GetScene() )
1087 Dali::WindowContainer Adaptor::GetWindows() const
1089 Dali::WindowContainer windows;
1091 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1093 // Downcast to Dali::Window
1094 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1097 windows.push_back( window );
1104 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1106 Dali::SceneHolderList sceneHolderList;
1108 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1110 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1113 return sceneHolderList;
1116 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1118 mLanguageChangedSignal(),
1119 mWindowCreatedSignal(),
1120 mAdaptor( adaptor ),
1123 mThreadController( nullptr ),
1124 mGraphics( nullptr ),
1125 mDisplayConnection( nullptr ),
1127 mConfigurationManager( nullptr ),
1128 mPlatformAbstraction( nullptr ),
1129 mCallbackManager( nullptr ),
1130 mNotificationOnIdleInstalled( false ),
1131 mNotificationTrigger( nullptr ),
1132 mDaliFeedbackPlugin(),
1133 mFeedbackController( nullptr ),
1136 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1137 mPerformanceInterface( nullptr ),
1140 mObjectProfiler( nullptr ),
1142 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1143 mUseRemoteSurface( false )
1145 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1146 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1148 gThreadLocalAdaptor = this;
1151 void Adaptor::SetRootLayoutDirection( std::string locale )
1153 Dali::Stage stage = Dali::Stage::GetCurrent();
1155 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1156 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1159 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1161 bool idleAdded( false );
1163 // Only add an idle if the Adaptor is actually running
1164 if( RUNNING == mState || READY == mState || forceAdd )
1166 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1172 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1174 mCallbackManager->RemoveIdleEntererCallback( callback );
1177 } // namespace Adaptor
1179 } // namespace Internal