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() );
189 defaultWindow->SetAdaptor( Get() );
191 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( defaultWindow ) );
194 mWindowCreatedSignal.Emit( window );
197 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
198 if( 0u < timeInterval )
200 mObjectProfiler = new ObjectProfiler( timeInterval );
203 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
205 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
207 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
209 // Should be called after Core creation
210 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
212 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
214 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
216 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
218 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
220 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
222 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
224 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
226 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
228 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
230 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
232 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
234 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
236 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
238 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
240 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
242 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
244 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
246 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
248 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
250 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
252 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
254 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
256 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
258 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
260 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
262 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
264 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
266 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
268 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
270 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
272 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
274 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
276 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
278 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
280 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
282 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
284 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
287 // Set max texture size
288 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
290 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
293 std::string systemCachePath = GetSystemCachePath();
294 if ( systemCachePath.c_str() != NULL )
296 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
297 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
298 if( stream.is_open() )
301 while( std::getline( stream, line ) )
303 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
304 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
305 if( '#' == *( line.cbegin() ) || line == "" )
310 std::istringstream stream( line );
311 std::string environmentVariableName, environmentVariableValue;
312 std::getline(stream, environmentVariableName, ' ');
313 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
315 std::getline(stream, environmentVariableValue);
316 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
317 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
323 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
330 // Ensure stop status
333 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
334 gThreadLocalAdaptor = NULL;
336 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
338 (*iter)->OnDestroy();
341 // Clear out all the handles to Windows
344 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
345 delete mObjectProfiler;
349 delete mDisplayConnection;
350 delete mPlatformAbstraction;
351 delete mCallbackManager;
352 delete mPerformanceInterface;
354 mGraphics->Destroy();
356 // uninstall it on this thread (main actor thread)
357 Dali::Integration::Log::UninstallLogFunction();
359 // Delete environment options if we own it
360 if( mEnvironmentOptionsOwned )
362 delete mEnvironmentOptions;
366 void Adaptor::Start()
368 // It doesn't support restart after stop at this moment to support restarting, need more testing
369 if( READY != mState )
376 SetupSystemInformation();
378 // Start the callback manager
379 mCallbackManager->Start();
381 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
383 unsigned int dpiHor, dpiVer;
386 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
388 // set the DPI value for font rendering
389 FontClient fontClient = FontClient::Get();
390 fontClient.SetDpi( dpiHor, dpiVer );
392 // Initialize the thread controller
393 mThreadController->Initialize();
395 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
397 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
398 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
399 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
401 std::string systemCachePath = GetSystemCachePath();
402 if( systemCachePath.c_str() != NULL )
404 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
407 printf("Error creating directory!n");
411 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
412 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
413 if( configFile.is_open() )
415 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
420 ProcessCoreEvents(); // Ensure any startup messages are processed.
422 // Initialize the image loader plugin
423 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
425 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
431 // Dali::Internal::Adaptor::Adaptor::Pause
432 void Adaptor::Pause()
434 // Only pause the adaptor if we're actually running.
435 if( RUNNING == mState )
437 // Inform observers that we are about to be paused.
438 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
443 // Pause all windows event handlers when adaptor paused
444 for( auto window : mWindows )
449 mThreadController->Pause();
452 // Ensure any messages queued during pause callbacks are processed by doing another update.
455 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
459 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
463 // Dali::Internal::Adaptor::Adaptor::Resume
464 void Adaptor::Resume()
466 // Only resume the adaptor if we are in the suspended state.
467 if( PAUSED == mState )
471 // Reset the event handlers when adaptor resumed
472 for( auto window : mWindows )
477 // Inform observers that we have resumed.
478 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
483 // Trigger processing of events queued up while paused
484 mCore->ProcessEvents();
486 // Do at end to ensure our first update/render after resumption includes the processed messages as well
487 mThreadController->Resume();
489 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
493 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
499 if( RUNNING == mState ||
501 PAUSED_WHILE_HIDDEN == mState )
503 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
508 mThreadController->Stop();
510 // Delete the TTS player
511 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
515 mTtsPlayers[i].Reset();
519 // Destroy the image loader plugin
520 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
522 delete mNotificationTrigger;
523 mNotificationTrigger = NULL;
525 mCallbackManager->Stop();
529 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
533 void Adaptor::ContextLost()
535 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
538 void Adaptor::ContextRegained()
540 // Inform core, so that texture resources can be reloaded
541 mCore->RecoverFromContextLoss();
543 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
546 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
548 Integration::Point convertedPoint( point );
549 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
552 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
554 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
555 mWindows.front()->FeedWheelEvent( event );
558 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
560 Integration::KeyEvent convertedEvent( keyEvent );
561 mWindows.front()->FeedKeyEvent( convertedEvent );
564 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
566 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
567 for( auto windowPtr : mWindows )
569 if( windowPtr == windowImpl ) // the window is not deleted
571 mResizedSignal.Emit( mAdaptor );
573 windowImpl->SetSurface( &newSurface );
575 // Flush the event queue to give the update-render thread chance
576 // to start processing messages for new camera setup etc as soon as possible
579 // This method blocks until the render thread has completed the replace.
580 mThreadController->ReplaceSurface( &newSurface );
586 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
588 // Flush the event queue to give the update-render thread chance
589 // to start processing messages for new camera setup etc as soon as possible
592 // This method blocks until the render thread has finished rendering the current surface.
593 mThreadController->DeleteSurface( &surface );
596 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
598 return *mWindows.front()->GetSurface();
601 void Adaptor::ReleaseSurfaceLock()
603 mWindows.front()->GetSurface()->ReleaseLock();
606 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
608 if( !mTtsPlayers[mode] )
610 // Create the TTS player when it needed, because it can reduce launching time.
611 mTtsPlayers[mode] = TtsPlayer::New(mode);
614 return mTtsPlayers[mode];
617 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
619 bool idleAdded(false);
621 // Only add an idle if the Adaptor is actually running
622 if( RUNNING == mState || READY == mState || forceAdd )
624 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
630 void Adaptor::RemoveIdle( CallbackBase* callback )
632 mCallbackManager->RemoveIdleCallback( callback );
635 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
637 mThreadController->SetPreRenderCallback( callback );
640 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
642 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
643 windowImpl.SetAdaptor( Get() );
645 // Add the new Window to the container - the order is not important
646 mWindows.push_back( &windowImpl );
648 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
651 mWindowCreatedSignal.Emit( window );
657 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
659 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
660 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
662 if( *iter == &windowImpl )
664 mWindows.erase( iter );
672 bool Adaptor::RemoveWindow( std::string childWindowName )
674 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
676 if( ( *iter )->GetName() == childWindowName )
678 mWindows.erase( iter );
686 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
688 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
690 if( ( *iter )->GetId() == childWindow->GetId() )
692 mWindows.erase( iter );
700 Dali::Adaptor& Adaptor::Get()
702 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
703 return gThreadLocalAdaptor->mAdaptor;
706 bool Adaptor::IsAvailable()
708 return gThreadLocalAdaptor != NULL;
711 void Adaptor::SceneCreated()
713 mCore->SceneCreated();
716 Dali::Integration::Core& Adaptor::GetCore()
721 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
723 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
726 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
728 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
729 return *mDisplayConnection;
732 GraphicsInterface& Adaptor::GetGraphicsInterface()
734 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
738 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
740 return *mPlatformAbstraction;
743 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
745 return *mNotificationTrigger;
748 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
750 return mTriggerEventFactory;
753 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
755 return mSocketFactory;
758 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
760 if( !mWindows.empty() )
762 return mWindows.front()->GetSurface();
768 TraceInterface& Adaptor::GetKernelTraceInterface()
770 return mKernelTracer;
773 TraceInterface& Adaptor::GetSystemTraceInterface()
775 return mSystemTracer;
778 PerformanceInterface* Adaptor::GetPerformanceInterface()
780 return mPerformanceInterface;
783 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
785 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
786 return *mPlatformAbstraction;
789 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
791 if( mTtsPlayers[mode] )
793 mTtsPlayers[mode].Reset();
797 Any Adaptor::GetNativeWindowHandle()
799 return mWindows.front()->GetNativeHandle();
802 Any Adaptor::GetGraphicsDisplay()
808 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
810 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
811 display = eglImpl.GetDisplay();
817 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
819 mUseRemoteSurface = useRemoteSurface;
822 void Adaptor::AddObserver( LifeCycleObserver& observer )
824 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
826 if ( match == mObservers.end() )
828 mObservers.push_back( &observer );
832 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
834 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
836 if ( match != mObservers.end() )
838 mObservers.erase( match );
842 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
846 mCore->QueueEvent(event);
850 void Adaptor::ProcessCoreEvents()
854 if( mPerformanceInterface )
856 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
859 mCore->ProcessEvents();
861 if( mPerformanceInterface )
863 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
868 void Adaptor::RequestUpdate( bool forceUpdate )
874 mThreadController->RequestUpdate();
878 case PAUSED_WHILE_HIDDEN:
880 // When Dali applications are partially visible behind the lock-screen,
881 // the indicator must be updated (therefore allow updates in the PAUSED state)
884 mThreadController->RequestUpdateOnce();
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 // Flush the event queue to give the update-render thread chance
988 // to start processing messages for new camera setup etc as soon as possible
991 mThreadController->ResizeSurface();
994 void Adaptor::NotifySceneCreated()
996 GetCore().SceneCreated();
998 // Flush the event queue to give the update-render thread chance
999 // to start processing messages for new camera setup etc as soon as possible
1000 ProcessCoreEvents();
1002 // Start thread controller after the scene has been created
1003 mThreadController->Start();
1005 // Process after surface is created (registering to remote surface provider if required)
1006 SurfaceInitialized();
1008 if( mState != PAUSED_WHILE_INITIALIZING )
1012 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1020 mState = PAUSED_WHILE_HIDDEN;
1022 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1026 void Adaptor::NotifyLanguageChanged()
1028 mLanguageChangedSignal.Emit( mAdaptor );
1031 void Adaptor::RenderOnce()
1033 RequestUpdateOnce();
1036 const LogFactoryInterface& Adaptor::GetLogFactory()
1038 return *mEnvironmentOptions;
1041 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1043 GetCore().RegisterProcessor(processor);
1046 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1048 GetCore().UnregisterProcessor(processor);
1051 void Adaptor::RequestUpdateOnce()
1053 if( mThreadController )
1055 mThreadController->RequestUpdateOnce();
1059 bool Adaptor::ProcessCoreEventsFromIdle()
1061 ProcessCoreEvents();
1063 // the idle handle automatically un-installs itself
1064 mNotificationOnIdleInstalled = false;
1069 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1071 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1073 for( auto window : mWindows )
1075 if ( scene == window->GetScene() )
1084 Dali::WindowContainer Adaptor::GetWindows() const
1086 Dali::WindowContainer windows;
1088 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1090 // Downcast to Dali::Window
1091 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1094 windows.push_back( window );
1101 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1103 mLanguageChangedSignal(),
1104 mWindowCreatedSignal(),
1105 mAdaptor( adaptor ),
1108 mThreadController( nullptr ),
1109 mGraphics( nullptr ),
1110 mDisplayConnection( nullptr ),
1112 mPlatformAbstraction( nullptr ),
1113 mCallbackManager( nullptr ),
1114 mNotificationOnIdleInstalled( false ),
1115 mNotificationTrigger( nullptr ),
1116 mDaliFeedbackPlugin(),
1117 mFeedbackController( nullptr ),
1120 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1121 mPerformanceInterface( nullptr ),
1124 mTriggerEventFactory(),
1125 mObjectProfiler( nullptr ),
1127 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1128 mUseRemoteSurface( false )
1130 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1131 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1133 gThreadLocalAdaptor = this;
1136 void Adaptor::SetRootLayoutDirection( std::string locale )
1138 Dali::Stage stage = Dali::Stage::GetCurrent();
1140 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1141 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1144 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1146 bool idleAdded( false );
1148 // Only add an idle if the Adaptor is actually running
1149 if( RUNNING == mState || READY == mState || forceAdd )
1151 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1157 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1159 mCallbackManager->RemoveIdleEntererCallback( callback );
1162 } // namespace Adaptor
1164 } // namespace Internal