2 * Copyright (c) 2019 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>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/key-event-integ.h>
33 #include <dali/integration-api/events/touch-event-integ.h>
34 #include <dali/integration-api/events/wheel-event-integ.h>
35 #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>
45 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
46 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
48 #include <dali/devel-api/text-abstraction/font-client.h>
50 #include <dali/internal/system/common/callback-manager.h>
51 #include <dali/internal/accessibility/common/tts-player-impl.h>
52 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
53 #include <dali/internal/window-system/common/event-handler.h>
54 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
55 #include <dali/internal/graphics/gles/gl-implementation.h>
56 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
57 #include <dali/internal/graphics/common/egl-image-extensions.h>
58 #include <dali/internal/clipboard/common/clipboard-impl.h>
59 #include <dali/internal/system/common/object-profiler.h>
60 #include <dali/internal/window-system/common/display-connection.h>
61 #include <dali/internal/window-system/common/window-impl.h>
62 #include <dali/internal/window-system/common/window-render-surface.h>
64 #include <dali/internal/system/common/logging.h>
66 #include <dali/internal/system/common/locale-utils.h>
67 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
68 #include <dali/internal/imaging/common/image-loader.h>
70 #include <dali/devel-api/adaptor-framework/file-stream.h>
72 using Dali::TextAbstraction::FontClient;
74 extern std::string GetSystemCachePath();
87 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
88 } // unnamed namespace
90 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
92 Dali::Adaptor* adaptor = new Dali::Adaptor;
93 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
94 adaptor->mImpl = impl;
96 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
97 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
99 impl->Initialize( graphicsFactory, configuration );
100 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
105 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
107 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
108 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
109 windowImpl.SetAdaptor( *adaptor );
113 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
115 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
116 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
117 adaptor->mImpl = impl;
119 impl->Initialize( graphicsFactory, configuration );
124 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
126 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
127 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
128 windowImpl.SetAdaptor( *adaptor );
132 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
134 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
135 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
136 mEnvironmentOptions->SetLogFunction( logFunction );
137 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
139 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
142 GetDataStoragePath( path );
143 mPlatformAbstraction->SetDataStoragePath( path );
145 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
146 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
148 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
151 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
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 = &( graphicsFactory.Create() );
168 mGraphics->Initialize( mEnvironmentOptions );
170 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
172 // This will only be created once
173 eglGraphics->Create();
175 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
176 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
177 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
179 mCore = Integration::Core::New( *this,
180 *mPlatformAbstraction,
183 eglContextHelperImpl,
184 dataRetentionPolicy ,
185 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
186 mGraphics->GetDepthBufferRequired(),
187 mGraphics->GetStencilBufferRequired(),
188 mGraphics->PartialUpdateAvailable() );
190 defaultWindow->SetAdaptor( Get() );
192 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
194 mWindowCreatedSignal.Emit( defaultSceneHolder );
196 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
197 if( 0u < timeInterval )
199 mObjectProfiler = new ObjectProfiler( timeInterval );
202 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
204 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
206 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
208 // Should be called after Core creation
209 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
211 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
213 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
215 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
217 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
219 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
221 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
223 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
225 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
227 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
229 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
231 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
233 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
235 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
237 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
239 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
241 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
243 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
245 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
247 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
249 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
251 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
253 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
255 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
257 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
259 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
261 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
263 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
265 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
267 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
269 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
271 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
273 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
275 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
277 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
279 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
281 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
283 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
286 // Set max texture size
287 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
289 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
292 std::string systemCachePath = GetSystemCachePath();
293 if ( ! systemCachePath.empty() )
295 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
296 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
297 if( stream.is_open() )
300 while( std::getline( stream, line ) )
302 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
303 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
304 if( '#' == *( line.cbegin() ) || line == "" )
309 std::istringstream stream( line );
310 std::string environmentVariableName, environmentVariableValue;
311 std::getline(stream, environmentVariableName, ' ');
312 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
314 std::getline(stream, environmentVariableValue);
315 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
316 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
322 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
329 // Ensure stop status
332 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
333 gThreadLocalAdaptor = NULL;
335 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
337 (*iter)->OnDestroy();
340 // Clear out all the handles to Windows
343 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
344 delete mObjectProfiler;
348 delete mDisplayConnection;
349 delete mPlatformAbstraction;
350 delete mCallbackManager;
351 delete mPerformanceInterface;
353 mGraphics->Destroy();
355 // uninstall it on this thread (main actor thread)
356 Dali::Integration::Log::UninstallLogFunction();
358 // Delete environment options if we own it
359 if( mEnvironmentOptionsOwned )
361 delete mEnvironmentOptions;
365 void Adaptor::Start()
367 // It doesn't support restart after stop at this moment to support restarting, need more testing
368 if( READY != mState )
375 SetupSystemInformation();
377 // Start the callback manager
378 mCallbackManager->Start();
380 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
382 unsigned int dpiHor, dpiVer;
385 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
387 // set the DPI value for font rendering
388 FontClient fontClient = FontClient::Get();
389 fontClient.SetDpi( dpiHor, dpiVer );
391 // Initialize the thread controller
392 mThreadController->Initialize();
394 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
396 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
397 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
398 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
400 std::string systemCachePath = GetSystemCachePath();
401 if( systemCachePath.c_str() != NULL )
403 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
406 printf("Error creating directory!n");
410 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
411 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
412 if( configFile.is_open() )
414 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
419 ProcessCoreEvents(); // Ensure any startup messages are processed.
421 // Initialize the image loader plugin
422 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
424 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
430 // Dali::Internal::Adaptor::Adaptor::Pause
431 void Adaptor::Pause()
433 // Only pause the adaptor if we're actually running.
434 if( RUNNING == mState )
436 // Inform observers that we are about to be paused.
437 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
442 // Pause all windows event handlers when adaptor paused
443 for( auto window : mWindows )
448 mThreadController->Pause();
451 // Ensure any messages queued during pause callbacks are processed by doing another update.
454 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
458 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
462 // Dali::Internal::Adaptor::Adaptor::Resume
463 void Adaptor::Resume()
465 // Only resume the adaptor if we are in the suspended state.
466 if( PAUSED == mState )
470 // Reset the event handlers when adaptor resumed
471 for( auto window : mWindows )
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 )
507 mThreadController->Stop();
509 // Delete the TTS player
510 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
514 mTtsPlayers[i].Reset();
518 // Destroy the image loader plugin
519 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
521 delete mNotificationTrigger;
522 mNotificationTrigger = NULL;
524 mCallbackManager->Stop();
528 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
532 void Adaptor::ContextLost()
534 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
537 void Adaptor::ContextRegained()
539 // Inform core, so that texture resources can be reloaded
540 mCore->RecoverFromContextLoss();
542 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
545 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
547 Integration::Point convertedPoint( point );
548 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
551 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
553 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
554 mWindows.front()->FeedWheelEvent( event );
557 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
559 Integration::KeyEvent convertedEvent( keyEvent );
560 mWindows.front()->FeedKeyEvent( convertedEvent );
563 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
565 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
566 for( auto windowPtr : mWindows )
568 if( windowPtr == windowImpl ) // the window is not deleted
570 mResizedSignal.Emit( mAdaptor );
572 windowImpl->SetSurface( &newSurface );
574 // Flush the event queue to give the update-render thread chance
575 // to start processing messages for new camera setup etc as soon as possible
578 // This method blocks until the render thread has completed the replace.
579 mThreadController->ReplaceSurface( &newSurface );
585 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
587 // Flush the event queue to give the update-render thread chance
588 // to start processing messages for new camera setup etc as soon as possible
591 // This method blocks until the render thread has finished rendering the current surface.
592 mThreadController->DeleteSurface( &surface );
595 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
597 return *mWindows.front()->GetSurface();
600 void Adaptor::ReleaseSurfaceLock()
602 mWindows.front()->GetSurface()->ReleaseLock();
605 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
607 if( !mTtsPlayers[mode] )
609 // Create the TTS player when it needed, because it can reduce launching time.
610 mTtsPlayers[mode] = TtsPlayer::New(mode);
613 return mTtsPlayers[mode];
616 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
618 bool idleAdded(false);
620 // Only add an idle if the Adaptor is actually running
621 if( RUNNING == mState || READY == mState || forceAdd )
623 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
629 void Adaptor::RemoveIdle( CallbackBase* callback )
631 mCallbackManager->RemoveIdleCallback( callback );
634 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
636 mThreadController->SetPreRenderCallback( callback );
639 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
641 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
642 windowImpl.SetAdaptor( Get() );
644 // Add the new Window to the container - the order is not important
645 mWindows.push_back( &windowImpl );
647 mWindowCreatedSignal.Emit( childWindow );
652 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
654 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
655 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
657 if( *iter == &windowImpl )
659 mWindows.erase( iter );
667 bool Adaptor::RemoveWindow( std::string childWindowName )
669 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
671 if( ( *iter )->GetName() == childWindowName )
673 mWindows.erase( iter );
681 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
683 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
685 if( ( *iter )->GetId() == childWindow->GetId() )
687 mWindows.erase( iter );
695 Dali::Adaptor& Adaptor::Get()
697 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
698 return gThreadLocalAdaptor->mAdaptor;
701 bool Adaptor::IsAvailable()
703 return gThreadLocalAdaptor != NULL;
706 void Adaptor::SceneCreated()
708 mCore->SceneCreated();
711 Dali::Integration::Core& Adaptor::GetCore()
716 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
718 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
721 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
723 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
724 return *mDisplayConnection;
727 GraphicsInterface& Adaptor::GetGraphicsInterface()
729 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
733 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
735 return *mPlatformAbstraction;
738 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
740 return *mNotificationTrigger;
743 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
745 return mTriggerEventFactory;
748 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
750 return mSocketFactory;
753 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
755 if( !mWindows.empty() )
757 return mWindows.front()->GetSurface();
763 TraceInterface& Adaptor::GetKernelTraceInterface()
765 return mKernelTracer;
768 TraceInterface& Adaptor::GetSystemTraceInterface()
770 return mSystemTracer;
773 PerformanceInterface* Adaptor::GetPerformanceInterface()
775 return mPerformanceInterface;
778 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
780 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
781 return *mPlatformAbstraction;
784 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
786 if( mTtsPlayers[mode] )
788 mTtsPlayers[mode].Reset();
792 Any Adaptor::GetNativeWindowHandle()
794 return mWindows.front()->GetNativeHandle();
797 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
799 Any nativeWindowHandle;
801 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
803 for( auto sceneHolder : mWindows )
805 if ( scene == sceneHolder->GetScene() )
807 nativeWindowHandle = sceneHolder->GetNativeHandle();
812 return nativeWindowHandle;
815 Any Adaptor::GetGraphicsDisplay()
821 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
823 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
824 display = eglImpl.GetDisplay();
830 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
832 mUseRemoteSurface = useRemoteSurface;
835 void Adaptor::AddObserver( LifeCycleObserver& observer )
837 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
839 if ( match == mObservers.end() )
841 mObservers.push_back( &observer );
845 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
847 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
849 if ( match != mObservers.end() )
851 mObservers.erase( match );
855 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
859 mCore->QueueEvent(event);
863 void Adaptor::ProcessCoreEvents()
867 if( mPerformanceInterface )
869 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
872 mCore->ProcessEvents();
874 if( mPerformanceInterface )
876 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
881 void Adaptor::RequestUpdate( bool forceUpdate )
887 mThreadController->RequestUpdate();
891 case PAUSED_WHILE_HIDDEN:
893 // When Dali applications are partially visible behind the lock-screen,
894 // the indicator must be updated (therefore allow updates in the PAUSED state)
897 mThreadController->RequestUpdateOnce();
909 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
911 // Only request a notification if the Adaptor is actually running
912 // and we haven't installed the idle notification
913 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
915 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
919 void Adaptor::OnWindowShown()
921 if( PAUSED_WHILE_HIDDEN == mState )
923 // Adaptor can now be resumed
928 // Force a render task
931 else if( RUNNING == mState )
933 // Force a render task
936 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
940 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
944 void Adaptor::OnWindowHidden()
946 if( RUNNING == mState || READY == mState )
948 bool allWindowsHidden = true;
950 for( auto window : mWindows )
952 if ( window->IsVisible() )
954 allWindowsHidden = false;
959 // Only pause the adaptor when all the windows are hidden
960 if( allWindowsHidden )
962 if( mState == RUNNING )
966 // Adaptor cannot be resumed until any window is shown
967 mState = PAUSED_WHILE_HIDDEN;
969 else // mState is READY
971 // Pause the adaptor after the state gets RUNNING
972 mState = PAUSED_WHILE_INITIALIZING;
977 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
982 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
986 // Dali::Internal::Adaptor::Adaptor::OnDamaged
987 void Adaptor::OnDamaged( const DamageArea& area )
989 // This is needed for the case where Dali window is partially obscured
990 RequestUpdate( false );
993 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
995 mResizedSignal.Emit( mAdaptor );
998 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1000 // Flush the event queue to give the update-render thread chance
1001 // to start processing messages for new camera setup etc as soon as possible
1002 ProcessCoreEvents();
1004 mThreadController->ResizeSurface();
1007 void Adaptor::NotifySceneCreated()
1009 GetCore().SceneCreated();
1011 // Flush the event queue to give the update-render thread chance
1012 // to start processing messages for new camera setup etc as soon as possible
1013 ProcessCoreEvents();
1015 // Start thread controller after the scene has been created
1016 mThreadController->Start();
1018 // Process after surface is created (registering to remote surface provider if required)
1019 SurfaceInitialized();
1021 if( mState != PAUSED_WHILE_INITIALIZING )
1025 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1033 mState = PAUSED_WHILE_HIDDEN;
1035 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1039 void Adaptor::NotifyLanguageChanged()
1041 mLanguageChangedSignal.Emit( mAdaptor );
1044 void Adaptor::RenderOnce()
1046 RequestUpdateOnce();
1049 const LogFactoryInterface& Adaptor::GetLogFactory()
1051 return *mEnvironmentOptions;
1054 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1056 GetCore().RegisterProcessor(processor);
1059 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1061 GetCore().UnregisterProcessor(processor);
1064 void Adaptor::RequestUpdateOnce()
1066 if( mThreadController )
1068 mThreadController->RequestUpdateOnce();
1072 bool Adaptor::ProcessCoreEventsFromIdle()
1074 ProcessCoreEvents();
1076 // the idle handle automatically un-installs itself
1077 mNotificationOnIdleInstalled = false;
1082 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1084 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1086 for( auto window : mWindows )
1088 if ( scene == window->GetScene() )
1097 Dali::WindowContainer Adaptor::GetWindows() const
1099 Dali::WindowContainer windows;
1101 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1103 // Downcast to Dali::Window
1104 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1107 windows.push_back( window );
1114 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1116 Dali::SceneHolderList sceneHolderList;
1118 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1120 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1123 return sceneHolderList;
1126 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1128 mLanguageChangedSignal(),
1129 mWindowCreatedSignal(),
1130 mAdaptor( adaptor ),
1133 mThreadController( nullptr ),
1134 mGraphics( nullptr ),
1135 mDisplayConnection( nullptr ),
1137 mPlatformAbstraction( nullptr ),
1138 mCallbackManager( nullptr ),
1139 mNotificationOnIdleInstalled( false ),
1140 mNotificationTrigger( nullptr ),
1141 mDaliFeedbackPlugin(),
1142 mFeedbackController( nullptr ),
1145 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1146 mPerformanceInterface( nullptr ),
1149 mTriggerEventFactory(),
1150 mObjectProfiler( nullptr ),
1152 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1153 mUseRemoteSurface( false )
1155 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1156 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1158 gThreadLocalAdaptor = this;
1161 void Adaptor::SetRootLayoutDirection( std::string locale )
1163 Dali::Stage stage = Dali::Stage::GetCurrent();
1165 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1166 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1169 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1171 bool idleAdded( false );
1173 // Only add an idle if the Adaptor is actually running
1174 if( RUNNING == mState || READY == mState || forceAdd )
1176 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1182 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1184 mCallbackManager->RemoveIdleEntererCallback( callback );
1187 } // namespace Adaptor
1189 } // namespace Internal