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, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
666 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
667 windowImpl.SetAdaptor( Get() );
669 // Add the new Window to the container - the order is not important
670 mWindows.push_back( &windowImpl );
672 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
674 mThreadController->AddSurface( surface );
676 mWindowCreatedSignal.Emit( childWindow );
681 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
683 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
684 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
686 if( *iter == &windowImpl )
688 mWindows.erase( iter );
696 bool Adaptor::RemoveWindow( std::string childWindowName )
698 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
700 if( ( *iter )->GetName() == childWindowName )
702 mWindows.erase( iter );
710 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
712 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
714 if( ( *iter )->GetId() == childWindow->GetId() )
716 mWindows.erase( iter );
724 Dali::Adaptor& Adaptor::Get()
726 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
727 return gThreadLocalAdaptor->mAdaptor;
730 bool Adaptor::IsAvailable()
732 return gThreadLocalAdaptor != NULL;
735 void Adaptor::SceneCreated()
737 mCore->SceneCreated();
740 Dali::Integration::Core& Adaptor::GetCore()
745 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
747 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
750 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
752 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
753 return *mDisplayConnection;
756 GraphicsInterface& Adaptor::GetGraphicsInterface()
758 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
759 return *( mGraphics.get() );
762 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
764 return *mPlatformAbstraction;
767 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
769 return *mNotificationTrigger;
772 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
774 return mSocketFactory;
777 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
779 if( !mWindows.empty() )
781 return mWindows.front()->GetSurface();
787 TraceInterface& Adaptor::GetKernelTraceInterface()
789 return mKernelTracer;
792 TraceInterface& Adaptor::GetSystemTraceInterface()
794 return mSystemTracer;
797 PerformanceInterface* Adaptor::GetPerformanceInterface()
799 return mPerformanceInterface;
802 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
804 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
805 return *mPlatformAbstraction;
808 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
813 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
815 if( mTtsPlayers[mode] )
817 mTtsPlayers[mode].Reset();
821 Any Adaptor::GetNativeWindowHandle()
823 return mWindows.front()->GetNativeHandle();
826 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
828 Any nativeWindowHandle;
830 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
832 for( auto sceneHolder : mWindows )
834 if ( scene == sceneHolder->GetScene() )
836 nativeWindowHandle = sceneHolder->GetNativeHandle();
841 return nativeWindowHandle;
844 Any Adaptor::GetGraphicsDisplay()
850 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
851 auto eglGraphics = static_cast<EglGraphics *>( graphics );
853 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
854 display = eglImpl.GetDisplay();
860 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
862 mUseRemoteSurface = useRemoteSurface;
865 void Adaptor::AddObserver( LifeCycleObserver& observer )
867 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
869 if ( match == mObservers.end() )
871 mObservers.push_back( &observer );
875 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
877 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
879 if ( match != mObservers.end() )
881 mObservers.erase( match );
885 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
889 mCore->QueueEvent(event);
893 void Adaptor::ProcessCoreEvents()
897 if( mPerformanceInterface )
899 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
902 mCore->ProcessEvents();
904 if( mPerformanceInterface )
906 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
911 void Adaptor::RequestUpdate( bool forceUpdate )
917 mThreadController->RequestUpdate();
921 case PAUSED_WHILE_HIDDEN:
925 // Update (and resource upload) without rendering
926 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
938 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
940 // Only request a notification if the Adaptor is actually running
941 // and we haven't installed the idle notification
942 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
944 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
948 void Adaptor::OnWindowShown()
950 if( PAUSED_WHILE_HIDDEN == mState )
952 // Adaptor can now be resumed
957 // Force a render task
960 else if( RUNNING == mState )
962 // Force a render task
965 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
969 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
973 void Adaptor::OnWindowHidden()
975 if( RUNNING == mState || READY == mState )
977 bool allWindowsHidden = true;
979 for( auto window : mWindows )
981 if ( window->IsVisible() )
983 allWindowsHidden = false;
988 // Only pause the adaptor when all the windows are hidden
989 if( allWindowsHidden )
991 if( mState == RUNNING )
995 // Adaptor cannot be resumed until any window is shown
996 mState = PAUSED_WHILE_HIDDEN;
998 else // mState is READY
1000 // Pause the adaptor after the state gets RUNNING
1001 mState = PAUSED_WHILE_INITIALIZING;
1006 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1011 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1015 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1016 void Adaptor::OnDamaged( const DamageArea& area )
1018 // This is needed for the case where Dali window is partially obscured
1019 RequestUpdate( false );
1022 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1024 mResizedSignal.Emit( mAdaptor );
1027 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1029 // Nofify surface resizing before flushing event queue
1030 mThreadController->ResizeSurface();
1032 // Flush the event queue to give the update-render thread chance
1033 // to start processing messages for new camera setup etc as soon as possible
1034 ProcessCoreEvents();
1037 void Adaptor::NotifySceneCreated()
1039 GetCore().SceneCreated();
1041 // Flush the event queue to give the update-render thread chance
1042 // to start processing messages for new camera setup etc as soon as possible
1043 ProcessCoreEvents();
1045 // Start thread controller after the scene has been created
1046 mThreadController->Start();
1048 // Process after surface is created (registering to remote surface provider if required)
1049 SurfaceInitialized();
1051 if( mState != PAUSED_WHILE_INITIALIZING )
1055 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1063 mState = PAUSED_WHILE_HIDDEN;
1065 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1069 void Adaptor::NotifyLanguageChanged()
1071 mLanguageChangedSignal.Emit( mAdaptor );
1074 void Adaptor::RenderOnce()
1076 if( mThreadController )
1078 UpdateMode updateMode;
1079 if( mThreadMode == ThreadMode::NORMAL )
1081 updateMode = UpdateMode::NORMAL;
1085 updateMode = UpdateMode::FORCE_RENDER;
1087 ProcessCoreEvents();
1089 mThreadController->RequestUpdateOnce( updateMode );
1093 const LogFactoryInterface& Adaptor::GetLogFactory()
1095 return *mEnvironmentOptions;
1098 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1100 GetCore().RegisterProcessor(processor);
1103 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1105 GetCore().UnregisterProcessor(processor);
1108 bool Adaptor::IsMultipleWindowSupported() const
1110 return mConfigurationManager->IsMultipleWindowSupported();
1113 void Adaptor::RequestUpdateOnce()
1115 if( mThreadController )
1117 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1121 bool Adaptor::ProcessCoreEventsFromIdle()
1123 ProcessCoreEvents();
1125 // the idle handle automatically un-installs itself
1126 mNotificationOnIdleInstalled = false;
1131 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1133 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1135 for( auto window : mWindows )
1137 if ( scene == window->GetScene() )
1146 Dali::WindowContainer Adaptor::GetWindows() const
1148 Dali::WindowContainer windows;
1150 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1152 // Downcast to Dali::Window
1153 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1156 windows.push_back( window );
1163 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1165 Dali::SceneHolderList sceneHolderList;
1167 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1169 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1172 return sceneHolderList;
1175 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1177 Dali::ObjectRegistry registry;
1180 registry = mCore->GetObjectRegistry();
1185 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1187 mLanguageChangedSignal(),
1188 mWindowCreatedSignal(),
1189 mAdaptor( adaptor ),
1192 mThreadController( nullptr ),
1193 mGraphics( nullptr ),
1194 mDisplayConnection( nullptr ),
1196 mConfigurationManager( nullptr ),
1197 mPlatformAbstraction( nullptr ),
1198 mCallbackManager( nullptr ),
1199 mNotificationOnIdleInstalled( false ),
1200 mNotificationTrigger( nullptr ),
1201 mDaliFeedbackPlugin(),
1202 mFeedbackController( nullptr ),
1205 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1206 mPerformanceInterface( nullptr ),
1209 mObjectProfiler( nullptr ),
1211 mThreadMode( threadMode ),
1212 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1213 mUseRemoteSurface( false )
1215 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1216 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1218 gThreadLocalAdaptor = this;
1221 void Adaptor::SetRootLayoutDirection( std::string locale )
1223 for ( auto& window : mWindows )
1225 Dali::Actor root = window->GetRootLayer();
1226 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1227 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1231 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1233 bool idleAdded( false );
1235 // Only add an idle if the Adaptor is actually running
1236 if( RUNNING == mState || READY == mState || forceAdd )
1238 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1250 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1252 mCallbackManager->RemoveIdleEntererCallback( callback );
1255 } // namespace Adaptor
1257 } // namespace Internal