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/window-system/common/event-handler.h>
53 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
54 #include <dali/internal/graphics/gles/gl-implementation.h>
55 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
56 #include <dali/internal/graphics/common/egl-image-extensions.h>
57 #include <dali/internal/clipboard/common/clipboard-impl.h>
58 #include <dali/internal/system/common/object-profiler.h>
59 #include <dali/internal/window-system/common/display-connection.h>
60 #include <dali/internal/window-system/common/window-impl.h>
61 #include <dali/internal/window-system/common/window-render-surface.h>
63 #include <dali/devel-api/adaptor-framework/accessibility.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() );
325 auto appName = GetApplicationPackageName();
326 auto bridge = Accessibility::Bridge::GetCurrentBridge();
327 bridge->SetApplicationName( appName );
328 bridge->Initialize();
329 Dali::Stage stage = Dali::Stage::GetCurrent();
330 Dali::Stage::GetCurrent().KeyEventSignal().Connect( &accessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent );
333 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent( const KeyEvent& event )
335 Accessibility::KeyEventType type;
336 if( event.state == KeyEvent::Down )
338 type = Accessibility::KeyEventType::KEY_PRESSED;
340 else if( event.state == KeyEvent::Up )
342 type = Accessibility::KeyEventType::KEY_RELEASED;
348 Dali::Accessibility::Bridge::GetCurrentBridge()->Emit( type, event.keyCode, event.keyPressedName, event.time, !event.keyPressed.empty() );
353 Accessibility::Bridge::GetCurrentBridge()->Terminate();
355 // Ensure stop status
358 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
359 gThreadLocalAdaptor = NULL;
361 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
363 (*iter)->OnDestroy();
366 // Clear out all the handles to Windows
369 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
370 delete mObjectProfiler;
374 delete mDisplayConnection;
375 delete mPlatformAbstraction;
376 delete mCallbackManager;
377 delete mPerformanceInterface;
379 mGraphics->Destroy();
381 // uninstall it on this thread (main actor thread)
382 Dali::Integration::Log::UninstallLogFunction();
384 // Delete environment options if we own it
385 if( mEnvironmentOptionsOwned )
387 delete mEnvironmentOptions;
391 void Adaptor::Start()
393 // It doesn't support restart after stop at this moment to support restarting, need more testing
394 if( READY != mState )
401 SetupSystemInformation();
403 // Start the callback manager
404 mCallbackManager->Start();
406 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
408 unsigned int dpiHor, dpiVer;
411 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
413 // set the DPI value for font rendering
414 FontClient fontClient = FontClient::Get();
415 fontClient.SetDpi( dpiHor, dpiVer );
417 // Initialize the thread controller
418 mThreadController->Initialize();
420 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
422 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
423 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
424 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
426 std::string systemCachePath = GetSystemCachePath();
427 if( ! systemCachePath.empty() )
429 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
432 printf("Error creating directory!n");
436 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
437 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
438 if( configFile.is_open() )
440 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
445 ProcessCoreEvents(); // Ensure any startup messages are processed.
447 // Initialize the image loader plugin
448 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
450 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
456 // Dali::Internal::Adaptor::Adaptor::Pause
457 void Adaptor::Pause()
459 // Only pause the adaptor if we're actually running.
460 if( RUNNING == mState )
462 // Inform observers that we are about to be paused.
463 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
468 // Pause all windows event handlers when adaptor paused
469 for( auto window : mWindows )
474 mThreadController->Pause();
477 // Ensure any messages queued during pause callbacks are processed by doing another update.
480 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
484 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
488 // Dali::Internal::Adaptor::Adaptor::Resume
489 void Adaptor::Resume()
491 // Only resume the adaptor if we are in the suspended state.
492 if( PAUSED == mState )
496 // Reset the event handlers when adaptor resumed
497 for( auto window : mWindows )
502 // Inform observers that we have resumed.
503 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
508 // Trigger processing of events queued up while paused
509 mCore->ProcessEvents();
511 // Do at end to ensure our first update/render after resumption includes the processed messages as well
512 mThreadController->Resume();
514 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
518 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
524 if( RUNNING == mState ||
526 PAUSED_WHILE_HIDDEN == mState )
528 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
533 mThreadController->Stop();
535 // Delete the TTS player
536 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
540 mTtsPlayers[i].Reset();
544 // Destroy the image loader plugin
545 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
547 delete mNotificationTrigger;
548 mNotificationTrigger = NULL;
550 mCallbackManager->Stop();
554 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
558 void Adaptor::ContextLost()
560 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
563 void Adaptor::ContextRegained()
565 // Inform core, so that texture resources can be reloaded
566 mCore->RecoverFromContextLoss();
568 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
571 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
573 Integration::Point convertedPoint( point );
574 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
577 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
579 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
580 mWindows.front()->FeedWheelEvent( event );
583 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
585 Integration::KeyEvent convertedEvent( keyEvent );
586 mWindows.front()->FeedKeyEvent( convertedEvent );
589 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
591 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
592 for( auto windowPtr : mWindows )
594 if( windowPtr == windowImpl ) // the window is not deleted
596 mResizedSignal.Emit( mAdaptor );
598 windowImpl->SetSurface( &newSurface );
600 // Flush the event queue to give the update-render thread chance
601 // to start processing messages for new camera setup etc as soon as possible
604 // This method blocks until the render thread has completed the replace.
605 mThreadController->ReplaceSurface( &newSurface );
611 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
613 // Flush the event queue to give the update-render thread chance
614 // to start processing messages for new camera setup etc as soon as possible
617 // This method blocks until the render thread has finished rendering the current surface.
618 mThreadController->DeleteSurface( &surface );
621 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
623 return *mWindows.front()->GetSurface();
626 void Adaptor::ReleaseSurfaceLock()
628 mWindows.front()->GetSurface()->ReleaseLock();
631 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
633 if( !mTtsPlayers[mode] )
635 // Create the TTS player when it needed, because it can reduce launching time.
636 mTtsPlayers[mode] = TtsPlayer::New(mode);
639 return mTtsPlayers[mode];
642 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
644 bool idleAdded(false);
646 // Only add an idle if the Adaptor is actually running
647 if( RUNNING == mState || READY == mState || forceAdd )
649 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
655 void Adaptor::RemoveIdle( CallbackBase* callback )
657 mCallbackManager->RemoveIdleCallback( callback );
660 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
662 mThreadController->SetPreRenderCallback( callback );
665 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
667 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
668 windowImpl.SetAdaptor( Get() );
670 // Add the new Window to the container - the order is not important
671 mWindows.push_back( &windowImpl );
673 mWindowCreatedSignal.Emit( childWindow );
678 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
680 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
681 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
683 if( *iter == &windowImpl )
685 mWindows.erase( iter );
693 bool Adaptor::RemoveWindow( std::string childWindowName )
695 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
697 if( ( *iter )->GetName() == childWindowName )
699 mWindows.erase( iter );
707 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
709 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
711 if( ( *iter )->GetId() == childWindow->GetId() )
713 mWindows.erase( iter );
721 Dali::Adaptor& Adaptor::Get()
723 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
724 return gThreadLocalAdaptor->mAdaptor;
727 bool Adaptor::IsAvailable()
729 return gThreadLocalAdaptor != NULL;
732 void Adaptor::SceneCreated()
734 mCore->SceneCreated();
737 Dali::Integration::Core& Adaptor::GetCore()
742 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
744 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
747 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
749 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
750 return *mDisplayConnection;
753 GraphicsInterface& Adaptor::GetGraphicsInterface()
755 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
759 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
761 return *mPlatformAbstraction;
764 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
766 return *mNotificationTrigger;
769 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
771 return mTriggerEventFactory;
774 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
776 return mSocketFactory;
779 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
781 if( !mWindows.empty() )
783 return mWindows.front()->GetSurface();
789 TraceInterface& Adaptor::GetKernelTraceInterface()
791 return mKernelTracer;
794 TraceInterface& Adaptor::GetSystemTraceInterface()
796 return mSystemTracer;
799 PerformanceInterface* Adaptor::GetPerformanceInterface()
801 return mPerformanceInterface;
804 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
806 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
807 return *mPlatformAbstraction;
810 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
812 if( mTtsPlayers[mode] )
814 mTtsPlayers[mode].Reset();
818 Any Adaptor::GetNativeWindowHandle()
820 return mWindows.front()->GetNativeHandle();
823 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
825 Any nativeWindowHandle;
827 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
829 for( auto sceneHolder : mWindows )
831 if ( scene == sceneHolder->GetScene() )
833 nativeWindowHandle = sceneHolder->GetNativeHandle();
838 return nativeWindowHandle;
841 Any Adaptor::GetGraphicsDisplay()
847 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
849 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
850 display = eglImpl.GetDisplay();
856 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
858 mUseRemoteSurface = useRemoteSurface;
861 void Adaptor::AddObserver( LifeCycleObserver& observer )
863 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
865 if ( match == mObservers.end() )
867 mObservers.push_back( &observer );
871 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
873 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
875 if ( match != mObservers.end() )
877 mObservers.erase( match );
881 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
885 mCore->QueueEvent(event);
889 void Adaptor::ProcessCoreEvents()
893 if( mPerformanceInterface )
895 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
898 mCore->ProcessEvents();
900 if( mPerformanceInterface )
902 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
907 void Adaptor::RequestUpdate( bool forceUpdate )
913 mThreadController->RequestUpdate();
917 case PAUSED_WHILE_HIDDEN:
919 // When Dali applications are partially visible behind the lock-screen,
920 // the indicator must be updated (therefore allow updates in the PAUSED state)
923 mThreadController->RequestUpdateOnce();
935 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
937 // Only request a notification if the Adaptor is actually running
938 // and we haven't installed the idle notification
939 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
941 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
945 void Adaptor::OnWindowShown()
947 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
949 if( PAUSED_WHILE_HIDDEN == mState )
951 // Adaptor can now be resumed
956 // Force a render task
959 else if( RUNNING == mState )
961 // Force a render task
964 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
968 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
972 void Adaptor::OnWindowHidden()
974 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
976 if( RUNNING == mState || READY == mState )
978 bool allWindowsHidden = true;
980 for( auto window : mWindows )
982 if ( window->IsVisible() )
984 allWindowsHidden = false;
989 // Only pause the adaptor when all the windows are hidden
990 if( allWindowsHidden )
992 if( mState == RUNNING )
996 // Adaptor cannot be resumed until any window is shown
997 mState = PAUSED_WHILE_HIDDEN;
999 else // mState is READY
1001 // Pause the adaptor after the state gets RUNNING
1002 mState = PAUSED_WHILE_INITIALIZING;
1007 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1012 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1016 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1017 void Adaptor::OnDamaged( const DamageArea& area )
1019 // This is needed for the case where Dali window is partially obscured
1020 RequestUpdate( false );
1023 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1025 mResizedSignal.Emit( mAdaptor );
1028 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1030 // Flush the event queue to give the update-render thread chance
1031 // to start processing messages for new camera setup etc as soon as possible
1032 ProcessCoreEvents();
1034 mThreadController->ResizeSurface();
1037 void Adaptor::NotifySceneCreated()
1039 GetCore().SceneCreated();
1041 // Flush the event queue to give the update-render thread chance
1042 // to start processing messages for new camera setup etc as soon as possible
1043 ProcessCoreEvents();
1045 // Start thread controller after the scene has been created
1046 mThreadController->Start();
1048 // Process after surface is created (registering to remote surface provider if required)
1049 SurfaceInitialized();
1051 if( mState != PAUSED_WHILE_INITIALIZING )
1055 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1063 mState = PAUSED_WHILE_HIDDEN;
1065 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1069 void Adaptor::NotifyLanguageChanged()
1071 mLanguageChangedSignal.Emit( mAdaptor );
1074 void Adaptor::RenderOnce()
1076 RequestUpdateOnce();
1079 const LogFactoryInterface& Adaptor::GetLogFactory()
1081 return *mEnvironmentOptions;
1084 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1086 GetCore().RegisterProcessor(processor);
1089 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1091 GetCore().UnregisterProcessor(processor);
1094 void Adaptor::RequestUpdateOnce()
1096 if( mThreadController )
1098 mThreadController->RequestUpdateOnce();
1102 bool Adaptor::ProcessCoreEventsFromIdle()
1104 ProcessCoreEvents();
1106 // the idle handle automatically un-installs itself
1107 mNotificationOnIdleInstalled = false;
1112 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1114 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1116 for( auto window : mWindows )
1118 if ( scene == window->GetScene() )
1127 Dali::WindowContainer Adaptor::GetWindows() const
1129 Dali::WindowContainer windows;
1131 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1133 // Downcast to Dali::Window
1134 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1137 windows.push_back( window );
1144 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1146 Dali::SceneHolderList sceneHolderList;
1148 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1150 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1153 return sceneHolderList;
1156 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1158 mLanguageChangedSignal(),
1159 mWindowCreatedSignal(),
1160 mAdaptor( adaptor ),
1163 mThreadController( nullptr ),
1164 mGraphics( nullptr ),
1165 mDisplayConnection( nullptr ),
1167 mPlatformAbstraction( nullptr ),
1168 mCallbackManager( nullptr ),
1169 mNotificationOnIdleInstalled( false ),
1170 mNotificationTrigger( nullptr ),
1171 mDaliFeedbackPlugin(),
1172 mFeedbackController( nullptr ),
1175 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1176 mPerformanceInterface( nullptr ),
1179 mTriggerEventFactory(),
1180 mObjectProfiler( nullptr ),
1182 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1183 mUseRemoteSurface( false )
1185 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1186 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1188 gThreadLocalAdaptor = this;
1191 void Adaptor::SetRootLayoutDirection( std::string locale )
1193 Dali::Stage stage = Dali::Stage::GetCurrent();
1195 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1196 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1199 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1201 bool idleAdded( false );
1203 // Only add an idle if the Adaptor is actually running
1204 if( RUNNING == mState || READY == mState || forceAdd )
1206 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1212 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1214 mCallbackManager->RemoveIdleEntererCallback( callback );
1217 } // namespace Adaptor
1219 } // namespace Internal