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/public-api/events/wheel-event.h>
31 #include <dali/devel-api/actors/actor-devel.h>
32 #include <dali/integration-api/debug.h>
33 #include <dali/integration-api/core.h>
34 #include <dali/integration-api/context-notifier.h>
35 #include <dali/integration-api/profiling.h>
36 #include <dali/integration-api/input-options.h>
37 #include <dali/integration-api/events/key-event-integ.h>
38 #include <dali/integration-api/events/touch-event-integ.h>
39 #include <dali/integration-api/events/wheel-event-integ.h>
40 #include <dali/integration-api/processor-interface.h>
41 #include <dali/integration-api/addon-manager.h>
44 #include <dali/public-api/dali-adaptor-common.h>
45 #include <dali/internal/system/common/thread-controller.h>
46 #include <dali/internal/system/common/performance-interface-factory.h>
47 #include <dali/internal/adaptor/common/lifecycle-observer.h>
48 #include <dali/internal/adaptor/common/thread-controller-interface.h>
50 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
51 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
53 #include <dali/devel-api/text-abstraction/font-client.h>
55 #include <dali/internal/system/common/callback-manager.h>
56 #include <dali/internal/accessibility/common/tts-player-impl.h>
57 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
58 #include <dali/internal/window-system/common/event-handler.h>
59 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
60 #include <dali/internal/graphics/gles/gl-implementation.h>
61 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
62 #include <dali/internal/graphics/common/egl-image-extensions.h>
63 #include <dali/internal/clipboard/common/clipboard-impl.h>
64 #include <dali/internal/system/common/object-profiler.h>
65 #include <dali/internal/window-system/common/display-connection.h>
66 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
67 #include <dali/internal/window-system/common/window-impl.h>
68 #include <dali/internal/window-system/common/window-render-surface.h>
70 #include <dali/internal/system/common/logging.h>
72 #include <dali/internal/system/common/locale-utils.h>
73 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
74 #include <dali/internal/imaging/common/image-loader.h>
76 #include <dali/internal/system/common/configuration-manager.h>
77 #include <dali/internal/system/common/environment-variables.h>
79 using Dali::TextAbstraction::FontClient;
81 extern std::string GetSystemCachePath();
95 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
97 } // unnamed namespace
99 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
101 Dali::Adaptor* adaptor = new Dali::Adaptor;
102 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode );
103 adaptor->mImpl = impl;
105 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
106 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
108 impl->Initialize( graphicsFactory, configuration );
109 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
114 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
116 Dali::Adaptor* adaptor = New( window, surface, configuration, environmentOptions, ThreadMode::NORMAL );
121 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
123 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
124 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
125 windowImpl.SetAdaptor( *adaptor );
129 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
131 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
132 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode ); // Impl adaptor
133 adaptor->mImpl = impl;
135 impl->Initialize( graphicsFactory, configuration );
140 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
142 Dali::Adaptor* adaptor = New( graphicsFactory, window, surface, configuration, environmentOptions, ThreadMode::NORMAL );
147 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
149 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
150 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
151 windowImpl.SetAdaptor( *adaptor );
155 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
157 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
158 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
159 mEnvironmentOptions->SetLogFunction( logFunction );
160 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
162 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
165 GetDataStoragePath( path );
166 mPlatformAbstraction->SetDataStoragePath( path );
168 if( mEnvironmentOptions->PerformanceServerRequired() )
170 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
173 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
174 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
176 mCallbackManager = CallbackManager::New();
178 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
180 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
182 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
183 mGraphics->Initialize( mEnvironmentOptions );
185 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
186 auto eglGraphics = static_cast<EglGraphics *>( graphics );
188 // This will only be created once
189 eglGraphics->Create();
191 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
192 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
193 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
195 // Create the AddOnManager
196 mAddOnManager.reset( Dali::Internal::AddOnManagerFactory::CreateAddOnManager() );
198 mCore = Integration::Core::New( *this,
199 *mPlatformAbstraction,
202 eglContextHelperImpl,
203 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
204 mGraphics->GetDepthBufferRequired(),
205 mGraphics->GetStencilBufferRequired(),
206 mGraphics->GetPartialUpdateRequired() );
209 defaultWindow->SetAdaptor( Get() );
211 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
213 mWindowCreatedSignal.Emit( defaultSceneHolder );
215 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
216 if( 0u < timeInterval )
218 mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
221 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
223 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
225 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
227 // Should be called after Core creation
228 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
230 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
232 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
234 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
236 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
238 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
240 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
242 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
244 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
246 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
248 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
250 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
252 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
254 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
256 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
258 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
260 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
262 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
264 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
266 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
268 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
270 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
272 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
274 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
276 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
278 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
280 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
282 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
284 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
286 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
288 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
290 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
292 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
294 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
296 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
298 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
300 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
302 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
304 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
306 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
308 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
310 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
312 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
314 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
316 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
318 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
320 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
322 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
325 std::string systemCachePath = GetSystemCachePath();
326 if( ! systemCachePath.empty() )
328 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
329 if ( 0 != dir_err && errno != EEXIST )
331 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
336 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
341 // Ensure stop status
344 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
345 gThreadLocalAdaptor = NULL;
347 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
349 (*iter)->OnDestroy();
352 // Clear out all the handles to Windows
355 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
356 delete mObjectProfiler;
360 delete mDisplayConnection;
361 delete mPlatformAbstraction;
362 delete mCallbackManager;
363 delete mPerformanceInterface;
365 mGraphics->Destroy();
367 // uninstall it on this thread (main actor thread)
368 Dali::Integration::Log::UninstallLogFunction();
370 // Delete environment options if we own it
371 if( mEnvironmentOptionsOwned )
373 delete mEnvironmentOptions;
377 void Adaptor::Start()
379 // It doesn't support restart after stop at this moment to support restarting, need more testing
380 if( READY != mState )
387 SetupSystemInformation();
389 // Start the callback manager
390 mCallbackManager->Start();
392 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
394 unsigned int dpiHor, dpiVer;
397 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
399 // set the DPI value for font rendering
400 FontClient fontClient = FontClient::Get();
401 fontClient.SetDpi( dpiHor, dpiVer );
403 // Initialize the thread controller
404 mThreadController->Initialize();
406 // Set max texture size
407 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
409 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
413 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
414 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
417 ProcessCoreEvents(); // Ensure any startup messages are processed.
419 // Initialize the image loader plugin
420 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
422 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
429 mAddOnManager->Start();
433 // Dali::Internal::Adaptor::Adaptor::Pause
434 void Adaptor::Pause()
436 // Only pause the adaptor if we're actually running.
437 if( RUNNING == mState )
439 // Inform observers that we are about to be paused.
440 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
448 mAddOnManager->Pause();
451 // Pause all windows event handlers when adaptor paused
452 for( auto window : mWindows )
457 mThreadController->Pause();
460 // Ensure any messages queued during pause callbacks are processed by doing another update.
463 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
467 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
471 // Dali::Internal::Adaptor::Adaptor::Resume
472 void Adaptor::Resume()
474 // Only resume the adaptor if we are in the suspended state.
475 if( PAUSED == mState )
479 // Reset the event handlers when adaptor resumed
480 for( auto window : mWindows )
485 // Resume AddOnManager
488 mAddOnManager->Resume();
491 // Inform observers that we have resumed.
492 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
497 // Trigger processing of events queued up while paused
498 mCore->ProcessEvents();
500 // Do at end to ensure our first update/render after resumption includes the processed messages as well
501 mThreadController->Resume();
503 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
507 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
513 if( RUNNING == mState ||
515 PAUSED_WHILE_HIDDEN == mState )
517 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
524 mAddOnManager->Stop();
527 mThreadController->Stop();
529 // Delete the TTS player
530 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
534 mTtsPlayers[i].Reset();
538 // Destroy the image loader plugin
539 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
541 delete mNotificationTrigger;
542 mNotificationTrigger = NULL;
544 mCallbackManager->Stop();
548 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
552 void Adaptor::ContextLost()
554 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
557 void Adaptor::ContextRegained()
559 // Inform core, so that texture resources can be reloaded
560 mCore->RecoverFromContextLoss();
562 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
565 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
567 Integration::Point convertedPoint( point );
568 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
571 void Adaptor::FeedWheelEvent( Dali::WheelEvent& wheelEvent )
573 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >( wheelEvent.GetType() ), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime() );
574 mWindows.front()->FeedWheelEvent( event );
577 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
579 Integration::KeyEvent convertedEvent( keyEvent );
580 mWindows.front()->FeedKeyEvent( convertedEvent );
583 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
585 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
586 for( auto windowPtr : mWindows )
588 if( windowPtr == windowImpl ) // the window is not deleted
590 mResizedSignal.Emit( mAdaptor );
592 windowImpl->SetSurface( &newSurface );
594 // Flush the event queue to give the update-render thread chance
595 // to start processing messages for new camera setup etc as soon as possible
598 // This method blocks until the render thread has completed the replace.
599 mThreadController->ReplaceSurface( &newSurface );
605 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
607 // Flush the event queue to give the update-render thread chance
608 // to start processing messages for new camera setup etc as soon as possible
611 // This method blocks until the render thread has finished rendering the current surface.
612 mThreadController->DeleteSurface( &surface );
615 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
617 return *mWindows.front()->GetSurface();
620 void Adaptor::ReleaseSurfaceLock()
622 mWindows.front()->GetSurface()->ReleaseLock();
625 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
627 if( !mTtsPlayers[mode] )
629 // Create the TTS player when it needed, because it can reduce launching time.
630 mTtsPlayers[mode] = TtsPlayer::New(mode);
633 return mTtsPlayers[mode];
636 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
638 bool idleAdded(false);
640 // Only add an idle if the Adaptor is actually running
641 if( RUNNING == mState || READY == mState || forceAdd )
643 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
649 void Adaptor::RemoveIdle( CallbackBase* callback )
651 mCallbackManager->RemoveIdleCallback( callback );
654 void Adaptor::ProcessIdle()
656 bool idleProcessed = mCallbackManager->ProcessIdle();
657 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
660 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
662 mThreadController->SetPreRenderCallback( callback );
665 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
667 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
668 windowImpl.SetAdaptor( Get() );
670 // Add the new Window to the container - the order is not important
671 mWindows.push_back( &windowImpl );
673 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
675 mThreadController->AddSurface( surface );
677 mWindowCreatedSignal.Emit( childWindow );
682 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
684 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
685 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
687 if( *iter == &windowImpl )
689 mWindows.erase( iter );
697 bool Adaptor::RemoveWindow( std::string childWindowName )
699 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
701 if( ( *iter )->GetName() == childWindowName )
703 mWindows.erase( iter );
711 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
713 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
715 if( ( *iter )->GetId() == childWindow->GetId() )
717 mWindows.erase( iter );
725 Dali::Adaptor& Adaptor::Get()
727 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
728 return gThreadLocalAdaptor->mAdaptor;
731 bool Adaptor::IsAvailable()
733 return gThreadLocalAdaptor != NULL;
736 void Adaptor::SceneCreated()
738 mCore->SceneCreated();
741 Dali::Integration::Core& Adaptor::GetCore()
746 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
748 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
751 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
753 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
754 return *mDisplayConnection;
757 GraphicsInterface& Adaptor::GetGraphicsInterface()
759 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
760 return *( mGraphics.get() );
763 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
765 return *mPlatformAbstraction;
768 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
770 return *mNotificationTrigger;
773 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
775 return mSocketFactory;
778 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
780 if( !mWindows.empty() )
782 return mWindows.front()->GetSurface();
788 TraceInterface& Adaptor::GetKernelTraceInterface()
790 return mKernelTracer;
793 TraceInterface& Adaptor::GetSystemTraceInterface()
795 return mSystemTracer;
798 PerformanceInterface* Adaptor::GetPerformanceInterface()
800 return mPerformanceInterface;
803 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
805 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
806 return *mPlatformAbstraction;
809 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
814 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
816 if( mTtsPlayers[mode] )
818 mTtsPlayers[mode].Reset();
822 Any Adaptor::GetNativeWindowHandle()
824 return mWindows.front()->GetNativeHandle();
827 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
829 Any nativeWindowHandle;
831 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
833 for( auto sceneHolder : mWindows )
835 if ( scene == sceneHolder->GetScene() )
837 nativeWindowHandle = sceneHolder->GetNativeHandle();
842 return nativeWindowHandle;
845 Any Adaptor::GetGraphicsDisplay()
851 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
852 auto eglGraphics = static_cast<EglGraphics *>( graphics );
854 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
855 display = eglImpl.GetDisplay();
861 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
863 mUseRemoteSurface = useRemoteSurface;
866 void Adaptor::AddObserver( LifeCycleObserver& observer )
868 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
870 if ( match == mObservers.end() )
872 mObservers.push_back( &observer );
876 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
878 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
880 if ( match != mObservers.end() )
882 mObservers.erase( match );
886 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
890 mCore->QueueEvent(event);
894 void Adaptor::ProcessCoreEvents()
898 if( mPerformanceInterface )
900 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
903 mCore->ProcessEvents();
905 if( mPerformanceInterface )
907 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
912 void Adaptor::RequestUpdate( bool forceUpdate )
918 mThreadController->RequestUpdate();
922 case PAUSED_WHILE_HIDDEN:
926 // Update (and resource upload) without rendering
927 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
939 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
941 // Only request a notification if the Adaptor is actually running
942 // and we haven't installed the idle notification
943 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
945 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
949 void Adaptor::OnWindowShown()
951 if( PAUSED_WHILE_HIDDEN == mState )
953 // Adaptor can now be resumed
958 // Force a render task
961 else if( RUNNING == mState )
963 // Force a render task
966 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
968 else if( PAUSED_WHILE_INITIALIZING == mState )
970 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
975 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
979 void Adaptor::OnWindowHidden()
981 if( RUNNING == mState || READY == mState )
983 bool allWindowsHidden = true;
985 for( auto window : mWindows )
987 if ( window->IsVisible() )
989 allWindowsHidden = false;
994 // Only pause the adaptor when all the windows are hidden
995 if( allWindowsHidden )
997 if( mState == RUNNING )
1001 // Adaptor cannot be resumed until any window is shown
1002 mState = PAUSED_WHILE_HIDDEN;
1004 else // mState is READY
1006 // Pause the adaptor after the state gets RUNNING
1007 mState = PAUSED_WHILE_INITIALIZING;
1012 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1017 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1021 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1022 void Adaptor::OnDamaged( const DamageArea& area )
1024 // This is needed for the case where Dali window is partially obscured
1025 RequestUpdate( false );
1028 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1030 mResizedSignal.Emit( mAdaptor );
1033 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1035 // Nofify surface resizing before flushing event queue
1036 mThreadController->ResizeSurface();
1038 // Flush the event queue to give the update-render thread chance
1039 // to start processing messages for new camera setup etc as soon as possible
1040 ProcessCoreEvents();
1043 void Adaptor::NotifySceneCreated()
1045 GetCore().SceneCreated();
1047 // Flush the event queue to give the update-render thread chance
1048 // to start processing messages for new camera setup etc as soon as possible
1049 ProcessCoreEvents();
1051 // Start thread controller after the scene has been created
1052 mThreadController->Start();
1054 // Process after surface is created (registering to remote surface provider if required)
1055 SurfaceInitialized();
1057 if( mState != PAUSED_WHILE_INITIALIZING )
1061 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1069 mState = PAUSED_WHILE_HIDDEN;
1071 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1075 void Adaptor::NotifyLanguageChanged()
1077 mLanguageChangedSignal.Emit( mAdaptor );
1080 void Adaptor::RenderOnce()
1082 if( mThreadController )
1084 UpdateMode updateMode;
1085 if( mThreadMode == ThreadMode::NORMAL )
1087 updateMode = UpdateMode::NORMAL;
1091 updateMode = UpdateMode::FORCE_RENDER;
1093 ProcessCoreEvents();
1095 mThreadController->RequestUpdateOnce( updateMode );
1099 const LogFactoryInterface& Adaptor::GetLogFactory()
1101 return *mEnvironmentOptions;
1104 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1106 GetCore().RegisterProcessor(processor);
1109 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1111 GetCore().UnregisterProcessor(processor);
1114 bool Adaptor::IsMultipleWindowSupported() const
1116 return mConfigurationManager->IsMultipleWindowSupported();
1119 void Adaptor::RequestUpdateOnce()
1121 if( mThreadController )
1123 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1127 bool Adaptor::ProcessCoreEventsFromIdle()
1129 ProcessCoreEvents();
1131 // the idle handle automatically un-installs itself
1132 mNotificationOnIdleInstalled = false;
1137 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1139 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1141 for( auto window : mWindows )
1143 if ( scene == window->GetScene() )
1152 Dali::WindowContainer Adaptor::GetWindows() const
1154 Dali::WindowContainer windows;
1156 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1158 // Downcast to Dali::Window
1159 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1162 windows.push_back( window );
1169 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1171 Dali::SceneHolderList sceneHolderList;
1173 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1175 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1178 return sceneHolderList;
1181 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1183 Dali::ObjectRegistry registry;
1186 registry = mCore->GetObjectRegistry();
1191 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1193 mLanguageChangedSignal(),
1194 mWindowCreatedSignal(),
1195 mAdaptor( adaptor ),
1198 mThreadController( nullptr ),
1199 mGraphics( nullptr ),
1200 mDisplayConnection( nullptr ),
1202 mConfigurationManager( nullptr ),
1203 mPlatformAbstraction( nullptr ),
1204 mCallbackManager( nullptr ),
1205 mNotificationOnIdleInstalled( false ),
1206 mNotificationTrigger( nullptr ),
1207 mDaliFeedbackPlugin(),
1208 mFeedbackController( nullptr ),
1211 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1212 mPerformanceInterface( nullptr ),
1215 mObjectProfiler( nullptr ),
1217 mThreadMode( threadMode ),
1218 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1219 mUseRemoteSurface( false )
1221 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1222 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1224 gThreadLocalAdaptor = this;
1227 void Adaptor::SetRootLayoutDirection( std::string locale )
1229 for ( auto& window : mWindows )
1231 Dali::Actor root = window->GetRootLayer();
1232 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1233 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1237 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1239 bool idleAdded( false );
1241 // Only add an idle if the Adaptor is actually running
1242 if( RUNNING == mState || READY == mState || forceAdd )
1244 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1256 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1258 mCallbackManager->RemoveIdleEntererCallback( callback );
1261 } // namespace Adaptor
1263 } // namespace Internal