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 // ChildWindow is set to the layout direction of the default window.
671 windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
673 // Add the new Window to the container - the order is not important
674 mWindows.push_back( &windowImpl );
676 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
678 mThreadController->AddSurface( surface );
680 mWindowCreatedSignal.Emit( childWindow );
685 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
687 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
688 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
690 if( *iter == &windowImpl )
692 mWindows.erase( iter );
700 bool Adaptor::RemoveWindow( std::string childWindowName )
702 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
704 if( ( *iter )->GetName() == childWindowName )
706 mWindows.erase( iter );
714 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
716 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
718 if( ( *iter )->GetId() == childWindow->GetId() )
720 mWindows.erase( iter );
728 Dali::Adaptor& Adaptor::Get()
730 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
731 return gThreadLocalAdaptor->mAdaptor;
734 bool Adaptor::IsAvailable()
736 return gThreadLocalAdaptor != NULL;
739 void Adaptor::SceneCreated()
741 mCore->SceneCreated();
744 Dali::Integration::Core& Adaptor::GetCore()
749 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
751 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
754 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
756 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
757 return *mDisplayConnection;
760 GraphicsInterface& Adaptor::GetGraphicsInterface()
762 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
763 return *( mGraphics.get() );
766 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
768 return *mPlatformAbstraction;
771 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
773 return *mNotificationTrigger;
776 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
778 return mSocketFactory;
781 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
783 if( !mWindows.empty() )
785 return mWindows.front()->GetSurface();
791 TraceInterface& Adaptor::GetKernelTraceInterface()
793 return mKernelTracer;
796 TraceInterface& Adaptor::GetSystemTraceInterface()
798 return mSystemTracer;
801 PerformanceInterface* Adaptor::GetPerformanceInterface()
803 return mPerformanceInterface;
806 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
808 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
809 return *mPlatformAbstraction;
812 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
817 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
819 if( mTtsPlayers[mode] )
821 mTtsPlayers[mode].Reset();
825 Any Adaptor::GetNativeWindowHandle()
827 return mWindows.front()->GetNativeHandle();
830 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
832 Any nativeWindowHandle;
834 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
836 for( auto sceneHolder : mWindows )
838 if ( scene == sceneHolder->GetScene() )
840 nativeWindowHandle = sceneHolder->GetNativeHandle();
845 return nativeWindowHandle;
848 Any Adaptor::GetGraphicsDisplay()
854 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
855 auto eglGraphics = static_cast<EglGraphics *>( graphics );
857 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
858 display = eglImpl.GetDisplay();
864 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
866 mUseRemoteSurface = useRemoteSurface;
869 void Adaptor::AddObserver( LifeCycleObserver& observer )
871 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
873 if ( match == mObservers.end() )
875 mObservers.push_back( &observer );
879 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
881 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
883 if ( match != mObservers.end() )
885 mObservers.erase( match );
889 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
893 mCore->QueueEvent(event);
897 void Adaptor::ProcessCoreEvents()
901 if( mPerformanceInterface )
903 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
906 mCore->ProcessEvents();
908 if( mPerformanceInterface )
910 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
915 void Adaptor::RequestUpdate( bool forceUpdate )
921 mThreadController->RequestUpdate();
925 case PAUSED_WHILE_HIDDEN:
929 // Update (and resource upload) without rendering
930 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
942 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
944 // Only request a notification if the Adaptor is actually running
945 // and we haven't installed the idle notification
946 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
948 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
952 void Adaptor::OnWindowShown()
954 if( PAUSED_WHILE_HIDDEN == mState )
956 // Adaptor can now be resumed
961 // Force a render task
964 else if( RUNNING == mState )
966 // Force a render task
969 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
971 else if( PAUSED_WHILE_INITIALIZING == mState )
973 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
978 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
982 void Adaptor::OnWindowHidden()
984 if( RUNNING == mState || READY == mState )
986 bool allWindowsHidden = true;
988 for( auto window : mWindows )
990 if ( window->IsVisible() )
992 allWindowsHidden = false;
997 // Only pause the adaptor when all the windows are hidden
998 if( allWindowsHidden )
1000 if( mState == RUNNING )
1004 // Adaptor cannot be resumed until any window is shown
1005 mState = PAUSED_WHILE_HIDDEN;
1007 else // mState is READY
1009 // Pause the adaptor after the state gets RUNNING
1010 mState = PAUSED_WHILE_INITIALIZING;
1015 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1020 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1024 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1025 void Adaptor::OnDamaged( const DamageArea& area )
1027 // This is needed for the case where Dali window is partially obscured
1028 RequestUpdate( false );
1031 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1033 mResizedSignal.Emit( mAdaptor );
1036 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1038 // Nofify surface resizing before flushing event queue
1039 mThreadController->ResizeSurface();
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();
1046 void Adaptor::NotifySceneCreated()
1048 GetCore().SceneCreated();
1050 // Flush the event queue to give the update-render thread chance
1051 // to start processing messages for new camera setup etc as soon as possible
1052 ProcessCoreEvents();
1054 // Start thread controller after the scene has been created
1055 mThreadController->Start();
1057 // Process after surface is created (registering to remote surface provider if required)
1058 SurfaceInitialized();
1060 if( mState != PAUSED_WHILE_INITIALIZING )
1064 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1072 mState = PAUSED_WHILE_HIDDEN;
1074 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1078 void Adaptor::NotifyLanguageChanged()
1080 mLanguageChangedSignal.Emit( mAdaptor );
1083 void Adaptor::RenderOnce()
1085 if( mThreadController )
1087 UpdateMode updateMode;
1088 if( mThreadMode == ThreadMode::NORMAL )
1090 updateMode = UpdateMode::NORMAL;
1094 updateMode = UpdateMode::FORCE_RENDER;
1096 ProcessCoreEvents();
1098 mThreadController->RequestUpdateOnce( updateMode );
1102 const LogFactoryInterface& Adaptor::GetLogFactory()
1104 return *mEnvironmentOptions;
1107 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1109 GetCore().RegisterProcessor(processor);
1112 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1114 GetCore().UnregisterProcessor(processor);
1117 bool Adaptor::IsMultipleWindowSupported() const
1119 return mConfigurationManager->IsMultipleWindowSupported();
1122 void Adaptor::RequestUpdateOnce()
1124 if( mThreadController )
1126 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1130 bool Adaptor::ProcessCoreEventsFromIdle()
1132 ProcessCoreEvents();
1134 // the idle handle automatically un-installs itself
1135 mNotificationOnIdleInstalled = false;
1140 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1142 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1144 for( auto window : mWindows )
1146 if ( scene == window->GetScene() )
1155 Dali::WindowContainer Adaptor::GetWindows() const
1157 Dali::WindowContainer windows;
1159 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1161 // Downcast to Dali::Window
1162 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1165 windows.push_back( window );
1172 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1174 Dali::SceneHolderList sceneHolderList;
1176 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1178 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1181 return sceneHolderList;
1184 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1186 Dali::ObjectRegistry registry;
1189 registry = mCore->GetObjectRegistry();
1194 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1196 mLanguageChangedSignal(),
1197 mWindowCreatedSignal(),
1198 mAdaptor( adaptor ),
1201 mThreadController( nullptr ),
1202 mGraphics( nullptr ),
1203 mDisplayConnection( nullptr ),
1205 mConfigurationManager( nullptr ),
1206 mPlatformAbstraction( nullptr ),
1207 mCallbackManager( nullptr ),
1208 mNotificationOnIdleInstalled( false ),
1209 mNotificationTrigger( nullptr ),
1210 mDaliFeedbackPlugin(),
1211 mFeedbackController( nullptr ),
1214 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1215 mPerformanceInterface( nullptr ),
1218 mObjectProfiler( nullptr ),
1220 mThreadMode( threadMode ),
1221 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1222 mUseRemoteSurface( false ),
1223 mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1225 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1226 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1228 gThreadLocalAdaptor = this;
1231 void Adaptor::SetRootLayoutDirection( std::string locale )
1233 mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1234 for ( auto& window : mWindows )
1236 Dali::Actor root = window->GetRootLayer();
1237 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1241 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1243 bool idleAdded( false );
1245 // Only add an idle if the Adaptor is actually running
1246 if( RUNNING == mState || READY == mState || forceAdd )
1248 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1260 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1262 mCallbackManager->RemoveIdleEntererCallback( callback );
1265 } // namespace Adaptor
1267 } // namespace Internal