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 )
412 mAddOnManager->Start();
415 // Dali::Internal::Adaptor::Adaptor::Pause
416 void Adaptor::Pause()
418 // Only pause the adaptor if we're actually running.
419 if( RUNNING == mState )
421 // Inform observers that we are about to be paused.
422 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
428 mAddOnManager->Pause();
430 // Pause all windows event handlers when adaptor paused
431 for( auto window : mWindows )
436 mThreadController->Pause();
439 // Ensure any messages queued during pause callbacks are processed by doing another update.
442 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
446 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
450 // Dali::Internal::Adaptor::Adaptor::Resume
451 void Adaptor::Resume()
453 // Only resume the adaptor if we are in the suspended state.
454 if( PAUSED == mState )
458 // Reset the event handlers when adaptor resumed
459 for( auto window : mWindows )
464 // Resume AddOnManager
465 mAddOnManager->Resume();
467 // Inform observers that we have resumed.
468 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
473 // Trigger processing of events queued up while paused
474 mCore->ProcessEvents();
476 // Do at end to ensure our first update/render after resumption includes the processed messages as well
477 mThreadController->Resume();
479 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
483 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
489 if( RUNNING == mState ||
491 PAUSED_WHILE_HIDDEN == mState )
493 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
498 mAddOnManager->Stop();
500 mThreadController->Stop();
502 // Delete the TTS player
503 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
507 mTtsPlayers[i].Reset();
511 // Destroy the image loader plugin
512 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
514 delete mNotificationTrigger;
515 mNotificationTrigger = NULL;
517 mCallbackManager->Stop();
521 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
525 void Adaptor::ContextLost()
527 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
530 void Adaptor::ContextRegained()
532 // Inform core, so that texture resources can be reloaded
533 mCore->RecoverFromContextLoss();
535 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
538 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
540 Integration::Point convertedPoint( point );
541 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
544 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
546 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
547 mWindows.front()->FeedWheelEvent( event );
550 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
552 Integration::KeyEvent convertedEvent( keyEvent );
553 mWindows.front()->FeedKeyEvent( convertedEvent );
556 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
558 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
559 for( auto windowPtr : mWindows )
561 if( windowPtr == windowImpl ) // the window is not deleted
563 mResizedSignal.Emit( mAdaptor );
565 windowImpl->SetSurface( &newSurface );
567 // Flush the event queue to give the update-render thread chance
568 // to start processing messages for new camera setup etc as soon as possible
571 // This method blocks until the render thread has completed the replace.
572 mThreadController->ReplaceSurface( &newSurface );
578 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
580 // Flush the event queue to give the update-render thread chance
581 // to start processing messages for new camera setup etc as soon as possible
584 // This method blocks until the render thread has finished rendering the current surface.
585 mThreadController->DeleteSurface( &surface );
588 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
590 return *mWindows.front()->GetSurface();
593 void Adaptor::ReleaseSurfaceLock()
595 mWindows.front()->GetSurface()->ReleaseLock();
598 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
600 if( !mTtsPlayers[mode] )
602 // Create the TTS player when it needed, because it can reduce launching time.
603 mTtsPlayers[mode] = TtsPlayer::New(mode);
606 return mTtsPlayers[mode];
609 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
611 bool idleAdded(false);
613 // Only add an idle if the Adaptor is actually running
614 if( RUNNING == mState || READY == mState || forceAdd )
616 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
622 void Adaptor::RemoveIdle( CallbackBase* callback )
624 mCallbackManager->RemoveIdleCallback( callback );
627 void Adaptor::ProcessIdle()
629 bool idleProcessed = mCallbackManager->ProcessIdle();
630 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
633 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
635 mThreadController->SetPreRenderCallback( callback );
638 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
640 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
641 windowImpl.SetAdaptor( Get() );
643 // Add the new Window to the container - the order is not important
644 mWindows.push_back( &windowImpl );
646 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
648 mThreadController->AddSurface( surface );
650 mWindowCreatedSignal.Emit( childWindow );
655 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
657 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
658 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
660 if( *iter == &windowImpl )
662 mWindows.erase( iter );
670 bool Adaptor::RemoveWindow( std::string childWindowName )
672 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
674 if( ( *iter )->GetName() == childWindowName )
676 mWindows.erase( iter );
684 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
686 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
688 if( ( *iter )->GetId() == childWindow->GetId() )
690 mWindows.erase( iter );
698 Dali::Adaptor& Adaptor::Get()
700 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
701 return gThreadLocalAdaptor->mAdaptor;
704 bool Adaptor::IsAvailable()
706 return gThreadLocalAdaptor != NULL;
709 void Adaptor::SceneCreated()
711 mCore->SceneCreated();
714 Dali::Integration::Core& Adaptor::GetCore()
719 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
721 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
724 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
726 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
727 return *mDisplayConnection;
730 GraphicsInterface& Adaptor::GetGraphicsInterface()
732 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
733 return *( mGraphics.get() );
736 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
738 return *mPlatformAbstraction;
741 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
743 return *mNotificationTrigger;
746 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
748 return mSocketFactory;
751 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
753 if( !mWindows.empty() )
755 return mWindows.front()->GetSurface();
761 TraceInterface& Adaptor::GetKernelTraceInterface()
763 return mKernelTracer;
766 TraceInterface& Adaptor::GetSystemTraceInterface()
768 return mSystemTracer;
771 PerformanceInterface* Adaptor::GetPerformanceInterface()
773 return mPerformanceInterface;
776 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
778 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
779 return *mPlatformAbstraction;
782 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
787 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
789 if( mTtsPlayers[mode] )
791 mTtsPlayers[mode].Reset();
795 Any Adaptor::GetNativeWindowHandle()
797 return mWindows.front()->GetNativeHandle();
800 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
802 Any nativeWindowHandle;
804 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
806 for( auto sceneHolder : mWindows )
808 if ( scene == sceneHolder->GetScene() )
810 nativeWindowHandle = sceneHolder->GetNativeHandle();
815 return nativeWindowHandle;
818 Any Adaptor::GetGraphicsDisplay()
824 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
825 auto eglGraphics = static_cast<EglGraphics *>( graphics );
827 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
828 display = eglImpl.GetDisplay();
834 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
836 mUseRemoteSurface = useRemoteSurface;
839 void Adaptor::AddObserver( LifeCycleObserver& observer )
841 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
843 if ( match == mObservers.end() )
845 mObservers.push_back( &observer );
849 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
851 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
853 if ( match != mObservers.end() )
855 mObservers.erase( match );
859 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
863 mCore->QueueEvent(event);
867 void Adaptor::ProcessCoreEvents()
871 if( mPerformanceInterface )
873 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
876 mCore->ProcessEvents();
878 if( mPerformanceInterface )
880 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
885 void Adaptor::RequestUpdate( bool forceUpdate )
891 mThreadController->RequestUpdate();
895 case PAUSED_WHILE_HIDDEN:
899 // Update (and resource upload) without rendering
900 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
912 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
914 // Only request a notification if the Adaptor is actually running
915 // and we haven't installed the idle notification
916 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
918 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
922 void Adaptor::OnWindowShown()
924 if( PAUSED_WHILE_HIDDEN == mState )
926 // Adaptor can now be resumed
931 // Force a render task
934 else if( RUNNING == mState )
936 // Force a render task
939 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
943 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
947 void Adaptor::OnWindowHidden()
949 if( RUNNING == mState || READY == mState )
951 bool allWindowsHidden = true;
953 for( auto window : mWindows )
955 if ( window->IsVisible() )
957 allWindowsHidden = false;
962 // Only pause the adaptor when all the windows are hidden
963 if( allWindowsHidden )
965 if( mState == RUNNING )
969 // Adaptor cannot be resumed until any window is shown
970 mState = PAUSED_WHILE_HIDDEN;
972 else // mState is READY
974 // Pause the adaptor after the state gets RUNNING
975 mState = PAUSED_WHILE_INITIALIZING;
980 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
985 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
989 // Dali::Internal::Adaptor::Adaptor::OnDamaged
990 void Adaptor::OnDamaged( const DamageArea& area )
992 // This is needed for the case where Dali window is partially obscured
993 RequestUpdate( false );
996 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
998 mResizedSignal.Emit( mAdaptor );
1001 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1003 // Nofify surface resizing before flushing event queue
1004 mThreadController->ResizeSurface();
1006 // Flush the event queue to give the update-render thread chance
1007 // to start processing messages for new camera setup etc as soon as possible
1008 ProcessCoreEvents();
1011 void Adaptor::NotifySceneCreated()
1013 GetCore().SceneCreated();
1015 // Flush the event queue to give the update-render thread chance
1016 // to start processing messages for new camera setup etc as soon as possible
1017 ProcessCoreEvents();
1019 // Start thread controller after the scene has been created
1020 mThreadController->Start();
1022 // Process after surface is created (registering to remote surface provider if required)
1023 SurfaceInitialized();
1025 if( mState != PAUSED_WHILE_INITIALIZING )
1029 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1037 mState = PAUSED_WHILE_HIDDEN;
1039 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1043 void Adaptor::NotifyLanguageChanged()
1045 mLanguageChangedSignal.Emit( mAdaptor );
1048 void Adaptor::RenderOnce()
1050 if( mThreadController )
1052 UpdateMode updateMode;
1053 if( mThreadMode == ThreadMode::NORMAL )
1055 updateMode = UpdateMode::NORMAL;
1059 updateMode = UpdateMode::FORCE_RENDER;
1061 ProcessCoreEvents();
1063 mThreadController->RequestUpdateOnce( updateMode );
1067 const LogFactoryInterface& Adaptor::GetLogFactory()
1069 return *mEnvironmentOptions;
1072 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1074 GetCore().RegisterProcessor(processor);
1077 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1079 GetCore().UnregisterProcessor(processor);
1082 bool Adaptor::IsMultipleWindowSupported() const
1084 return mConfigurationManager->IsMultipleWindowSupported();
1087 void Adaptor::RequestUpdateOnce()
1089 if( mThreadController )
1091 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1095 bool Adaptor::ProcessCoreEventsFromIdle()
1097 ProcessCoreEvents();
1099 // the idle handle automatically un-installs itself
1100 mNotificationOnIdleInstalled = false;
1105 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1107 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1109 for( auto window : mWindows )
1111 if ( scene == window->GetScene() )
1120 Dali::WindowContainer Adaptor::GetWindows() const
1122 Dali::WindowContainer windows;
1124 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1126 // Downcast to Dali::Window
1127 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1130 windows.push_back( window );
1137 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1139 Dali::SceneHolderList sceneHolderList;
1141 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1143 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1146 return sceneHolderList;
1149 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1151 Dali::ObjectRegistry registry;
1154 registry = mCore->GetObjectRegistry();
1159 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1161 mLanguageChangedSignal(),
1162 mWindowCreatedSignal(),
1163 mAdaptor( adaptor ),
1166 mThreadController( nullptr ),
1167 mGraphics( nullptr ),
1168 mDisplayConnection( nullptr ),
1170 mConfigurationManager( nullptr ),
1171 mPlatformAbstraction( nullptr ),
1172 mCallbackManager( nullptr ),
1173 mNotificationOnIdleInstalled( false ),
1174 mNotificationTrigger( nullptr ),
1175 mDaliFeedbackPlugin(),
1176 mFeedbackController( nullptr ),
1179 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1180 mPerformanceInterface( nullptr ),
1183 mObjectProfiler( nullptr ),
1185 mThreadMode( ThreadMode::NORMAL ),
1186 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1187 mUseRemoteSurface( false )
1189 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1190 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1192 gThreadLocalAdaptor = this;
1195 void Adaptor::SetRootLayoutDirection( std::string locale )
1197 for ( auto& window : mWindows )
1199 Dali::Actor root = window->GetRootLayer();
1200 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1201 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1205 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1207 bool idleAdded( false );
1209 // Only add an idle if the Adaptor is actually running
1210 if( RUNNING == mState || READY == mState || forceAdd )
1212 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1224 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1226 mCallbackManager->RemoveIdleEntererCallback( callback );
1229 } // namespace Adaptor
1231 } // namespace Internal