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 )
100 Dali::Adaptor* adaptor = new Dali::Adaptor;
101 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
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::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
115 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
116 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
117 windowImpl.SetAdaptor( *adaptor );
121 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
123 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
124 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
125 adaptor->mImpl = impl;
127 impl->Initialize( graphicsFactory, configuration );
132 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
134 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
135 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
136 windowImpl.SetAdaptor( *adaptor );
140 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
142 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
143 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
144 mEnvironmentOptions->SetLogFunction( logFunction );
145 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
147 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
150 GetDataStoragePath( path );
151 mPlatformAbstraction->SetDataStoragePath( path );
153 if( mEnvironmentOptions->PerformanceServerRequired() )
155 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
158 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
159 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
161 mCallbackManager = CallbackManager::New();
163 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
165 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
167 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
168 mGraphics->Initialize( mEnvironmentOptions );
170 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
171 auto eglGraphics = static_cast<EglGraphics *>( graphics );
173 // This will only be created once
174 eglGraphics->Create();
176 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
177 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
178 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
180 // Create the AddOnManager
181 mAddOnManager.reset( Dali::Internal::AddOnManagerFactory::CreateAddOnManager() );
183 mCore = Integration::Core::New( *this,
184 *mPlatformAbstraction,
187 eglContextHelperImpl,
188 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
189 mGraphics->GetDepthBufferRequired(),
190 mGraphics->GetStencilBufferRequired(),
191 mGraphics->GetPartialUpdateRequired() );
194 defaultWindow->SetAdaptor( Get() );
196 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
198 mWindowCreatedSignal.Emit( defaultSceneHolder );
200 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
201 if( 0u < timeInterval )
203 mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
206 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
208 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
210 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
212 // Should be called after Core creation
213 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
215 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
217 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
219 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
221 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
223 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
225 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
227 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
229 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
231 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
233 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
235 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
237 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
239 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
241 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
243 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
245 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
247 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
249 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
251 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
253 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
255 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
257 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
259 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
261 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
263 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
265 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
267 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
269 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
271 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
273 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
275 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
277 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
279 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
281 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
283 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
285 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
287 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
289 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
291 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
293 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
295 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
297 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
299 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
301 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
303 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
305 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
307 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
310 std::string systemCachePath = GetSystemCachePath();
311 if( ! systemCachePath.empty() )
313 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
314 if ( 0 != dir_err && errno != EEXIST )
316 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
321 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
326 // Ensure stop status
329 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
330 gThreadLocalAdaptor = NULL;
332 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
334 (*iter)->OnDestroy();
337 // Clear out all the handles to Windows
340 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
341 delete mObjectProfiler;
345 delete mDisplayConnection;
346 delete mPlatformAbstraction;
347 delete mCallbackManager;
348 delete mPerformanceInterface;
350 mGraphics->Destroy();
352 // uninstall it on this thread (main actor thread)
353 Dali::Integration::Log::UninstallLogFunction();
355 // Delete environment options if we own it
356 if( mEnvironmentOptionsOwned )
358 delete mEnvironmentOptions;
362 void Adaptor::Start()
364 // It doesn't support restart after stop at this moment to support restarting, need more testing
365 if( READY != mState )
372 SetupSystemInformation();
374 // Start the callback manager
375 mCallbackManager->Start();
377 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
379 unsigned int dpiHor, dpiVer;
382 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
384 // set the DPI value for font rendering
385 FontClient fontClient = FontClient::Get();
386 fontClient.SetDpi( dpiHor, dpiVer );
388 // Initialize the thread controller
389 mThreadController->Initialize();
391 // Set max texture size
392 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
394 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
398 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
399 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
402 ProcessCoreEvents(); // Ensure any startup messages are processed.
404 // Initialize the image loader plugin
405 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
407 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
414 mAddOnManager->Start();
418 // Dali::Internal::Adaptor::Adaptor::Pause
419 void Adaptor::Pause()
421 // Only pause the adaptor if we're actually running.
422 if( RUNNING == mState )
424 // Inform observers that we are about to be paused.
425 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
433 mAddOnManager->Pause();
436 // Pause all windows event handlers when adaptor paused
437 for( auto window : mWindows )
442 mThreadController->Pause();
445 // Ensure any messages queued during pause callbacks are processed by doing another update.
448 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
452 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
456 // Dali::Internal::Adaptor::Adaptor::Resume
457 void Adaptor::Resume()
459 // Only resume the adaptor if we are in the suspended state.
460 if( PAUSED == mState )
464 // Reset the event handlers when adaptor resumed
465 for( auto window : mWindows )
470 // Resume AddOnManager
473 mAddOnManager->Resume();
476 // Inform observers that we have resumed.
477 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
482 // Trigger processing of events queued up while paused
483 mCore->ProcessEvents();
485 // Do at end to ensure our first update/render after resumption includes the processed messages as well
486 mThreadController->Resume();
488 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
492 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
498 if( RUNNING == mState ||
500 PAUSED_WHILE_HIDDEN == mState )
502 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
509 mAddOnManager->Stop();
512 mThreadController->Stop();
514 // Delete the TTS player
515 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
519 mTtsPlayers[i].Reset();
523 // Destroy the image loader plugin
524 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
526 delete mNotificationTrigger;
527 mNotificationTrigger = NULL;
529 mCallbackManager->Stop();
533 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
537 void Adaptor::ContextLost()
539 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
542 void Adaptor::ContextRegained()
544 // Inform core, so that texture resources can be reloaded
545 mCore->RecoverFromContextLoss();
547 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
550 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
552 Integration::Point convertedPoint( point );
553 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
556 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
558 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
559 mWindows.front()->FeedWheelEvent( event );
562 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
564 Integration::KeyEvent convertedEvent( keyEvent );
565 mWindows.front()->FeedKeyEvent( convertedEvent );
568 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
570 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
571 for( auto windowPtr : mWindows )
573 if( windowPtr == windowImpl ) // the window is not deleted
575 mResizedSignal.Emit( mAdaptor );
577 windowImpl->SetSurface( &newSurface );
579 // Flush the event queue to give the update-render thread chance
580 // to start processing messages for new camera setup etc as soon as possible
583 // This method blocks until the render thread has completed the replace.
584 mThreadController->ReplaceSurface( &newSurface );
590 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
592 // Flush the event queue to give the update-render thread chance
593 // to start processing messages for new camera setup etc as soon as possible
596 // This method blocks until the render thread has finished rendering the current surface.
597 mThreadController->DeleteSurface( &surface );
600 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
602 return *mWindows.front()->GetSurface();
605 void Adaptor::ReleaseSurfaceLock()
607 mWindows.front()->GetSurface()->ReleaseLock();
610 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
612 if( !mTtsPlayers[mode] )
614 // Create the TTS player when it needed, because it can reduce launching time.
615 mTtsPlayers[mode] = TtsPlayer::New(mode);
618 return mTtsPlayers[mode];
621 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
623 bool idleAdded(false);
625 // Only add an idle if the Adaptor is actually running
626 if( RUNNING == mState || READY == mState || forceAdd )
628 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
634 void Adaptor::RemoveIdle( CallbackBase* callback )
636 mCallbackManager->RemoveIdleCallback( callback );
639 void Adaptor::ProcessIdle()
641 bool idleProcessed = mCallbackManager->ProcessIdle();
642 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
645 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
647 mThreadController->SetPreRenderCallback( callback );
650 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
652 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
653 windowImpl.SetAdaptor( Get() );
655 // ChildWindow is set to the layout direction of the default window.
656 windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
658 // Add the new Window to the container - the order is not important
659 mWindows.push_back( &windowImpl );
661 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
663 mThreadController->AddSurface( surface );
665 mWindowCreatedSignal.Emit( childWindow );
670 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
672 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
673 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
675 if( *iter == &windowImpl )
677 mWindows.erase( iter );
685 bool Adaptor::RemoveWindow( std::string childWindowName )
687 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
689 if( ( *iter )->GetName() == childWindowName )
691 mWindows.erase( iter );
699 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
701 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
703 if( ( *iter )->GetId() == childWindow->GetId() )
705 mWindows.erase( iter );
713 Dali::Adaptor& Adaptor::Get()
715 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
716 return gThreadLocalAdaptor->mAdaptor;
719 bool Adaptor::IsAvailable()
721 return gThreadLocalAdaptor != NULL;
724 void Adaptor::SceneCreated()
726 mCore->SceneCreated();
729 Dali::Integration::Core& Adaptor::GetCore()
734 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
736 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
739 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
741 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
742 return *mDisplayConnection;
745 GraphicsInterface& Adaptor::GetGraphicsInterface()
747 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
748 return *( mGraphics.get() );
751 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
753 return *mPlatformAbstraction;
756 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
758 return *mNotificationTrigger;
761 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
763 return mSocketFactory;
766 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
768 if( !mWindows.empty() )
770 return mWindows.front()->GetSurface();
776 TraceInterface& Adaptor::GetKernelTraceInterface()
778 return mKernelTracer;
781 TraceInterface& Adaptor::GetSystemTraceInterface()
783 return mSystemTracer;
786 PerformanceInterface* Adaptor::GetPerformanceInterface()
788 return mPerformanceInterface;
791 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
793 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
794 return *mPlatformAbstraction;
797 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
802 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
804 if( mTtsPlayers[mode] )
806 mTtsPlayers[mode].Reset();
810 Any Adaptor::GetNativeWindowHandle()
812 return mWindows.front()->GetNativeHandle();
815 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
817 Any nativeWindowHandle;
819 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
821 for( auto sceneHolder : mWindows )
823 if ( scene == sceneHolder->GetScene() )
825 nativeWindowHandle = sceneHolder->GetNativeHandle();
830 return nativeWindowHandle;
833 Any Adaptor::GetGraphicsDisplay()
839 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
840 auto eglGraphics = static_cast<EglGraphics *>( graphics );
842 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
843 display = eglImpl.GetDisplay();
849 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
851 mUseRemoteSurface = useRemoteSurface;
854 void Adaptor::AddObserver( LifeCycleObserver& observer )
856 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
858 if ( match == mObservers.end() )
860 mObservers.push_back( &observer );
864 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
866 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
868 if ( match != mObservers.end() )
870 mObservers.erase( match );
874 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
878 mCore->QueueEvent(event);
882 void Adaptor::ProcessCoreEvents()
886 if( mPerformanceInterface )
888 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
891 mCore->ProcessEvents();
893 if( mPerformanceInterface )
895 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
900 void Adaptor::RequestUpdate( bool forceUpdate )
906 mThreadController->RequestUpdate();
910 case PAUSED_WHILE_HIDDEN:
914 // Update (and resource upload) without rendering
915 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
927 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
929 // Only request a notification if the Adaptor is actually running
930 // and we haven't installed the idle notification
931 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
933 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
937 void Adaptor::OnWindowShown()
939 if( PAUSED_WHILE_HIDDEN == mState )
941 // Adaptor can now be resumed
946 // Force a render task
949 else if( RUNNING == mState )
951 // Force a render task
954 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
956 else if( PAUSED_WHILE_INITIALIZING == mState )
958 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
963 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
967 void Adaptor::OnWindowHidden()
969 if( RUNNING == mState || READY == mState )
971 bool allWindowsHidden = true;
973 for( auto window : mWindows )
975 if ( window->IsVisible() )
977 allWindowsHidden = false;
982 // Only pause the adaptor when all the windows are hidden
983 if( allWindowsHidden )
985 if( mState == RUNNING )
989 // Adaptor cannot be resumed until any window is shown
990 mState = PAUSED_WHILE_HIDDEN;
992 else // mState is READY
994 // Pause the adaptor after the state gets RUNNING
995 mState = PAUSED_WHILE_INITIALIZING;
1000 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1005 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1009 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1010 void Adaptor::OnDamaged( const DamageArea& area )
1012 // This is needed for the case where Dali window is partially obscured
1013 RequestUpdate( false );
1016 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1018 mResizedSignal.Emit( mAdaptor );
1021 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1023 // Nofify surface resizing before flushing event queue
1024 mThreadController->ResizeSurface();
1026 // Flush the event queue to give the update-render thread chance
1027 // to start processing messages for new camera setup etc as soon as possible
1028 ProcessCoreEvents();
1031 void Adaptor::NotifySceneCreated()
1033 GetCore().SceneCreated();
1035 // Flush the event queue to give the update-render thread chance
1036 // to start processing messages for new camera setup etc as soon as possible
1037 ProcessCoreEvents();
1039 // Start thread controller after the scene has been created
1040 mThreadController->Start();
1042 // Process after surface is created (registering to remote surface provider if required)
1043 SurfaceInitialized();
1045 if( mState != PAUSED_WHILE_INITIALIZING )
1049 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1057 mState = PAUSED_WHILE_HIDDEN;
1059 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1063 void Adaptor::NotifyLanguageChanged()
1065 mLanguageChangedSignal.Emit( mAdaptor );
1068 void Adaptor::RenderOnce()
1070 if( mThreadController )
1072 UpdateMode updateMode;
1073 if( mThreadMode == ThreadMode::NORMAL )
1075 updateMode = UpdateMode::NORMAL;
1079 updateMode = UpdateMode::FORCE_RENDER;
1081 ProcessCoreEvents();
1083 mThreadController->RequestUpdateOnce( updateMode );
1087 const LogFactoryInterface& Adaptor::GetLogFactory()
1089 return *mEnvironmentOptions;
1092 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1094 GetCore().RegisterProcessor(processor);
1097 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1099 GetCore().UnregisterProcessor(processor);
1102 bool Adaptor::IsMultipleWindowSupported() const
1104 return mConfigurationManager->IsMultipleWindowSupported();
1107 void Adaptor::RequestUpdateOnce()
1109 if( mThreadController )
1111 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1115 bool Adaptor::ProcessCoreEventsFromIdle()
1117 ProcessCoreEvents();
1119 // the idle handle automatically un-installs itself
1120 mNotificationOnIdleInstalled = false;
1125 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1127 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1129 for( auto window : mWindows )
1131 if ( scene == window->GetScene() )
1140 Dali::WindowContainer Adaptor::GetWindows() const
1142 Dali::WindowContainer windows;
1144 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1146 // Downcast to Dali::Window
1147 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1150 windows.push_back( window );
1157 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1159 Dali::SceneHolderList sceneHolderList;
1161 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1163 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1166 return sceneHolderList;
1169 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1171 Dali::ObjectRegistry registry;
1174 registry = mCore->GetObjectRegistry();
1179 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1181 mLanguageChangedSignal(),
1182 mWindowCreatedSignal(),
1183 mAdaptor( adaptor ),
1186 mThreadController( nullptr ),
1187 mGraphics( nullptr ),
1188 mDisplayConnection( nullptr ),
1190 mConfigurationManager( nullptr ),
1191 mPlatformAbstraction( nullptr ),
1192 mCallbackManager( nullptr ),
1193 mNotificationOnIdleInstalled( false ),
1194 mNotificationTrigger( nullptr ),
1195 mDaliFeedbackPlugin(),
1196 mFeedbackController( nullptr ),
1199 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1200 mPerformanceInterface( nullptr ),
1203 mObjectProfiler( nullptr ),
1205 mThreadMode( ThreadMode::NORMAL ),
1206 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1207 mUseRemoteSurface( false ),
1208 mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1210 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1211 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1213 gThreadLocalAdaptor = this;
1216 void Adaptor::SetRootLayoutDirection( std::string locale )
1218 mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1219 for ( auto& window : mWindows )
1221 Dali::Actor root = window->GetRootLayer();
1222 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1226 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1228 bool idleAdded( false );
1230 // Only add an idle if the Adaptor is actually running
1231 if( RUNNING == mState || READY == mState || forceAdd )
1233 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1245 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1247 mCallbackManager->RemoveIdleEntererCallback( callback );
1250 } // namespace Adaptor
1252 } // namespace Internal