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, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
652 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
653 windowImpl.SetAdaptor( Get() );
655 // Add the new Window to the container - the order is not important
656 mWindows.push_back( &windowImpl );
658 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
660 mThreadController->AddSurface( surface );
662 mWindowCreatedSignal.Emit( childWindow );
667 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
669 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
670 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
672 if( *iter == &windowImpl )
674 mWindows.erase( iter );
682 bool Adaptor::RemoveWindow( std::string childWindowName )
684 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
686 if( ( *iter )->GetName() == childWindowName )
688 mWindows.erase( iter );
696 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
698 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
700 if( ( *iter )->GetId() == childWindow->GetId() )
702 mWindows.erase( iter );
710 Dali::Adaptor& Adaptor::Get()
712 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
713 return gThreadLocalAdaptor->mAdaptor;
716 bool Adaptor::IsAvailable()
718 return gThreadLocalAdaptor != NULL;
721 void Adaptor::SceneCreated()
723 mCore->SceneCreated();
726 Dali::Integration::Core& Adaptor::GetCore()
731 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
733 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
736 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
738 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
739 return *mDisplayConnection;
742 GraphicsInterface& Adaptor::GetGraphicsInterface()
744 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
745 return *( mGraphics.get() );
748 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
750 return *mPlatformAbstraction;
753 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
755 return *mNotificationTrigger;
758 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
760 return mSocketFactory;
763 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
765 if( !mWindows.empty() )
767 return mWindows.front()->GetSurface();
773 TraceInterface& Adaptor::GetKernelTraceInterface()
775 return mKernelTracer;
778 TraceInterface& Adaptor::GetSystemTraceInterface()
780 return mSystemTracer;
783 PerformanceInterface* Adaptor::GetPerformanceInterface()
785 return mPerformanceInterface;
788 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
790 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
791 return *mPlatformAbstraction;
794 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
799 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
801 if( mTtsPlayers[mode] )
803 mTtsPlayers[mode].Reset();
807 Any Adaptor::GetNativeWindowHandle()
809 return mWindows.front()->GetNativeHandle();
812 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
814 Any nativeWindowHandle;
816 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
818 for( auto sceneHolder : mWindows )
820 if ( scene == sceneHolder->GetScene() )
822 nativeWindowHandle = sceneHolder->GetNativeHandle();
827 return nativeWindowHandle;
830 Any Adaptor::GetGraphicsDisplay()
836 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
837 auto eglGraphics = static_cast<EglGraphics *>( graphics );
839 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
840 display = eglImpl.GetDisplay();
846 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
848 mUseRemoteSurface = useRemoteSurface;
851 void Adaptor::AddObserver( LifeCycleObserver& observer )
853 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
855 if ( match == mObservers.end() )
857 mObservers.push_back( &observer );
861 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
863 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
865 if ( match != mObservers.end() )
867 mObservers.erase( match );
871 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
875 mCore->QueueEvent(event);
879 void Adaptor::ProcessCoreEvents()
883 if( mPerformanceInterface )
885 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
888 mCore->ProcessEvents();
890 if( mPerformanceInterface )
892 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
897 void Adaptor::RequestUpdate( bool forceUpdate )
903 mThreadController->RequestUpdate();
907 case PAUSED_WHILE_HIDDEN:
911 // Update (and resource upload) without rendering
912 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
924 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
926 // Only request a notification if the Adaptor is actually running
927 // and we haven't installed the idle notification
928 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
930 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
934 void Adaptor::OnWindowShown()
936 if( PAUSED_WHILE_HIDDEN == mState )
938 // Adaptor can now be resumed
943 // Force a render task
946 else if( RUNNING == mState )
948 // Force a render task
951 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
953 else if( PAUSED_WHILE_INITIALIZING == mState )
955 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
960 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
964 void Adaptor::OnWindowHidden()
966 if( RUNNING == mState || READY == mState )
968 bool allWindowsHidden = true;
970 for( auto window : mWindows )
972 if ( window->IsVisible() )
974 allWindowsHidden = false;
979 // Only pause the adaptor when all the windows are hidden
980 if( allWindowsHidden )
982 if( mState == RUNNING )
986 // Adaptor cannot be resumed until any window is shown
987 mState = PAUSED_WHILE_HIDDEN;
989 else // mState is READY
991 // Pause the adaptor after the state gets RUNNING
992 mState = PAUSED_WHILE_INITIALIZING;
997 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1002 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1006 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1007 void Adaptor::OnDamaged( const DamageArea& area )
1009 // This is needed for the case where Dali window is partially obscured
1010 RequestUpdate( false );
1013 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1015 mResizedSignal.Emit( mAdaptor );
1018 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1020 // Nofify surface resizing before flushing event queue
1021 mThreadController->ResizeSurface();
1023 // Flush the event queue to give the update-render thread chance
1024 // to start processing messages for new camera setup etc as soon as possible
1025 ProcessCoreEvents();
1028 void Adaptor::NotifySceneCreated()
1030 GetCore().SceneCreated();
1032 // Flush the event queue to give the update-render thread chance
1033 // to start processing messages for new camera setup etc as soon as possible
1034 ProcessCoreEvents();
1036 // Start thread controller after the scene has been created
1037 mThreadController->Start();
1039 // Process after surface is created (registering to remote surface provider if required)
1040 SurfaceInitialized();
1042 if( mState != PAUSED_WHILE_INITIALIZING )
1046 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1054 mState = PAUSED_WHILE_HIDDEN;
1056 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1060 void Adaptor::NotifyLanguageChanged()
1062 mLanguageChangedSignal.Emit( mAdaptor );
1065 void Adaptor::RenderOnce()
1067 if( mThreadController )
1069 UpdateMode updateMode;
1070 if( mThreadMode == ThreadMode::NORMAL )
1072 updateMode = UpdateMode::NORMAL;
1076 updateMode = UpdateMode::FORCE_RENDER;
1078 ProcessCoreEvents();
1080 mThreadController->RequestUpdateOnce( updateMode );
1084 const LogFactoryInterface& Adaptor::GetLogFactory()
1086 return *mEnvironmentOptions;
1089 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1091 GetCore().RegisterProcessor(processor);
1094 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1096 GetCore().UnregisterProcessor(processor);
1099 bool Adaptor::IsMultipleWindowSupported() const
1101 return mConfigurationManager->IsMultipleWindowSupported();
1104 void Adaptor::RequestUpdateOnce()
1106 if( mThreadController )
1108 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1112 bool Adaptor::ProcessCoreEventsFromIdle()
1114 ProcessCoreEvents();
1116 // the idle handle automatically un-installs itself
1117 mNotificationOnIdleInstalled = false;
1122 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1124 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1126 for( auto window : mWindows )
1128 if ( scene == window->GetScene() )
1137 Dali::WindowContainer Adaptor::GetWindows() const
1139 Dali::WindowContainer windows;
1141 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1143 // Downcast to Dali::Window
1144 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1147 windows.push_back( window );
1154 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1156 Dali::SceneHolderList sceneHolderList;
1158 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1160 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1163 return sceneHolderList;
1166 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1168 Dali::ObjectRegistry registry;
1171 registry = mCore->GetObjectRegistry();
1176 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1178 mLanguageChangedSignal(),
1179 mWindowCreatedSignal(),
1180 mAdaptor( adaptor ),
1183 mThreadController( nullptr ),
1184 mGraphics( nullptr ),
1185 mDisplayConnection( nullptr ),
1187 mConfigurationManager( nullptr ),
1188 mPlatformAbstraction( nullptr ),
1189 mCallbackManager( nullptr ),
1190 mNotificationOnIdleInstalled( false ),
1191 mNotificationTrigger( nullptr ),
1192 mDaliFeedbackPlugin(),
1193 mFeedbackController( nullptr ),
1196 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1197 mPerformanceInterface( nullptr ),
1200 mObjectProfiler( nullptr ),
1202 mThreadMode( ThreadMode::NORMAL ),
1203 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1204 mUseRemoteSurface( false )
1206 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1207 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1209 gThreadLocalAdaptor = this;
1212 void Adaptor::SetRootLayoutDirection( std::string locale )
1214 for ( auto& window : mWindows )
1216 Dali::Actor root = window->GetRootLayer();
1217 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1218 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1222 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1224 bool idleAdded( false );
1226 // Only add an idle if the Adaptor is actually running
1227 if( RUNNING == mState || READY == mState || forceAdd )
1229 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1241 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1243 mCallbackManager->RemoveIdleEntererCallback( callback );
1246 } // namespace Adaptor
1248 } // namespace Internal