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>
41 #include <dali/public-api/dali-adaptor-common.h>
42 #include <dali/internal/system/common/thread-controller.h>
43 #include <dali/internal/system/common/performance-interface-factory.h>
44 #include <dali/internal/adaptor/common/lifecycle-observer.h>
46 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
47 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
49 #include <dali/devel-api/text-abstraction/font-client.h>
51 #include <dali/internal/system/common/callback-manager.h>
52 #include <dali/internal/accessibility/common/tts-player-impl.h>
53 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
54 #include <dali/internal/window-system/common/event-handler.h>
55 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
56 #include <dali/internal/graphics/gles/gl-implementation.h>
57 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
58 #include <dali/internal/graphics/common/egl-image-extensions.h>
59 #include <dali/internal/clipboard/common/clipboard-impl.h>
60 #include <dali/internal/system/common/object-profiler.h>
61 #include <dali/internal/window-system/common/display-connection.h>
62 #include <dali/internal/window-system/common/window-impl.h>
63 #include <dali/internal/window-system/common/window-render-surface.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-loader.h>
72 #include <dali/devel-api/adaptor-framework/file-stream.h>
74 using Dali::TextAbstraction::FontClient;
76 extern std::string GetSystemCachePath();
89 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
90 } // unnamed namespace
92 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
94 Dali::Adaptor* adaptor = new Dali::Adaptor;
95 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
96 adaptor->mImpl = impl;
98 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
99 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
101 impl->Initialize( graphicsFactory, configuration );
102 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
107 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
109 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
110 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
111 windowImpl.SetAdaptor( *adaptor );
115 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
117 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
118 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
119 adaptor->mImpl = impl;
121 impl->Initialize( graphicsFactory, configuration );
126 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
128 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
129 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
130 windowImpl.SetAdaptor( *adaptor );
134 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
136 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
137 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
138 mEnvironmentOptions->SetLogFunction( logFunction );
139 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
141 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
144 GetDataStoragePath( path );
145 mPlatformAbstraction->SetDataStoragePath( path );
147 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
148 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
150 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
153 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
155 if( mEnvironmentOptions->PerformanceServerRequired() )
157 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
160 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
161 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
163 mCallbackManager = CallbackManager::New();
165 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
167 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
169 mGraphics = &( graphicsFactory.Create() );
170 mGraphics->Initialize( mEnvironmentOptions );
172 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
174 // This will only be created once
175 eglGraphics->Create();
177 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
178 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
179 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
181 mCore = Integration::Core::New( *this,
182 *mPlatformAbstraction,
185 eglContextHelperImpl,
186 dataRetentionPolicy ,
187 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
188 mGraphics->GetDepthBufferRequired(),
189 mGraphics->GetStencilBufferRequired() );
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.c_str() != NULL )
298 Dali::Vector<char> buffer;
299 if( Dali::FileLoader::ReadFile( systemCachePath + "gpu-environment.conf", buffer, Dali::FileLoader::FileType::TEXT ) )
301 std::stringstream stream( &buffer[0], std::ios::in );
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() );
332 // Ensure stop status
335 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
336 gThreadLocalAdaptor = NULL;
338 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
340 (*iter)->OnDestroy();
343 // Clear out all the handles to Windows
346 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
347 delete mObjectProfiler;
351 delete mDisplayConnection;
352 delete mPlatformAbstraction;
353 delete mCallbackManager;
354 delete mPerformanceInterface;
356 mGraphics->Destroy();
358 // uninstall it on this thread (main actor thread)
359 Dali::Integration::Log::UninstallLogFunction();
361 // Delete environment options if we own it
362 if( mEnvironmentOptionsOwned )
364 delete mEnvironmentOptions;
368 void Adaptor::Start()
370 // It doesn't support restart after stop at this moment to support restarting, need more testing
371 if( READY != mState )
378 SetupSystemInformation();
380 // Start the callback manager
381 mCallbackManager->Start();
383 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
385 unsigned int dpiHor, dpiVer;
388 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
390 // set the DPI value for font rendering
391 FontClient fontClient = FontClient::Get();
392 fontClient.SetDpi( dpiHor, dpiVer );
394 // Initialize the thread controller
395 mThreadController->Initialize();
397 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
399 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
400 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
401 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
403 std::string systemCachePath = GetSystemCachePath();
404 if( systemCachePath.c_str() != NULL )
406 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
409 printf("Error creating directory!n");
413 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
414 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
415 if( configFile.is_open() )
417 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
423 ProcessCoreEvents(); // Ensure any startup messages are processed.
425 // Initialize the image loader plugin
426 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
428 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
434 // Dali::Internal::Adaptor::Adaptor::Pause
435 void Adaptor::Pause()
437 // Only pause the adaptor if we're actually running.
438 if( RUNNING == mState )
440 // Inform observers that we are about to be paused.
441 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
446 // Pause all windows event handlers when adaptor paused
447 for( auto window : mWindows )
452 mThreadController->Pause();
455 // Ensure any messages queued during pause callbacks are processed by doing another update.
458 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
462 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
466 // Dali::Internal::Adaptor::Adaptor::Resume
467 void Adaptor::Resume()
469 // Only resume the adaptor if we are in the suspended state.
470 if( PAUSED == mState )
474 // Reset the event handlers when adaptor resumed
475 for( auto window : mWindows )
480 // Inform observers that we have resumed.
481 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
486 // Trigger processing of events queued up while paused
487 mCore->ProcessEvents();
489 // Do at end to ensure our first update/render after resumption includes the processed messages as well
490 mThreadController->Resume();
492 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
496 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
502 if( RUNNING == mState ||
504 PAUSED_WHILE_HIDDEN == mState )
506 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
511 mThreadController->Stop();
513 // Delete the TTS player
514 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
518 mTtsPlayers[i].Reset();
522 // Destroy the image loader plugin
523 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
525 delete mNotificationTrigger;
526 mNotificationTrigger = NULL;
528 mCallbackManager->Stop();
532 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
536 void Adaptor::ContextLost()
538 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
541 void Adaptor::ContextRegained()
543 // Inform core, so that texture resources can be reloaded
544 mCore->RecoverFromContextLoss();
546 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
549 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
551 Integration::Point convertedPoint( point );
552 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
555 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
557 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
558 mWindows.front()->FeedWheelEvent( event );
561 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
563 Integration::KeyEvent convertedEvent( keyEvent );
564 mWindows.front()->FeedKeyEvent( convertedEvent );
567 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
569 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
570 for( auto windowPtr : mWindows )
572 if( windowPtr == windowImpl ) // the window is not deleted
574 mResizedSignal.Emit( mAdaptor );
576 windowImpl->SetSurface( &newSurface );
578 // Flush the event queue to give the update-render thread chance
579 // to start processing messages for new camera setup etc as soon as possible
582 // This method blocks until the render thread has completed the replace.
583 mThreadController->ReplaceSurface( &newSurface );
589 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
591 // Flush the event queue to give the update-render thread chance
592 // to start processing messages for new camera setup etc as soon as possible
595 // This method blocks until the render thread has finished rendering the current surface.
596 mThreadController->DeleteSurface( &surface );
599 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
601 return *mWindows.front()->GetSurface();
604 void Adaptor::ReleaseSurfaceLock()
606 mWindows.front()->GetSurface()->ReleaseLock();
609 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
611 if( !mTtsPlayers[mode] )
613 // Create the TTS player when it needed, because it can reduce launching time.
614 mTtsPlayers[mode] = TtsPlayer::New(mode);
617 return mTtsPlayers[mode];
620 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
622 bool idleAdded(false);
624 // Only add an idle if the Adaptor is actually running
625 if( RUNNING == mState || READY == mState || forceAdd )
627 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
633 void Adaptor::RemoveIdle( CallbackBase* callback )
635 mCallbackManager->RemoveIdleCallback( callback );
638 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
640 mThreadController->SetPreRenderCallback( callback );
643 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
645 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
646 windowImpl.SetAdaptor( Get() );
648 // Add the new Window to the container - the order is not important
649 mWindows.push_back( &windowImpl );
651 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
654 mWindowCreatedSignal.Emit( window );
660 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
662 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
663 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
665 if( *iter == &windowImpl )
667 mWindows.erase( iter );
675 bool Adaptor::RemoveWindow( std::string childWindowName )
677 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
679 if( ( *iter )->GetName() == childWindowName )
681 mWindows.erase( iter );
689 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
691 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
693 if( ( *iter )->GetId() == childWindow->GetId() )
695 mWindows.erase( iter );
703 Dali::Adaptor& Adaptor::Get()
705 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
706 return gThreadLocalAdaptor->mAdaptor;
709 bool Adaptor::IsAvailable()
711 return gThreadLocalAdaptor != NULL;
714 void Adaptor::SceneCreated()
716 mCore->SceneCreated();
719 Dali::Integration::Core& Adaptor::GetCore()
724 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
726 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
729 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
731 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
732 return *mDisplayConnection;
735 GraphicsInterface& Adaptor::GetGraphicsInterface()
737 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
741 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
743 return *mPlatformAbstraction;
746 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
748 return *mNotificationTrigger;
751 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
753 return mTriggerEventFactory;
756 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
758 return mSocketFactory;
761 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
763 if( !mWindows.empty() )
765 return mWindows.front()->GetSurface();
771 TraceInterface& Adaptor::GetKernelTraceInterface()
773 return mKernelTracer;
776 TraceInterface& Adaptor::GetSystemTraceInterface()
778 return mSystemTracer;
781 PerformanceInterface* Adaptor::GetPerformanceInterface()
783 return mPerformanceInterface;
786 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
788 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
789 return *mPlatformAbstraction;
792 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
794 if( mTtsPlayers[mode] )
796 mTtsPlayers[mode].Reset();
800 Any Adaptor::GetNativeWindowHandle()
802 return mWindows.front()->GetNativeHandle();
805 Any Adaptor::GetGraphicsDisplay()
811 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
813 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
814 display = eglImpl.GetDisplay();
820 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
822 mUseRemoteSurface = useRemoteSurface;
825 void Adaptor::AddObserver( LifeCycleObserver& observer )
827 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
829 if ( match == mObservers.end() )
831 mObservers.push_back( &observer );
835 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
837 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
839 if ( match != mObservers.end() )
841 mObservers.erase( match );
845 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
849 mCore->QueueEvent(event);
853 void Adaptor::ProcessCoreEvents()
857 if( mPerformanceInterface )
859 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
862 mCore->ProcessEvents();
864 if( mPerformanceInterface )
866 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
871 void Adaptor::RequestUpdate( bool forceUpdate )
877 mThreadController->RequestUpdate();
881 case PAUSED_WHILE_HIDDEN:
883 // When Dali applications are partially visible behind the lock-screen,
884 // the indicator must be updated (therefore allow updates in the PAUSED state)
887 mThreadController->RequestUpdateOnce();
899 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
901 // Only request a notification if the Adaptor is actually running
902 // and we haven't installed the idle notification
903 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
905 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
909 void Adaptor::OnWindowShown()
911 if( PAUSED_WHILE_HIDDEN == mState )
913 // Adaptor can now be resumed
918 // Force a render task
921 else if( RUNNING == mState )
923 // Force a render task
926 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
930 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
934 void Adaptor::OnWindowHidden()
936 if( RUNNING == mState || READY == mState )
938 bool allWindowsHidden = true;
940 for( auto window : mWindows )
942 if ( window->IsVisible() )
944 allWindowsHidden = false;
949 // Only pause the adaptor when all the windows are hidden
950 if( allWindowsHidden )
952 if( mState == RUNNING )
956 // Adaptor cannot be resumed until any window is shown
957 mState = PAUSED_WHILE_HIDDEN;
959 else // mState is READY
961 // Pause the adaptor after the state gets RUNNING
962 mState = PAUSED_WHILE_INITIALIZING;
967 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
972 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
976 // Dali::Internal::Adaptor::Adaptor::OnDamaged
977 void Adaptor::OnDamaged( const DamageArea& area )
979 // This is needed for the case where Dali window is partially obscured
980 RequestUpdate( false );
983 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
985 mResizedSignal.Emit( mAdaptor );
988 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
990 // Flush the event queue to give the update-render thread chance
991 // to start processing messages for new camera setup etc as soon as possible
994 mThreadController->ResizeSurface();
997 void Adaptor::NotifySceneCreated()
999 GetCore().SceneCreated();
1001 // Flush the event queue to give the update-render thread chance
1002 // to start processing messages for new camera setup etc as soon as possible
1003 ProcessCoreEvents();
1005 // Start thread controller after the scene has been created
1006 mThreadController->Start();
1008 // Process after surface is created (registering to remote surface provider if required)
1009 SurfaceInitialized();
1011 if( mState != PAUSED_WHILE_INITIALIZING )
1015 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1023 mState = PAUSED_WHILE_HIDDEN;
1025 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1029 void Adaptor::NotifyLanguageChanged()
1031 mLanguageChangedSignal.Emit( mAdaptor );
1034 void Adaptor::RenderOnce()
1036 RequestUpdateOnce();
1039 const LogFactoryInterface& Adaptor::GetLogFactory()
1041 return *mEnvironmentOptions;
1044 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1046 GetCore().RegisterProcessor(processor);
1049 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1051 GetCore().UnregisterProcessor(processor);
1054 void Adaptor::RequestUpdateOnce()
1056 if( mThreadController )
1058 mThreadController->RequestUpdateOnce();
1062 bool Adaptor::ProcessCoreEventsFromIdle()
1064 ProcessCoreEvents();
1066 // the idle handle automatically un-installs itself
1067 mNotificationOnIdleInstalled = false;
1072 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1074 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1076 for( auto window : mWindows )
1078 if ( scene == window->GetScene() )
1087 Dali::WindowContainer Adaptor::GetWindows() const
1089 Dali::WindowContainer windows;
1091 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1093 // Downcast to Dali::Window
1094 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1097 windows.push_back( window );
1104 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1106 mLanguageChangedSignal(),
1107 mWindowCreatedSignal(),
1108 mAdaptor( adaptor ),
1111 mThreadController( nullptr ),
1112 mGraphics( nullptr ),
1113 mDisplayConnection( nullptr ),
1115 mPlatformAbstraction( nullptr ),
1116 mCallbackManager( nullptr ),
1117 mNotificationOnIdleInstalled( false ),
1118 mNotificationTrigger( nullptr ),
1119 mDaliFeedbackPlugin(),
1120 mFeedbackController( nullptr ),
1123 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1124 mPerformanceInterface( nullptr ),
1127 mTriggerEventFactory(),
1128 mObjectProfiler( nullptr ),
1130 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1131 mUseRemoteSurface( false )
1133 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1134 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1136 gThreadLocalAdaptor = this;
1139 void Adaptor::SetRootLayoutDirection( std::string locale )
1141 Dali::Stage stage = Dali::Stage::GetCurrent();
1143 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1144 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1147 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1149 bool idleAdded( false );
1151 // Only add an idle if the Adaptor is actually running
1152 if( RUNNING == mState || READY == mState || forceAdd )
1154 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1160 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1162 mCallbackManager->RemoveIdleEntererCallback( callback );
1165 } // namespace Adaptor
1167 } // namespace Internal