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::GetNativeWindowHandle( Dali::Actor actor )
804 Any nativeWindowHandle;
806 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
808 for( auto sceneHolder : mWindows )
810 if ( scene == sceneHolder->GetScene() )
812 nativeWindowHandle = sceneHolder->GetNativeHandle();
817 return nativeWindowHandle;
820 Any Adaptor::GetGraphicsDisplay()
826 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
828 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
829 display = eglImpl.GetDisplay();
835 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
837 mUseRemoteSurface = useRemoteSurface;
840 void Adaptor::AddObserver( LifeCycleObserver& observer )
842 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
844 if ( match == mObservers.end() )
846 mObservers.push_back( &observer );
850 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
852 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
854 if ( match != mObservers.end() )
856 mObservers.erase( match );
860 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
864 mCore->QueueEvent(event);
868 void Adaptor::ProcessCoreEvents()
872 if( mPerformanceInterface )
874 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
877 mCore->ProcessEvents();
879 if( mPerformanceInterface )
881 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
886 void Adaptor::RequestUpdate( bool forceUpdate )
892 mThreadController->RequestUpdate();
896 case PAUSED_WHILE_HIDDEN:
898 // When Dali applications are partially visible behind the lock-screen,
899 // the indicator must be updated (therefore allow updates in the PAUSED state)
902 mThreadController->RequestUpdateOnce();
914 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
916 // Only request a notification if the Adaptor is actually running
917 // and we haven't installed the idle notification
918 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
920 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
924 void Adaptor::OnWindowShown()
926 if( PAUSED_WHILE_HIDDEN == mState )
928 // Adaptor can now be resumed
933 // Force a render task
936 else if( RUNNING == mState )
938 // Force a render task
941 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
945 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
949 void Adaptor::OnWindowHidden()
951 if( RUNNING == mState || READY == mState )
953 bool allWindowsHidden = true;
955 for( auto window : mWindows )
957 if ( window->IsVisible() )
959 allWindowsHidden = false;
964 // Only pause the adaptor when all the windows are hidden
965 if( allWindowsHidden )
967 if( mState == RUNNING )
971 // Adaptor cannot be resumed until any window is shown
972 mState = PAUSED_WHILE_HIDDEN;
974 else // mState is READY
976 // Pause the adaptor after the state gets RUNNING
977 mState = PAUSED_WHILE_INITIALIZING;
982 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
987 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
991 // Dali::Internal::Adaptor::Adaptor::OnDamaged
992 void Adaptor::OnDamaged( const DamageArea& area )
994 // This is needed for the case where Dali window is partially obscured
995 RequestUpdate( false );
998 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1000 mResizedSignal.Emit( mAdaptor );
1003 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1005 // Flush the event queue to give the update-render thread chance
1006 // to start processing messages for new camera setup etc as soon as possible
1007 ProcessCoreEvents();
1009 mThreadController->ResizeSurface();
1012 void Adaptor::NotifySceneCreated()
1014 GetCore().SceneCreated();
1016 // Flush the event queue to give the update-render thread chance
1017 // to start processing messages for new camera setup etc as soon as possible
1018 ProcessCoreEvents();
1020 // Start thread controller after the scene has been created
1021 mThreadController->Start();
1023 // Process after surface is created (registering to remote surface provider if required)
1024 SurfaceInitialized();
1026 if( mState != PAUSED_WHILE_INITIALIZING )
1030 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1038 mState = PAUSED_WHILE_HIDDEN;
1040 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1044 void Adaptor::NotifyLanguageChanged()
1046 mLanguageChangedSignal.Emit( mAdaptor );
1049 void Adaptor::RenderOnce()
1051 RequestUpdateOnce();
1054 const LogFactoryInterface& Adaptor::GetLogFactory()
1056 return *mEnvironmentOptions;
1059 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1061 GetCore().RegisterProcessor(processor);
1064 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1066 GetCore().UnregisterProcessor(processor);
1069 void Adaptor::RequestUpdateOnce()
1071 if( mThreadController )
1073 mThreadController->RequestUpdateOnce();
1077 bool Adaptor::ProcessCoreEventsFromIdle()
1079 ProcessCoreEvents();
1081 // the idle handle automatically un-installs itself
1082 mNotificationOnIdleInstalled = false;
1087 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1089 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1091 for( auto window : mWindows )
1093 if ( scene == window->GetScene() )
1102 Dali::WindowContainer Adaptor::GetWindows() const
1104 Dali::WindowContainer windows;
1106 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1108 // Downcast to Dali::Window
1109 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1112 windows.push_back( window );
1119 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1121 mLanguageChangedSignal(),
1122 mWindowCreatedSignal(),
1123 mAdaptor( adaptor ),
1126 mThreadController( nullptr ),
1127 mGraphics( nullptr ),
1128 mDisplayConnection( nullptr ),
1130 mPlatformAbstraction( nullptr ),
1131 mCallbackManager( nullptr ),
1132 mNotificationOnIdleInstalled( false ),
1133 mNotificationTrigger( nullptr ),
1134 mDaliFeedbackPlugin(),
1135 mFeedbackController( nullptr ),
1138 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1139 mPerformanceInterface( nullptr ),
1142 mTriggerEventFactory(),
1143 mObjectProfiler( nullptr ),
1145 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1146 mUseRemoteSurface( false )
1148 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1149 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1151 gThreadLocalAdaptor = this;
1154 void Adaptor::SetRootLayoutDirection( std::string locale )
1156 Dali::Stage stage = Dali::Stage::GetCurrent();
1158 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1159 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1162 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1164 bool idleAdded( false );
1166 // Only add an idle if the Adaptor is actually running
1167 if( RUNNING == mState || READY == mState || forceAdd )
1169 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1175 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1177 mCallbackManager->RemoveIdleEntererCallback( callback );
1180 } // namespace Adaptor
1182 } // namespace Internal