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/addons/common/addon-manager-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
27 #include <dali/public-api/actors/layer.h>
28 #include <dali/public-api/object/any.h>
29 #include <dali/public-api/object/object-registry.h>
30 #include <dali/devel-api/actors/actor-devel.h>
31 #include <dali/integration-api/debug.h>
32 #include <dali/integration-api/core.h>
33 #include <dali/integration-api/context-notifier.h>
34 #include <dali/integration-api/profiling.h>
35 #include <dali/integration-api/input-options.h>
36 #include <dali/integration-api/events/key-event-integ.h>
37 #include <dali/integration-api/events/touch-event-integ.h>
38 #include <dali/integration-api/events/wheel-event-integ.h>
39 #include <dali/integration-api/processor-interface.h>
40 #include <dali/integration-api/addon-manager.h>
43 #include <dali/public-api/dali-adaptor-common.h>
44 #include <dali/internal/system/common/thread-controller.h>
45 #include <dali/internal/system/common/performance-interface-factory.h>
46 #include <dali/internal/adaptor/common/lifecycle-observer.h>
47 #include <dali/internal/adaptor/common/thread-controller-interface.h>
49 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
50 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
52 #include <dali/devel-api/text-abstraction/font-client.h>
54 #include <dali/internal/system/common/callback-manager.h>
55 #include <dali/internal/accessibility/common/tts-player-impl.h>
56 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
57 #include <dali/internal/window-system/common/event-handler.h>
58 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
59 #include <dali/internal/graphics/gles/gl-implementation.h>
60 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
61 #include <dali/internal/graphics/common/egl-image-extensions.h>
62 #include <dali/internal/clipboard/common/clipboard-impl.h>
63 #include <dali/internal/system/common/object-profiler.h>
64 #include <dali/internal/window-system/common/display-connection.h>
65 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
66 #include <dali/internal/window-system/common/window-impl.h>
67 #include <dali/internal/window-system/common/window-render-surface.h>
69 #include <dali/internal/system/common/logging.h>
71 #include <dali/internal/system/common/locale-utils.h>
72 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
73 #include <dali/internal/imaging/common/image-loader.h>
75 #include <dali/internal/system/common/configuration-manager.h>
76 #include <dali/internal/system/common/environment-variables.h>
78 using Dali::TextAbstraction::FontClient;
80 extern std::string GetSystemCachePath();
94 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
96 } // unnamed namespace
98 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
100 Dali::Adaptor* adaptor = new Dali::Adaptor;
101 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode );
102 adaptor->mImpl = impl;
104 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
105 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
107 impl->Initialize( graphicsFactory, configuration );
108 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
113 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
115 Dali::Adaptor* adaptor = New( window, surface, configuration, environmentOptions, ThreadMode::NORMAL );
120 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
122 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
123 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
124 windowImpl.SetAdaptor( *adaptor );
128 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
130 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
131 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode ); // Impl adaptor
132 adaptor->mImpl = impl;
134 impl->Initialize( graphicsFactory, configuration );
139 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
141 Dali::Adaptor* adaptor = New( graphicsFactory, window, surface, configuration, environmentOptions, ThreadMode::NORMAL );
146 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
148 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
149 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
150 windowImpl.SetAdaptor( *adaptor );
154 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
156 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
157 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
158 mEnvironmentOptions->SetLogFunction( logFunction );
159 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
161 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
164 GetDataStoragePath( path );
165 mPlatformAbstraction->SetDataStoragePath( path );
167 if( mEnvironmentOptions->PerformanceServerRequired() )
169 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
172 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
173 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
175 mCallbackManager = CallbackManager::New();
177 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
179 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
181 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
182 mGraphics->Initialize( mEnvironmentOptions );
184 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
185 auto eglGraphics = static_cast<EglGraphics *>( graphics );
187 // This will only be created once
188 eglGraphics->Create();
190 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
191 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
192 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
194 // Create the AddOnManager
195 mAddOnManager.reset( Dali::Internal::AddOnManagerFactory::CreateAddOnManager() );
197 mCore = Integration::Core::New( *this,
198 *mPlatformAbstraction,
201 eglContextHelperImpl,
202 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
203 mGraphics->GetDepthBufferRequired(),
204 mGraphics->GetStencilBufferRequired(),
205 mGraphics->GetPartialUpdateRequired() );
208 defaultWindow->SetAdaptor( Get() );
210 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
212 mWindowCreatedSignal.Emit( defaultSceneHolder );
214 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
215 if( 0u < timeInterval )
217 mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
220 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
222 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
224 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
226 // Should be called after Core creation
227 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
229 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
231 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
233 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
235 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
237 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
239 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
241 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
243 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
245 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
247 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
249 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
251 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
253 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
255 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
257 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
259 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
261 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
263 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
265 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
267 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
269 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
271 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
273 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
275 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
277 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
279 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
281 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
283 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
285 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
287 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
289 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
291 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
293 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
295 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
297 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
299 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
301 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
303 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
305 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
307 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
309 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
311 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
313 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
315 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
317 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
319 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
321 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
324 std::string systemCachePath = GetSystemCachePath();
325 if( ! systemCachePath.empty() )
327 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
328 if ( 0 != dir_err && errno != EEXIST )
330 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
335 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
340 // Ensure stop status
343 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
344 gThreadLocalAdaptor = NULL;
346 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
348 (*iter)->OnDestroy();
351 // Clear out all the handles to Windows
354 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
355 delete mObjectProfiler;
359 delete mDisplayConnection;
360 delete mPlatformAbstraction;
361 delete mCallbackManager;
362 delete mPerformanceInterface;
364 mGraphics->Destroy();
366 // uninstall it on this thread (main actor thread)
367 Dali::Integration::Log::UninstallLogFunction();
369 // Delete environment options if we own it
370 if( mEnvironmentOptionsOwned )
372 delete mEnvironmentOptions;
376 void Adaptor::Start()
378 // It doesn't support restart after stop at this moment to support restarting, need more testing
379 if( READY != mState )
386 SetupSystemInformation();
388 // Start the callback manager
389 mCallbackManager->Start();
391 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
393 unsigned int dpiHor, dpiVer;
396 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
398 // set the DPI value for font rendering
399 FontClient fontClient = FontClient::Get();
400 fontClient.SetDpi( dpiHor, dpiVer );
402 // Initialize the thread controller
403 mThreadController->Initialize();
405 // Set max texture size
406 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
408 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
412 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
413 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
416 ProcessCoreEvents(); // Ensure any startup messages are processed.
418 // Initialize the image loader plugin
419 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
421 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
428 mAddOnManager->Start();
432 // Dali::Internal::Adaptor::Adaptor::Pause
433 void Adaptor::Pause()
435 // Only pause the adaptor if we're actually running.
436 if( RUNNING == mState )
438 // Inform observers that we are about to be paused.
439 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
447 mAddOnManager->Pause();
450 // Pause all windows event handlers when adaptor paused
451 for( auto window : mWindows )
456 mThreadController->Pause();
459 // Ensure any messages queued during pause callbacks are processed by doing another update.
462 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
466 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
470 // Dali::Internal::Adaptor::Adaptor::Resume
471 void Adaptor::Resume()
473 // Only resume the adaptor if we are in the suspended state.
474 if( PAUSED == mState )
478 // Reset the event handlers when adaptor resumed
479 for( auto window : mWindows )
484 // Resume AddOnManager
487 mAddOnManager->Resume();
490 // Inform observers that we have resumed.
491 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
496 // Trigger processing of events queued up while paused
497 mCore->ProcessEvents();
499 // Do at end to ensure our first update/render after resumption includes the processed messages as well
500 mThreadController->Resume();
502 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
506 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
512 if( RUNNING == mState ||
514 PAUSED_WHILE_HIDDEN == mState )
516 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
523 mAddOnManager->Stop();
526 mThreadController->Stop();
528 // Delete the TTS player
529 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
533 mTtsPlayers[i].Reset();
537 // Destroy the image loader plugin
538 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
540 delete mNotificationTrigger;
541 mNotificationTrigger = NULL;
543 mCallbackManager->Stop();
547 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
551 void Adaptor::ContextLost()
553 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
556 void Adaptor::ContextRegained()
558 // Inform core, so that texture resources can be reloaded
559 mCore->RecoverFromContextLoss();
561 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
564 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
566 Integration::Point convertedPoint( point );
567 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
570 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
572 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
573 mWindows.front()->FeedWheelEvent( event );
576 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
578 Integration::KeyEvent convertedEvent( keyEvent );
579 mWindows.front()->FeedKeyEvent( convertedEvent );
582 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
584 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
585 for( auto windowPtr : mWindows )
587 if( windowPtr == windowImpl ) // the window is not deleted
589 mResizedSignal.Emit( mAdaptor );
591 windowImpl->SetSurface( &newSurface );
593 // Flush the event queue to give the update-render thread chance
594 // to start processing messages for new camera setup etc as soon as possible
597 // This method blocks until the render thread has completed the replace.
598 mThreadController->ReplaceSurface( &newSurface );
604 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
606 // Flush the event queue to give the update-render thread chance
607 // to start processing messages for new camera setup etc as soon as possible
610 // This method blocks until the render thread has finished rendering the current surface.
611 mThreadController->DeleteSurface( &surface );
614 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
616 return *mWindows.front()->GetSurface();
619 void Adaptor::ReleaseSurfaceLock()
621 mWindows.front()->GetSurface()->ReleaseLock();
624 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
626 if( !mTtsPlayers[mode] )
628 // Create the TTS player when it needed, because it can reduce launching time.
629 mTtsPlayers[mode] = TtsPlayer::New(mode);
632 return mTtsPlayers[mode];
635 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
637 bool idleAdded(false);
639 // Only add an idle if the Adaptor is actually running
640 if( RUNNING == mState || READY == mState || forceAdd )
642 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
648 void Adaptor::RemoveIdle( CallbackBase* callback )
650 mCallbackManager->RemoveIdleCallback( callback );
653 void Adaptor::ProcessIdle()
655 bool idleProcessed = mCallbackManager->ProcessIdle();
656 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
659 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
661 mThreadController->SetPreRenderCallback( callback );
664 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
666 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
667 windowImpl.SetAdaptor( Get() );
669 // ChildWindow is set to the layout direction of the default window.
670 windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
672 // Add the new Window to the container - the order is not important
673 mWindows.push_back( &windowImpl );
675 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
677 mThreadController->AddSurface( surface );
679 mWindowCreatedSignal.Emit( childWindow );
684 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
686 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
687 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
689 if( *iter == &windowImpl )
691 mWindows.erase( iter );
699 bool Adaptor::RemoveWindow( std::string childWindowName )
701 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
703 if( ( *iter )->GetName() == childWindowName )
705 mWindows.erase( iter );
713 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
715 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
717 if( ( *iter )->GetId() == childWindow->GetId() )
719 mWindows.erase( iter );
727 Dali::Adaptor& Adaptor::Get()
729 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
730 return gThreadLocalAdaptor->mAdaptor;
733 bool Adaptor::IsAvailable()
735 return gThreadLocalAdaptor != NULL;
738 void Adaptor::SceneCreated()
740 mCore->SceneCreated();
743 Dali::Integration::Core& Adaptor::GetCore()
748 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
750 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
753 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
755 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
756 return *mDisplayConnection;
759 GraphicsInterface& Adaptor::GetGraphicsInterface()
761 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
762 return *( mGraphics.get() );
765 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
767 return *mPlatformAbstraction;
770 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
772 return *mNotificationTrigger;
775 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
777 return mSocketFactory;
780 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
782 if( !mWindows.empty() )
784 return mWindows.front()->GetSurface();
790 TraceInterface& Adaptor::GetKernelTraceInterface()
792 return mKernelTracer;
795 TraceInterface& Adaptor::GetSystemTraceInterface()
797 return mSystemTracer;
800 PerformanceInterface* Adaptor::GetPerformanceInterface()
802 return mPerformanceInterface;
805 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
807 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
808 return *mPlatformAbstraction;
811 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
816 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
818 if( mTtsPlayers[mode] )
820 mTtsPlayers[mode].Reset();
824 Any Adaptor::GetNativeWindowHandle()
826 return mWindows.front()->GetNativeHandle();
829 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
831 Any nativeWindowHandle;
833 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
835 for( auto sceneHolder : mWindows )
837 if ( scene == sceneHolder->GetScene() )
839 nativeWindowHandle = sceneHolder->GetNativeHandle();
844 return nativeWindowHandle;
847 Any Adaptor::GetGraphicsDisplay()
853 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
854 auto eglGraphics = static_cast<EglGraphics *>( graphics );
856 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
857 display = eglImpl.GetDisplay();
863 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
865 mUseRemoteSurface = useRemoteSurface;
868 void Adaptor::AddObserver( LifeCycleObserver& observer )
870 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
872 if ( match == mObservers.end() )
874 mObservers.push_back( &observer );
878 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
880 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
882 if ( match != mObservers.end() )
884 mObservers.erase( match );
888 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
892 mCore->QueueEvent(event);
896 void Adaptor::ProcessCoreEvents()
900 if( mPerformanceInterface )
902 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
905 mCore->ProcessEvents();
907 if( mPerformanceInterface )
909 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
914 void Adaptor::RequestUpdate( bool forceUpdate )
920 mThreadController->RequestUpdate();
924 case PAUSED_WHILE_HIDDEN:
928 // Update (and resource upload) without rendering
929 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
941 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
943 // Only request a notification if the Adaptor is actually running
944 // and we haven't installed the idle notification
945 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
947 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
951 void Adaptor::OnWindowShown()
953 if( PAUSED_WHILE_HIDDEN == mState )
955 // Adaptor can now be resumed
960 // Force a render task
963 else if( RUNNING == mState )
965 // Force a render task
968 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
970 else if( PAUSED_WHILE_INITIALIZING == mState )
972 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
977 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
981 void Adaptor::OnWindowHidden()
983 if( RUNNING == mState || READY == mState )
985 bool allWindowsHidden = true;
987 for( auto window : mWindows )
989 if ( window->IsVisible() )
991 allWindowsHidden = false;
996 // Only pause the adaptor when all the windows are hidden
997 if( allWindowsHidden )
999 if( mState == RUNNING )
1003 // Adaptor cannot be resumed until any window is shown
1004 mState = PAUSED_WHILE_HIDDEN;
1006 else // mState is READY
1008 // Pause the adaptor after the state gets RUNNING
1009 mState = PAUSED_WHILE_INITIALIZING;
1014 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1019 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1023 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1024 void Adaptor::OnDamaged( const DamageArea& area )
1026 // This is needed for the case where Dali window is partially obscured
1027 RequestUpdate( false );
1030 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1032 mResizedSignal.Emit( mAdaptor );
1035 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1037 // Nofify surface resizing before flushing event queue
1038 mThreadController->ResizeSurface();
1040 // Flush the event queue to give the update-render thread chance
1041 // to start processing messages for new camera setup etc as soon as possible
1042 ProcessCoreEvents();
1045 void Adaptor::NotifySceneCreated()
1047 GetCore().SceneCreated();
1049 // Flush the event queue to give the update-render thread chance
1050 // to start processing messages for new camera setup etc as soon as possible
1051 ProcessCoreEvents();
1053 // Start thread controller after the scene has been created
1054 mThreadController->Start();
1056 // Process after surface is created (registering to remote surface provider if required)
1057 SurfaceInitialized();
1059 if( mState != PAUSED_WHILE_INITIALIZING )
1063 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1071 mState = PAUSED_WHILE_HIDDEN;
1073 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1077 void Adaptor::NotifyLanguageChanged()
1079 mLanguageChangedSignal.Emit( mAdaptor );
1082 void Adaptor::RenderOnce()
1084 if( mThreadController )
1086 UpdateMode updateMode;
1087 if( mThreadMode == ThreadMode::NORMAL )
1089 updateMode = UpdateMode::NORMAL;
1093 updateMode = UpdateMode::FORCE_RENDER;
1095 ProcessCoreEvents();
1097 mThreadController->RequestUpdateOnce( updateMode );
1101 const LogFactoryInterface& Adaptor::GetLogFactory()
1103 return *mEnvironmentOptions;
1106 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1108 GetCore().RegisterProcessor(processor);
1111 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1113 GetCore().UnregisterProcessor(processor);
1116 bool Adaptor::IsMultipleWindowSupported() const
1118 return mConfigurationManager->IsMultipleWindowSupported();
1121 void Adaptor::RequestUpdateOnce()
1123 if( mThreadController )
1125 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1129 bool Adaptor::ProcessCoreEventsFromIdle()
1131 ProcessCoreEvents();
1133 // the idle handle automatically un-installs itself
1134 mNotificationOnIdleInstalled = false;
1139 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1141 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1143 for( auto window : mWindows )
1145 if ( scene == window->GetScene() )
1154 Dali::WindowContainer Adaptor::GetWindows() const
1156 Dali::WindowContainer windows;
1158 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1160 // Downcast to Dali::Window
1161 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1164 windows.push_back( window );
1171 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1173 Dali::SceneHolderList sceneHolderList;
1175 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1177 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1180 return sceneHolderList;
1183 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1185 Dali::ObjectRegistry registry;
1188 registry = mCore->GetObjectRegistry();
1193 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1195 mLanguageChangedSignal(),
1196 mWindowCreatedSignal(),
1197 mAdaptor( adaptor ),
1200 mThreadController( nullptr ),
1201 mGraphics( nullptr ),
1202 mDisplayConnection( nullptr ),
1204 mConfigurationManager( nullptr ),
1205 mPlatformAbstraction( nullptr ),
1206 mCallbackManager( nullptr ),
1207 mNotificationOnIdleInstalled( false ),
1208 mNotificationTrigger( nullptr ),
1209 mDaliFeedbackPlugin(),
1210 mFeedbackController( nullptr ),
1213 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1214 mPerformanceInterface( nullptr ),
1217 mObjectProfiler( nullptr ),
1219 mThreadMode( threadMode ),
1220 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1221 mUseRemoteSurface( false ),
1222 mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1224 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1225 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1227 gThreadLocalAdaptor = this;
1230 void Adaptor::SetRootLayoutDirection( std::string locale )
1232 mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1233 for ( auto& window : mWindows )
1235 Dali::Actor root = window->GetRootLayer();
1236 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1240 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1242 bool idleAdded( false );
1244 // Only add an idle if the Adaptor is actually running
1245 if( RUNNING == mState || READY == mState || forceAdd )
1247 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1259 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1261 mCallbackManager->RemoveIdleEntererCallback( callback );
1264 } // namespace Adaptor
1266 } // namespace Internal