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/adaptor/common/adaptor-builder-impl.h>
25 #include <dali/public-api/common/stage.h>
26 #include <dali/public-api/actors/layer.h>
27 #include <dali/public-api/object/any.h>
28 #include <dali/devel-api/actors/actor-devel.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/integration-api/core.h>
31 #include <dali/integration-api/context-notifier.h>
32 #include <dali/integration-api/profiling.h>
33 #include <dali/integration-api/input-options.h>
34 #include <dali/integration-api/events/key-event-integ.h>
35 #include <dali/integration-api/events/touch-event-integ.h>
36 #include <dali/integration-api/events/wheel-event-integ.h>
37 #include <dali/integration-api/processor-interface.h>
40 #include <dali/public-api/dali-adaptor-common.h>
41 #include <dali/internal/system/common/thread-controller.h>
42 #include <dali/internal/system/common/performance-interface-factory.h>
43 #include <dali/internal/adaptor/common/lifecycle-observer.h>
44 #include <dali/internal/adaptor/common/thread-controller-interface.h>
46 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
47 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
49 #include <dali/devel-api/text-abstraction/font-client.h>
51 #include <dali/internal/system/common/callback-manager.h>
52 #include <dali/internal/accessibility/common/tts-player-impl.h>
53 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
54 #include <dali/internal/window-system/common/event-handler.h>
55 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
56 #include <dali/internal/graphics/gles/gl-implementation.h>
57 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
58 #include <dali/internal/graphics/common/egl-image-extensions.h>
59 #include <dali/internal/clipboard/common/clipboard-impl.h>
60 #include <dali/internal/system/common/object-profiler.h>
61 #include <dali/internal/window-system/common/display-connection.h>
62 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
63 #include <dali/internal/window-system/common/window-impl.h>
64 #include <dali/internal/window-system/common/window-render-surface.h>
66 #include <dali/internal/system/common/logging.h>
68 #include <dali/internal/system/common/locale-utils.h>
69 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
70 #include <dali/internal/imaging/common/image-loader.h>
72 #include <dali/internal/system/common/configuration-manager.h>
73 #include <dali/internal/system/common/environment-variables.h>
75 using Dali::TextAbstraction::FontClient;
77 extern std::string GetSystemCachePath();
91 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
93 } // unnamed namespace
95 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
97 Dali::Adaptor* adaptor = new Dali::Adaptor;
98 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
99 adaptor->mImpl = impl;
101 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
102 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
104 impl->Initialize( graphicsFactory, configuration );
105 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
110 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
112 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
113 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
114 windowImpl.SetAdaptor( *adaptor );
118 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
120 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
121 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
122 adaptor->mImpl = impl;
124 impl->Initialize( graphicsFactory, configuration );
129 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
131 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
132 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
133 windowImpl.SetAdaptor( *adaptor );
137 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
139 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
140 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
141 mEnvironmentOptions->SetLogFunction( logFunction );
142 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
144 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
147 GetDataStoragePath( path );
148 mPlatformAbstraction->SetDataStoragePath( path );
150 if( mEnvironmentOptions->PerformanceServerRequired() )
152 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
155 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
156 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
158 mCallbackManager = CallbackManager::New();
160 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
162 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
164 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
165 mGraphics->Initialize( mEnvironmentOptions );
167 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
168 auto eglGraphics = static_cast<EglGraphics *>( graphics );
170 // This will only be created once
171 eglGraphics->Create();
173 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
174 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
175 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
177 mCore = Integration::Core::New( *this,
178 *mPlatformAbstraction,
181 eglContextHelperImpl,
182 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
183 mGraphics->GetDepthBufferRequired(),
184 mGraphics->GetStencilBufferRequired(),
185 mGraphics->GetPartialUpdateRequired() );
187 defaultWindow->SetAdaptor( Get() );
189 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
191 mWindowCreatedSignal.Emit( defaultSceneHolder );
193 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
194 if( 0u < timeInterval )
196 mObjectProfiler = new ObjectProfiler( timeInterval );
199 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
201 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
203 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
205 // Should be called after Core creation
206 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
208 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
210 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
212 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
214 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
216 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
218 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
220 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
222 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
224 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
226 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
228 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
230 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
232 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
234 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
236 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
238 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
240 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
242 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
244 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
246 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
248 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
250 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
252 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
254 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
256 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
258 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
260 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
262 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
264 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
266 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
268 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
270 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
272 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
274 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
276 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
278 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
280 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
282 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
284 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
286 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
288 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
290 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
292 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
294 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
296 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
298 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
300 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
303 std::string systemCachePath = GetSystemCachePath();
304 if( ! systemCachePath.empty() )
306 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
307 if ( 0 != dir_err && errno != EEXIST )
309 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
314 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
319 // Ensure stop status
322 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
323 gThreadLocalAdaptor = NULL;
325 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
327 (*iter)->OnDestroy();
330 // Clear out all the handles to Windows
333 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
334 delete mObjectProfiler;
338 delete mDisplayConnection;
339 delete mPlatformAbstraction;
340 delete mCallbackManager;
341 delete mPerformanceInterface;
343 mGraphics->Destroy();
345 // uninstall it on this thread (main actor thread)
346 Dali::Integration::Log::UninstallLogFunction();
348 // Delete environment options if we own it
349 if( mEnvironmentOptionsOwned )
351 delete mEnvironmentOptions;
355 void Adaptor::Start()
357 // It doesn't support restart after stop at this moment to support restarting, need more testing
358 if( READY != mState )
365 SetupSystemInformation();
367 // Start the callback manager
368 mCallbackManager->Start();
370 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
372 unsigned int dpiHor, dpiVer;
375 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
377 // set the DPI value for font rendering
378 FontClient fontClient = FontClient::Get();
379 fontClient.SetDpi( dpiHor, dpiVer );
381 // Initialize the thread controller
382 mThreadController->Initialize();
384 // Set max texture size
385 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
387 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
391 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
392 setenv( DALI_ENV_MAX_TEXTURE_SIZE, std::to_string( maxTextureSize ).c_str(), 1 );
393 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
396 ProcessCoreEvents(); // Ensure any startup messages are processed.
398 // Initialize the image loader plugin
399 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
401 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
407 // Dali::Internal::Adaptor::Adaptor::Pause
408 void Adaptor::Pause()
410 // Only pause the adaptor if we're actually running.
411 if( RUNNING == mState )
413 // Inform observers that we are about to be paused.
414 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
419 // Pause all windows event handlers when adaptor paused
420 for( auto window : mWindows )
425 mThreadController->Pause();
428 // Ensure any messages queued during pause callbacks are processed by doing another update.
431 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
435 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
439 // Dali::Internal::Adaptor::Adaptor::Resume
440 void Adaptor::Resume()
442 // Only resume the adaptor if we are in the suspended state.
443 if( PAUSED == mState )
447 // Reset the event handlers when adaptor resumed
448 for( auto window : mWindows )
453 // Inform observers that we have resumed.
454 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
459 // Trigger processing of events queued up while paused
460 mCore->ProcessEvents();
462 // Do at end to ensure our first update/render after resumption includes the processed messages as well
463 mThreadController->Resume();
465 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
469 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
475 if( RUNNING == mState ||
477 PAUSED_WHILE_HIDDEN == mState )
479 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
484 mThreadController->Stop();
486 // Delete the TTS player
487 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
491 mTtsPlayers[i].Reset();
495 // Destroy the image loader plugin
496 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
498 delete mNotificationTrigger;
499 mNotificationTrigger = NULL;
501 mCallbackManager->Stop();
505 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
509 void Adaptor::ContextLost()
511 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
514 void Adaptor::ContextRegained()
516 // Inform core, so that texture resources can be reloaded
517 mCore->RecoverFromContextLoss();
519 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
522 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
524 Integration::Point convertedPoint( point );
525 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
528 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
530 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
531 mWindows.front()->FeedWheelEvent( event );
534 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
536 Integration::KeyEvent convertedEvent( keyEvent );
537 mWindows.front()->FeedKeyEvent( convertedEvent );
540 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
542 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
543 for( auto windowPtr : mWindows )
545 if( windowPtr == windowImpl ) // the window is not deleted
547 mResizedSignal.Emit( mAdaptor );
549 windowImpl->SetSurface( &newSurface );
551 // Flush the event queue to give the update-render thread chance
552 // to start processing messages for new camera setup etc as soon as possible
555 // This method blocks until the render thread has completed the replace.
556 mThreadController->ReplaceSurface( &newSurface );
562 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
564 // Flush the event queue to give the update-render thread chance
565 // to start processing messages for new camera setup etc as soon as possible
568 // This method blocks until the render thread has finished rendering the current surface.
569 mThreadController->DeleteSurface( &surface );
572 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
574 return *mWindows.front()->GetSurface();
577 void Adaptor::ReleaseSurfaceLock()
579 mWindows.front()->GetSurface()->ReleaseLock();
582 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
584 if( !mTtsPlayers[mode] )
586 // Create the TTS player when it needed, because it can reduce launching time.
587 mTtsPlayers[mode] = TtsPlayer::New(mode);
590 return mTtsPlayers[mode];
593 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
595 bool idleAdded(false);
597 // Only add an idle if the Adaptor is actually running
598 if( RUNNING == mState || READY == mState || forceAdd )
600 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
606 void Adaptor::RemoveIdle( CallbackBase* callback )
608 mCallbackManager->RemoveIdleCallback( callback );
611 void Adaptor::ProcessIdle()
613 bool idleProcessed = mCallbackManager->ProcessIdle();
614 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
617 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
619 mThreadController->SetPreRenderCallback( callback );
622 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
624 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
625 windowImpl.SetAdaptor( Get() );
627 // Add the new Window to the container - the order is not important
628 mWindows.push_back( &windowImpl );
630 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
632 mThreadController->AddSurface( surface );
634 mWindowCreatedSignal.Emit( childWindow );
639 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
641 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
642 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
644 if( *iter == &windowImpl )
646 mWindows.erase( iter );
654 bool Adaptor::RemoveWindow( std::string childWindowName )
656 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
658 if( ( *iter )->GetName() == childWindowName )
660 mWindows.erase( iter );
668 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
670 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
672 if( ( *iter )->GetId() == childWindow->GetId() )
674 mWindows.erase( iter );
682 Dali::Adaptor& Adaptor::Get()
684 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
685 return gThreadLocalAdaptor->mAdaptor;
688 bool Adaptor::IsAvailable()
690 return gThreadLocalAdaptor != NULL;
693 void Adaptor::SceneCreated()
695 mCore->SceneCreated();
698 Dali::Integration::Core& Adaptor::GetCore()
703 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
705 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
708 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
710 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
711 return *mDisplayConnection;
714 GraphicsInterface& Adaptor::GetGraphicsInterface()
716 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
717 return *( mGraphics.get() );
720 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
722 return *mPlatformAbstraction;
725 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
727 return *mNotificationTrigger;
730 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
732 return mSocketFactory;
735 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
737 if( !mWindows.empty() )
739 return mWindows.front()->GetSurface();
745 TraceInterface& Adaptor::GetKernelTraceInterface()
747 return mKernelTracer;
750 TraceInterface& Adaptor::GetSystemTraceInterface()
752 return mSystemTracer;
755 PerformanceInterface* Adaptor::GetPerformanceInterface()
757 return mPerformanceInterface;
760 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
762 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
763 return *mPlatformAbstraction;
766 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
771 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
773 if( mTtsPlayers[mode] )
775 mTtsPlayers[mode].Reset();
779 Any Adaptor::GetNativeWindowHandle()
781 return mWindows.front()->GetNativeHandle();
784 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
786 Any nativeWindowHandle;
788 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
790 for( auto sceneHolder : mWindows )
792 if ( scene == sceneHolder->GetScene() )
794 nativeWindowHandle = sceneHolder->GetNativeHandle();
799 return nativeWindowHandle;
802 Any Adaptor::GetGraphicsDisplay()
808 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
809 auto eglGraphics = static_cast<EglGraphics *>( graphics );
811 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
812 display = eglImpl.GetDisplay();
818 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
820 mUseRemoteSurface = useRemoteSurface;
823 void Adaptor::AddObserver( LifeCycleObserver& observer )
825 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
827 if ( match == mObservers.end() )
829 mObservers.push_back( &observer );
833 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
835 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
837 if ( match != mObservers.end() )
839 mObservers.erase( match );
843 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
847 mCore->QueueEvent(event);
851 void Adaptor::ProcessCoreEvents()
855 if( mPerformanceInterface )
857 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
860 mCore->ProcessEvents();
862 if( mPerformanceInterface )
864 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
869 void Adaptor::RequestUpdate( bool forceUpdate )
875 mThreadController->RequestUpdate();
879 case PAUSED_WHILE_HIDDEN:
883 // Update (and resource upload) without rendering
884 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
896 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
898 // Only request a notification if the Adaptor is actually running
899 // and we haven't installed the idle notification
900 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
902 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
906 void Adaptor::OnWindowShown()
908 if( PAUSED_WHILE_HIDDEN == mState )
910 // Adaptor can now be resumed
915 // Force a render task
918 else if( RUNNING == mState )
920 // Force a render task
923 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
927 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
931 void Adaptor::OnWindowHidden()
933 if( RUNNING == mState || READY == mState )
935 bool allWindowsHidden = true;
937 for( auto window : mWindows )
939 if ( window->IsVisible() )
941 allWindowsHidden = false;
946 // Only pause the adaptor when all the windows are hidden
947 if( allWindowsHidden )
949 if( mState == RUNNING )
953 // Adaptor cannot be resumed until any window is shown
954 mState = PAUSED_WHILE_HIDDEN;
956 else // mState is READY
958 // Pause the adaptor after the state gets RUNNING
959 mState = PAUSED_WHILE_INITIALIZING;
964 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
969 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
973 // Dali::Internal::Adaptor::Adaptor::OnDamaged
974 void Adaptor::OnDamaged( const DamageArea& area )
976 // This is needed for the case where Dali window is partially obscured
977 RequestUpdate( false );
980 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
982 mResizedSignal.Emit( mAdaptor );
985 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
987 // Nofify surface resizing before flushing event queue
988 mThreadController->ResizeSurface();
990 // Flush the event queue to give the update-render thread chance
991 // to start processing messages for new camera setup etc as soon as possible
995 void Adaptor::NotifySceneCreated()
997 GetCore().SceneCreated();
999 // Flush the event queue to give the update-render thread chance
1000 // to start processing messages for new camera setup etc as soon as possible
1001 ProcessCoreEvents();
1003 // Start thread controller after the scene has been created
1004 mThreadController->Start();
1006 // Process after surface is created (registering to remote surface provider if required)
1007 SurfaceInitialized();
1009 if( mState != PAUSED_WHILE_INITIALIZING )
1013 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1021 mState = PAUSED_WHILE_HIDDEN;
1023 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1027 void Adaptor::NotifyLanguageChanged()
1029 mLanguageChangedSignal.Emit( mAdaptor );
1032 void Adaptor::RenderOnce()
1034 if( mThreadController )
1036 UpdateMode updateMode;
1037 if( mThreadMode == ThreadMode::NORMAL )
1039 updateMode = UpdateMode::NORMAL;
1043 updateMode = UpdateMode::FORCE_RENDER;
1045 ProcessCoreEvents();
1047 mThreadController->RequestUpdateOnce( updateMode );
1051 const LogFactoryInterface& Adaptor::GetLogFactory()
1053 return *mEnvironmentOptions;
1056 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1058 GetCore().RegisterProcessor(processor);
1061 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1063 GetCore().UnregisterProcessor(processor);
1066 bool Adaptor::IsMultipleWindowSupported() const
1068 return mConfigurationManager->IsMultipleWindowSupported();
1071 void Adaptor::RequestUpdateOnce()
1073 if( mThreadController )
1075 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1079 bool Adaptor::ProcessCoreEventsFromIdle()
1081 ProcessCoreEvents();
1083 // the idle handle automatically un-installs itself
1084 mNotificationOnIdleInstalled = false;
1089 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1091 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1093 for( auto window : mWindows )
1095 if ( scene == window->GetScene() )
1104 Dali::WindowContainer Adaptor::GetWindows() const
1106 Dali::WindowContainer windows;
1108 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1110 // Downcast to Dali::Window
1111 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1114 windows.push_back( window );
1121 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1123 Dali::SceneHolderList sceneHolderList;
1125 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1127 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1130 return sceneHolderList;
1133 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1135 mLanguageChangedSignal(),
1136 mWindowCreatedSignal(),
1137 mAdaptor( adaptor ),
1140 mThreadController( nullptr ),
1141 mGraphics( nullptr ),
1142 mDisplayConnection( nullptr ),
1144 mConfigurationManager( nullptr ),
1145 mPlatformAbstraction( nullptr ),
1146 mCallbackManager( nullptr ),
1147 mNotificationOnIdleInstalled( false ),
1148 mNotificationTrigger( nullptr ),
1149 mDaliFeedbackPlugin(),
1150 mFeedbackController( nullptr ),
1153 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1154 mPerformanceInterface( nullptr ),
1157 mObjectProfiler( nullptr ),
1159 mThreadMode( ThreadMode::NORMAL ),
1160 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1161 mUseRemoteSurface( false )
1163 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1164 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1166 gThreadLocalAdaptor = this;
1169 void Adaptor::SetRootLayoutDirection( std::string locale )
1171 Dali::Stage stage = Dali::Stage::GetCurrent();
1173 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1174 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1177 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1179 bool idleAdded( false );
1181 // Only add an idle if the Adaptor is actually running
1182 if( RUNNING == mState || READY == mState || forceAdd )
1184 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1190 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1192 mCallbackManager->RemoveIdleEntererCallback( callback );
1195 } // namespace Adaptor
1197 } // namespace Internal