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::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( defaultWindow ) );
195 mWindowCreatedSignal.Emit( window );
198 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
199 if( 0u < timeInterval )
201 mObjectProfiler = new ObjectProfiler( timeInterval );
204 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
206 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
208 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
210 // Should be called after Core creation
211 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
213 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
215 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
217 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
219 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
221 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
223 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
225 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
227 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
229 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
231 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
233 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
235 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
237 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
239 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
241 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
243 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
245 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
247 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
249 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
251 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
253 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
255 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
257 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
259 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
261 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
263 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
265 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
267 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
269 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
271 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
273 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
275 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
277 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
279 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
281 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
283 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
285 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
288 // Set max texture size
289 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
291 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
294 std::string systemCachePath = GetSystemCachePath();
295 if ( ! systemCachePath.empty() )
297 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
298 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
299 if( stream.is_open() )
302 while( std::getline( stream, line ) )
304 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
305 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
306 if( '#' == *( line.cbegin() ) || line == "" )
311 std::istringstream stream( line );
312 std::string environmentVariableName, environmentVariableValue;
313 std::getline(stream, environmentVariableName, ' ');
314 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
316 std::getline(stream, environmentVariableValue);
317 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
318 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
324 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
327 auto appName = GetApplicationPackageName();
328 auto bridge = Accessibility::Bridge::GetCurrentBridge();
329 bridge->SetApplicationName( appName );
330 bridge->Initialize();
331 Dali::Stage stage = Dali::Stage::GetCurrent();
332 Dali::Stage::GetCurrent().KeyEventSignal().Connect( &accessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent );
335 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent( const KeyEvent& event )
337 Accessibility::KeyEventType type;
338 if( event.state == KeyEvent::Down )
340 type = Accessibility::KeyEventType::KEY_PRESSED;
342 else if( event.state == KeyEvent::Up )
344 type = Accessibility::KeyEventType::KEY_RELEASED;
350 Dali::Accessibility::Bridge::GetCurrentBridge()->Emit( type, event.keyCode, event.keyPressedName, event.time, !event.keyPressed.empty() );
355 Accessibility::Bridge::GetCurrentBridge()->Terminate();
357 // Ensure stop status
360 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
361 gThreadLocalAdaptor = NULL;
363 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
365 (*iter)->OnDestroy();
368 // Clear out all the handles to Windows
371 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
372 delete mObjectProfiler;
376 delete mDisplayConnection;
377 delete mPlatformAbstraction;
378 delete mCallbackManager;
379 delete mPerformanceInterface;
381 mGraphics->Destroy();
383 // uninstall it on this thread (main actor thread)
384 Dali::Integration::Log::UninstallLogFunction();
386 // Delete environment options if we own it
387 if( mEnvironmentOptionsOwned )
389 delete mEnvironmentOptions;
393 void Adaptor::Start()
395 // It doesn't support restart after stop at this moment to support restarting, need more testing
396 if( READY != mState )
403 SetupSystemInformation();
405 // Start the callback manager
406 mCallbackManager->Start();
408 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
410 unsigned int dpiHor, dpiVer;
413 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
415 // set the DPI value for font rendering
416 FontClient fontClient = FontClient::Get();
417 fontClient.SetDpi( dpiHor, dpiVer );
419 // Initialize the thread controller
420 mThreadController->Initialize();
422 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
424 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
425 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
426 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
428 std::string systemCachePath = GetSystemCachePath();
429 if( ! systemCachePath.empty() )
431 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
434 printf("Error creating directory!n");
438 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
439 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
440 if( configFile.is_open() )
442 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
447 ProcessCoreEvents(); // Ensure any startup messages are processed.
449 // Initialize the image loader plugin
450 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
452 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
458 // Dali::Internal::Adaptor::Adaptor::Pause
459 void Adaptor::Pause()
461 // Only pause the adaptor if we're actually running.
462 if( RUNNING == mState )
464 // Inform observers that we are about to be paused.
465 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
470 // Pause all windows event handlers when adaptor paused
471 for( auto window : mWindows )
476 mThreadController->Pause();
479 // Ensure any messages queued during pause callbacks are processed by doing another update.
482 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
486 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
490 // Dali::Internal::Adaptor::Adaptor::Resume
491 void Adaptor::Resume()
493 // Only resume the adaptor if we are in the suspended state.
494 if( PAUSED == mState )
498 // Reset the event handlers when adaptor resumed
499 for( auto window : mWindows )
504 // Inform observers that we have resumed.
505 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
510 // Trigger processing of events queued up while paused
511 mCore->ProcessEvents();
513 // Do at end to ensure our first update/render after resumption includes the processed messages as well
514 mThreadController->Resume();
516 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
520 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
526 if( RUNNING == mState ||
528 PAUSED_WHILE_HIDDEN == mState )
530 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
535 mThreadController->Stop();
537 // Delete the TTS player
538 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
542 mTtsPlayers[i].Reset();
546 // Destroy the image loader plugin
547 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
549 delete mNotificationTrigger;
550 mNotificationTrigger = NULL;
552 mCallbackManager->Stop();
556 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
560 void Adaptor::ContextLost()
562 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
565 void Adaptor::ContextRegained()
567 // Inform core, so that texture resources can be reloaded
568 mCore->RecoverFromContextLoss();
570 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
573 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
575 Integration::Point convertedPoint( point );
576 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
579 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
581 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
582 mWindows.front()->FeedWheelEvent( event );
585 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
587 Integration::KeyEvent convertedEvent( keyEvent );
588 mWindows.front()->FeedKeyEvent( convertedEvent );
591 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
593 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
594 for( auto windowPtr : mWindows )
596 if( windowPtr == windowImpl ) // the window is not deleted
598 mResizedSignal.Emit( mAdaptor );
600 windowImpl->SetSurface( &newSurface );
602 // Flush the event queue to give the update-render thread chance
603 // to start processing messages for new camera setup etc as soon as possible
606 // This method blocks until the render thread has completed the replace.
607 mThreadController->ReplaceSurface( &newSurface );
613 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
615 // Flush the event queue to give the update-render thread chance
616 // to start processing messages for new camera setup etc as soon as possible
619 // This method blocks until the render thread has finished rendering the current surface.
620 mThreadController->DeleteSurface( &surface );
623 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
625 return *mWindows.front()->GetSurface();
628 void Adaptor::ReleaseSurfaceLock()
630 mWindows.front()->GetSurface()->ReleaseLock();
633 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
635 if( !mTtsPlayers[mode] )
637 // Create the TTS player when it needed, because it can reduce launching time.
638 mTtsPlayers[mode] = TtsPlayer::New(mode);
641 return mTtsPlayers[mode];
644 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
646 bool idleAdded(false);
648 // Only add an idle if the Adaptor is actually running
649 if( RUNNING == mState || READY == mState || forceAdd )
651 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
657 void Adaptor::RemoveIdle( CallbackBase* callback )
659 mCallbackManager->RemoveIdleCallback( callback );
662 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
664 mThreadController->SetPreRenderCallback( callback );
667 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
669 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
670 windowImpl.SetAdaptor( Get() );
672 // Add the new Window to the container - the order is not important
673 mWindows.push_back( &windowImpl );
675 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
678 mWindowCreatedSignal.Emit( window );
684 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
686 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
687 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
689 if( *iter == &windowImpl )
691 mWindows.erase( iter );
699 bool Adaptor::RemoveWindow( std::string childWindowName )
701 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
703 if( ( *iter )->GetName() == childWindowName )
705 mWindows.erase( iter );
713 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
715 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
717 if( ( *iter )->GetId() == childWindow->GetId() )
719 mWindows.erase( iter );
727 Dali::Adaptor& Adaptor::Get()
729 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
730 return gThreadLocalAdaptor->mAdaptor;
733 bool Adaptor::IsAvailable()
735 return gThreadLocalAdaptor != NULL;
738 void Adaptor::SceneCreated()
740 mCore->SceneCreated();
743 Dali::Integration::Core& Adaptor::GetCore()
748 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
750 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
753 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
755 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
756 return *mDisplayConnection;
759 GraphicsInterface& Adaptor::GetGraphicsInterface()
761 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
765 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
767 return *mPlatformAbstraction;
770 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
772 return *mNotificationTrigger;
775 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
777 return mTriggerEventFactory;
780 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
782 return mSocketFactory;
785 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
787 if( !mWindows.empty() )
789 return mWindows.front()->GetSurface();
795 TraceInterface& Adaptor::GetKernelTraceInterface()
797 return mKernelTracer;
800 TraceInterface& Adaptor::GetSystemTraceInterface()
802 return mSystemTracer;
805 PerformanceInterface* Adaptor::GetPerformanceInterface()
807 return mPerformanceInterface;
810 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
812 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
813 return *mPlatformAbstraction;
816 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
818 if( mTtsPlayers[mode] )
820 mTtsPlayers[mode].Reset();
824 Any Adaptor::GetNativeWindowHandle()
826 return mWindows.front()->GetNativeHandle();
829 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
831 Any nativeWindowHandle;
833 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
835 for( auto sceneHolder : mWindows )
837 if ( scene == sceneHolder->GetScene() )
839 nativeWindowHandle = sceneHolder->GetNativeHandle();
844 return nativeWindowHandle;
847 Any Adaptor::GetGraphicsDisplay()
853 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
855 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
856 display = eglImpl.GetDisplay();
862 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
864 mUseRemoteSurface = useRemoteSurface;
867 void Adaptor::AddObserver( LifeCycleObserver& observer )
869 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
871 if ( match == mObservers.end() )
873 mObservers.push_back( &observer );
877 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
879 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
881 if ( match != mObservers.end() )
883 mObservers.erase( match );
887 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
891 mCore->QueueEvent(event);
895 void Adaptor::ProcessCoreEvents()
899 if( mPerformanceInterface )
901 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
904 mCore->ProcessEvents();
906 if( mPerformanceInterface )
908 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
913 void Adaptor::RequestUpdate( bool forceUpdate )
919 mThreadController->RequestUpdate();
923 case PAUSED_WHILE_HIDDEN:
925 // When Dali applications are partially visible behind the lock-screen,
926 // the indicator must be updated (therefore allow updates in the PAUSED state)
929 mThreadController->RequestUpdateOnce();
941 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
943 // Only request a notification if the Adaptor is actually running
944 // and we haven't installed the idle notification
945 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
947 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
951 void Adaptor::OnWindowShown()
953 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
955 if( PAUSED_WHILE_HIDDEN == mState )
957 // Adaptor can now be resumed
962 // Force a render task
965 else if( RUNNING == mState )
967 // Force a render task
970 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
974 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
978 void Adaptor::OnWindowHidden()
980 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
982 if( RUNNING == mState || READY == mState )
984 bool allWindowsHidden = true;
986 for( auto window : mWindows )
988 if ( window->IsVisible() )
990 allWindowsHidden = false;
995 // Only pause the adaptor when all the windows are hidden
996 if( allWindowsHidden )
998 if( mState == RUNNING )
1002 // Adaptor cannot be resumed until any window is shown
1003 mState = PAUSED_WHILE_HIDDEN;
1005 else // mState is READY
1007 // Pause the adaptor after the state gets RUNNING
1008 mState = PAUSED_WHILE_INITIALIZING;
1013 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1018 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1022 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1023 void Adaptor::OnDamaged( const DamageArea& area )
1025 // This is needed for the case where Dali window is partially obscured
1026 RequestUpdate( false );
1029 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1031 mResizedSignal.Emit( mAdaptor );
1034 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1036 // Flush the event queue to give the update-render thread chance
1037 // to start processing messages for new camera setup etc as soon as possible
1038 ProcessCoreEvents();
1040 mThreadController->ResizeSurface();
1043 void Adaptor::NotifySceneCreated()
1045 GetCore().SceneCreated();
1047 // Flush the event queue to give the update-render thread chance
1048 // to start processing messages for new camera setup etc as soon as possible
1049 ProcessCoreEvents();
1051 // Start thread controller after the scene has been created
1052 mThreadController->Start();
1054 // Process after surface is created (registering to remote surface provider if required)
1055 SurfaceInitialized();
1057 if( mState != PAUSED_WHILE_INITIALIZING )
1061 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1069 mState = PAUSED_WHILE_HIDDEN;
1071 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1075 void Adaptor::NotifyLanguageChanged()
1077 mLanguageChangedSignal.Emit( mAdaptor );
1080 void Adaptor::RenderOnce()
1082 RequestUpdateOnce();
1085 const LogFactoryInterface& Adaptor::GetLogFactory()
1087 return *mEnvironmentOptions;
1090 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1092 GetCore().RegisterProcessor(processor);
1095 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1097 GetCore().UnregisterProcessor(processor);
1100 void Adaptor::RequestUpdateOnce()
1102 if( mThreadController )
1104 mThreadController->RequestUpdateOnce();
1108 bool Adaptor::ProcessCoreEventsFromIdle()
1110 ProcessCoreEvents();
1112 // the idle handle automatically un-installs itself
1113 mNotificationOnIdleInstalled = false;
1118 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1120 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1122 for( auto window : mWindows )
1124 if ( scene == window->GetScene() )
1133 Dali::WindowContainer Adaptor::GetWindows() const
1135 Dali::WindowContainer windows;
1137 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1139 // Downcast to Dali::Window
1140 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1143 windows.push_back( window );
1150 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1152 mLanguageChangedSignal(),
1153 mWindowCreatedSignal(),
1154 mAdaptor( adaptor ),
1157 mThreadController( nullptr ),
1158 mGraphics( nullptr ),
1159 mDisplayConnection( nullptr ),
1161 mPlatformAbstraction( nullptr ),
1162 mCallbackManager( nullptr ),
1163 mNotificationOnIdleInstalled( false ),
1164 mNotificationTrigger( nullptr ),
1165 mDaliFeedbackPlugin(),
1166 mFeedbackController( nullptr ),
1169 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1170 mPerformanceInterface( nullptr ),
1173 mTriggerEventFactory(),
1174 mObjectProfiler( nullptr ),
1176 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1177 mUseRemoteSurface( false )
1179 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1180 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1182 gThreadLocalAdaptor = this;
1185 void Adaptor::SetRootLayoutDirection( std::string locale )
1187 Dali::Stage stage = Dali::Stage::GetCurrent();
1189 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1190 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1193 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1195 bool idleAdded( false );
1197 // Only add an idle if the Adaptor is actually running
1198 if( RUNNING == mState || READY == mState || forceAdd )
1200 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1206 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1208 mCallbackManager->RemoveIdleEntererCallback( callback );
1211 } // namespace Adaptor
1213 } // namespace Internal