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/devel-api/adaptor-framework/accessibility.h>
65 #include <dali/internal/system/common/logging.h>
67 #include <dali/internal/system/common/locale-utils.h>
68 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
69 #include <dali/internal/imaging/common/image-loader.h>
71 #include <dali/devel-api/adaptor-framework/file-stream.h>
73 using Dali::TextAbstraction::FontClient;
75 extern std::string GetSystemCachePath();
88 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
89 } // unnamed namespace
91 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
93 Dali::Adaptor* adaptor = new Dali::Adaptor;
94 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
95 adaptor->mImpl = impl;
97 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
98 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
100 impl->Initialize( graphicsFactory, configuration );
101 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
106 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
108 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
109 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
110 windowImpl.SetAdaptor( *adaptor );
114 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
116 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
117 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
118 adaptor->mImpl = impl;
120 impl->Initialize( graphicsFactory, configuration );
125 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
127 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
128 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
129 windowImpl.SetAdaptor( *adaptor );
133 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
135 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
136 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
137 mEnvironmentOptions->SetLogFunction( logFunction );
138 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
140 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
143 GetDataStoragePath( path );
144 mPlatformAbstraction->SetDataStoragePath( path );
146 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
147 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
149 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
152 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
154 if( mEnvironmentOptions->PerformanceServerRequired() )
156 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
159 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
160 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
162 mCallbackManager = CallbackManager::New();
164 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
166 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
168 mGraphics = &( graphicsFactory.Create() );
169 mGraphics->Initialize( mEnvironmentOptions );
171 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
173 // This will only be created once
174 eglGraphics->Create();
176 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
177 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
178 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
180 mCore = Integration::Core::New( *this,
181 *mPlatformAbstraction,
184 eglContextHelperImpl,
185 dataRetentionPolicy ,
186 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
187 mGraphics->GetDepthBufferRequired(),
188 mGraphics->GetStencilBufferRequired(),
189 mGraphics->PartialUpdateAvailable() );
191 defaultWindow->SetAdaptor( Get() );
193 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( defaultWindow ) );
196 mWindowCreatedSignal.Emit( window );
199 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
200 if( 0u < timeInterval )
202 mObjectProfiler = new ObjectProfiler( timeInterval );
205 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
207 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
209 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
211 // Should be called after Core creation
212 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
214 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
216 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
218 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
220 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
222 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
224 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
226 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
228 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
230 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
232 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
234 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
236 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
238 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
240 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
242 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
244 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
246 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
248 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
250 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
252 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
254 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
256 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
258 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
260 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
262 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
264 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
266 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
268 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
270 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
272 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
274 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
276 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
278 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
280 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
282 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
284 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
286 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
289 // Set max texture size
290 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
292 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
295 std::string systemCachePath = GetSystemCachePath();
296 if ( ! systemCachePath.empty() )
298 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
299 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
300 if( stream.is_open() )
303 while( std::getline( stream, line ) )
305 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
306 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
307 if( '#' == *( line.cbegin() ) || line == "" )
312 std::istringstream stream( line );
313 std::string environmentVariableName, environmentVariableValue;
314 std::getline(stream, environmentVariableName, ' ');
315 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
317 std::getline(stream, environmentVariableValue);
318 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
319 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
325 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
328 auto appName = GetApplicationPackageName();
329 auto bridge = Accessibility::Bridge::GetCurrentBridge();
330 bridge->SetApplicationName( appName );
331 bridge->Initialize();
332 Dali::Stage stage = Dali::Stage::GetCurrent();
333 Dali::Stage::GetCurrent().KeyEventSignal().Connect( &accessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent );
336 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent( const KeyEvent& event )
338 Accessibility::KeyEventType type;
339 if( event.state == KeyEvent::Down )
341 type = Accessibility::KeyEventType::KEY_PRESSED;
343 else if( event.state == KeyEvent::Up )
345 type = Accessibility::KeyEventType::KEY_RELEASED;
351 Dali::Accessibility::Bridge::GetCurrentBridge()->Emit( type, event.keyCode, event.keyPressedName, event.time, !event.keyPressed.empty() );
356 Accessibility::Bridge::GetCurrentBridge()->Terminate();
358 // Ensure stop status
361 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
362 gThreadLocalAdaptor = NULL;
364 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
366 (*iter)->OnDestroy();
369 // Clear out all the handles to Windows
372 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
373 delete mObjectProfiler;
377 delete mDisplayConnection;
378 delete mPlatformAbstraction;
379 delete mCallbackManager;
380 delete mPerformanceInterface;
382 mGraphics->Destroy();
384 // uninstall it on this thread (main actor thread)
385 Dali::Integration::Log::UninstallLogFunction();
387 // Delete environment options if we own it
388 if( mEnvironmentOptionsOwned )
390 delete mEnvironmentOptions;
394 void Adaptor::Start()
396 // It doesn't support restart after stop at this moment to support restarting, need more testing
397 if( READY != mState )
404 SetupSystemInformation();
406 // Start the callback manager
407 mCallbackManager->Start();
409 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
411 unsigned int dpiHor, dpiVer;
414 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
416 // set the DPI value for font rendering
417 FontClient fontClient = FontClient::Get();
418 fontClient.SetDpi( dpiHor, dpiVer );
420 // Initialize the thread controller
421 mThreadController->Initialize();
423 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
425 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
426 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
427 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
429 std::string systemCachePath = GetSystemCachePath();
430 if( ! systemCachePath.empty() )
432 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
435 printf("Error creating directory!n");
439 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
440 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
441 if( configFile.is_open() )
443 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
448 ProcessCoreEvents(); // Ensure any startup messages are processed.
450 // Initialize the image loader plugin
451 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
453 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
459 // Dali::Internal::Adaptor::Adaptor::Pause
460 void Adaptor::Pause()
462 // Only pause the adaptor if we're actually running.
463 if( RUNNING == mState )
465 // Inform observers that we are about to be paused.
466 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
471 // Pause all windows event handlers when adaptor paused
472 for( auto window : mWindows )
477 mThreadController->Pause();
480 // Ensure any messages queued during pause callbacks are processed by doing another update.
483 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
487 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
491 // Dali::Internal::Adaptor::Adaptor::Resume
492 void Adaptor::Resume()
494 // Only resume the adaptor if we are in the suspended state.
495 if( PAUSED == mState )
499 // Reset the event handlers when adaptor resumed
500 for( auto window : mWindows )
505 // Inform observers that we have resumed.
506 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
511 // Trigger processing of events queued up while paused
512 mCore->ProcessEvents();
514 // Do at end to ensure our first update/render after resumption includes the processed messages as well
515 mThreadController->Resume();
517 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
521 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
527 if( RUNNING == mState ||
529 PAUSED_WHILE_HIDDEN == mState )
531 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
536 mThreadController->Stop();
538 // Delete the TTS player
539 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
543 mTtsPlayers[i].Reset();
547 // Destroy the image loader plugin
548 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
550 delete mNotificationTrigger;
551 mNotificationTrigger = NULL;
553 mCallbackManager->Stop();
557 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
561 void Adaptor::ContextLost()
563 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
566 void Adaptor::ContextRegained()
568 // Inform core, so that texture resources can be reloaded
569 mCore->RecoverFromContextLoss();
571 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
574 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
576 Integration::Point convertedPoint( point );
577 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
580 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
582 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
583 mWindows.front()->FeedWheelEvent( event );
586 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
588 Integration::KeyEvent convertedEvent( keyEvent );
589 mWindows.front()->FeedKeyEvent( convertedEvent );
592 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
594 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
595 for( auto windowPtr : mWindows )
597 if( windowPtr == windowImpl ) // the window is not deleted
599 mResizedSignal.Emit( mAdaptor );
601 windowImpl->SetSurface( &newSurface );
603 // Flush the event queue to give the update-render thread chance
604 // to start processing messages for new camera setup etc as soon as possible
607 // This method blocks until the render thread has completed the replace.
608 mThreadController->ReplaceSurface( &newSurface );
614 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
616 // Flush the event queue to give the update-render thread chance
617 // to start processing messages for new camera setup etc as soon as possible
620 // This method blocks until the render thread has finished rendering the current surface.
621 mThreadController->DeleteSurface( &surface );
624 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
626 return *mWindows.front()->GetSurface();
629 void Adaptor::ReleaseSurfaceLock()
631 mWindows.front()->GetSurface()->ReleaseLock();
634 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
636 if( !mTtsPlayers[mode] )
638 // Create the TTS player when it needed, because it can reduce launching time.
639 mTtsPlayers[mode] = TtsPlayer::New(mode);
642 return mTtsPlayers[mode];
645 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
647 bool idleAdded(false);
649 // Only add an idle if the Adaptor is actually running
650 if( RUNNING == mState || READY == mState || forceAdd )
652 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
658 void Adaptor::RemoveIdle( CallbackBase* callback )
660 mCallbackManager->RemoveIdleCallback( callback );
663 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
665 mThreadController->SetPreRenderCallback( callback );
668 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
670 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
671 windowImpl.SetAdaptor( Get() );
673 // Add the new Window to the container - the order is not important
674 mWindows.push_back( &windowImpl );
676 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
679 mWindowCreatedSignal.Emit( window );
685 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
687 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
688 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
690 if( *iter == &windowImpl )
692 mWindows.erase( iter );
700 bool Adaptor::RemoveWindow( std::string childWindowName )
702 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
704 if( ( *iter )->GetName() == childWindowName )
706 mWindows.erase( iter );
714 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
716 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
718 if( ( *iter )->GetId() == childWindow->GetId() )
720 mWindows.erase( iter );
728 Dali::Adaptor& Adaptor::Get()
730 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
731 return gThreadLocalAdaptor->mAdaptor;
734 bool Adaptor::IsAvailable()
736 return gThreadLocalAdaptor != NULL;
739 void Adaptor::SceneCreated()
741 mCore->SceneCreated();
744 Dali::Integration::Core& Adaptor::GetCore()
749 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
751 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
754 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
756 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
757 return *mDisplayConnection;
760 GraphicsInterface& Adaptor::GetGraphicsInterface()
762 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
766 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
768 return *mPlatformAbstraction;
771 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
773 return *mNotificationTrigger;
776 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
778 return mTriggerEventFactory;
781 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
783 return mSocketFactory;
786 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
788 if( !mWindows.empty() )
790 return mWindows.front()->GetSurface();
796 TraceInterface& Adaptor::GetKernelTraceInterface()
798 return mKernelTracer;
801 TraceInterface& Adaptor::GetSystemTraceInterface()
803 return mSystemTracer;
806 PerformanceInterface* Adaptor::GetPerformanceInterface()
808 return mPerformanceInterface;
811 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
813 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
814 return *mPlatformAbstraction;
817 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
819 if( mTtsPlayers[mode] )
821 mTtsPlayers[mode].Reset();
825 Any Adaptor::GetNativeWindowHandle()
827 return mWindows.front()->GetNativeHandle();
830 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
832 Any nativeWindowHandle;
834 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
836 for( auto sceneHolder : mWindows )
838 if ( scene == sceneHolder->GetScene() )
840 nativeWindowHandle = sceneHolder->GetNativeHandle();
845 return nativeWindowHandle;
848 Any Adaptor::GetGraphicsDisplay()
854 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
856 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
857 display = eglImpl.GetDisplay();
863 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
865 mUseRemoteSurface = useRemoteSurface;
868 void Adaptor::AddObserver( LifeCycleObserver& observer )
870 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
872 if ( match == mObservers.end() )
874 mObservers.push_back( &observer );
878 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
880 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
882 if ( match != mObservers.end() )
884 mObservers.erase( match );
888 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
892 mCore->QueueEvent(event);
896 void Adaptor::ProcessCoreEvents()
900 if( mPerformanceInterface )
902 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
905 mCore->ProcessEvents();
907 if( mPerformanceInterface )
909 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
914 void Adaptor::RequestUpdate( bool forceUpdate )
920 mThreadController->RequestUpdate();
924 case PAUSED_WHILE_HIDDEN:
926 // When Dali applications are partially visible behind the lock-screen,
927 // the indicator must be updated (therefore allow updates in the PAUSED state)
930 mThreadController->RequestUpdateOnce();
942 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
944 // Only request a notification if the Adaptor is actually running
945 // and we haven't installed the idle notification
946 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
948 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
952 void Adaptor::OnWindowShown()
954 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
956 if( PAUSED_WHILE_HIDDEN == mState )
958 // Adaptor can now be resumed
963 // Force a render task
966 else if( RUNNING == mState )
968 // Force a render task
971 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
975 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
979 void Adaptor::OnWindowHidden()
981 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
983 if( RUNNING == mState || READY == mState )
985 bool allWindowsHidden = true;
987 for( auto window : mWindows )
989 if ( window->IsVisible() )
991 allWindowsHidden = false;
996 // Only pause the adaptor when all the windows are hidden
997 if( allWindowsHidden )
999 if( mState == RUNNING )
1003 // Adaptor cannot be resumed until any window is shown
1004 mState = PAUSED_WHILE_HIDDEN;
1006 else // mState is READY
1008 // Pause the adaptor after the state gets RUNNING
1009 mState = PAUSED_WHILE_INITIALIZING;
1014 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1019 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1023 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1024 void Adaptor::OnDamaged( const DamageArea& area )
1026 // This is needed for the case where Dali window is partially obscured
1027 RequestUpdate( false );
1030 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1032 mResizedSignal.Emit( mAdaptor );
1035 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1037 // Flush the event queue to give the update-render thread chance
1038 // to start processing messages for new camera setup etc as soon as possible
1039 ProcessCoreEvents();
1041 mThreadController->ResizeSurface();
1044 void Adaptor::NotifySceneCreated()
1046 GetCore().SceneCreated();
1048 // Flush the event queue to give the update-render thread chance
1049 // to start processing messages for new camera setup etc as soon as possible
1050 ProcessCoreEvents();
1052 // Start thread controller after the scene has been created
1053 mThreadController->Start();
1055 // Process after surface is created (registering to remote surface provider if required)
1056 SurfaceInitialized();
1058 if( mState != PAUSED_WHILE_INITIALIZING )
1062 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1070 mState = PAUSED_WHILE_HIDDEN;
1072 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1076 void Adaptor::NotifyLanguageChanged()
1078 mLanguageChangedSignal.Emit( mAdaptor );
1081 void Adaptor::RenderOnce()
1083 RequestUpdateOnce();
1086 const LogFactoryInterface& Adaptor::GetLogFactory()
1088 return *mEnvironmentOptions;
1091 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1093 GetCore().RegisterProcessor(processor);
1096 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1098 GetCore().UnregisterProcessor(processor);
1101 void Adaptor::RequestUpdateOnce()
1103 if( mThreadController )
1105 mThreadController->RequestUpdateOnce();
1109 bool Adaptor::ProcessCoreEventsFromIdle()
1111 ProcessCoreEvents();
1113 // the idle handle automatically un-installs itself
1114 mNotificationOnIdleInstalled = false;
1119 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1121 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1123 for( auto window : mWindows )
1125 if ( scene == window->GetScene() )
1134 Dali::WindowContainer Adaptor::GetWindows() const
1136 Dali::WindowContainer windows;
1138 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1140 // Downcast to Dali::Window
1141 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1144 windows.push_back( window );
1151 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1153 mLanguageChangedSignal(),
1154 mWindowCreatedSignal(),
1155 mAdaptor( adaptor ),
1158 mThreadController( nullptr ),
1159 mGraphics( nullptr ),
1160 mDisplayConnection( nullptr ),
1162 mPlatformAbstraction( nullptr ),
1163 mCallbackManager( nullptr ),
1164 mNotificationOnIdleInstalled( false ),
1165 mNotificationTrigger( nullptr ),
1166 mDaliFeedbackPlugin(),
1167 mFeedbackController( nullptr ),
1170 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1171 mPerformanceInterface( nullptr ),
1174 mTriggerEventFactory(),
1175 mObjectProfiler( nullptr ),
1177 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1178 mUseRemoteSurface( false )
1180 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1181 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1183 gThreadLocalAdaptor = this;
1186 void Adaptor::SetRootLayoutDirection( std::string locale )
1188 Dali::Stage stage = Dali::Stage::GetCurrent();
1190 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1191 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1194 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1196 bool idleAdded( false );
1198 // Only add an idle if the Adaptor is actually running
1199 if( RUNNING == mState || READY == mState || forceAdd )
1201 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1207 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1209 mCallbackManager->RemoveIdleEntererCallback( callback );
1212 } // namespace Adaptor
1214 } // namespace Internal