2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/key-event-integ.h>
33 #include <dali/integration-api/events/touch-event-integ.h>
34 #include <dali/integration-api/events/wheel-event-integ.h>
35 #include <dali/integration-api/processor-interface.h>
40 #include <dali/public-api/dali-adaptor-common.h>
41 #include <dali/internal/system/common/thread-controller.h>
42 #include <dali/internal/system/common/performance-interface-factory.h>
43 #include <dali/internal/adaptor/common/lifecycle-observer.h>
45 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
46 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
48 #include <dali/devel-api/text-abstraction/font-client.h>
50 #include <dali/internal/system/common/callback-manager.h>
51 #include <dali/internal/accessibility/common/tts-player-impl.h>
52 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
53 #include <dali/internal/window-system/common/event-handler.h>
54 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
55 #include <dali/internal/graphics/gles/gl-implementation.h>
56 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
57 #include <dali/internal/graphics/common/egl-image-extensions.h>
58 #include <dali/internal/clipboard/common/clipboard-impl.h>
59 #include <dali/internal/system/common/object-profiler.h>
60 #include <dali/internal/window-system/common/display-connection.h>
61 #include <dali/internal/window-system/common/window-impl.h>
62 #include <dali/internal/window-system/common/window-render-surface.h>
64 #include <dali/internal/system/common/logging.h>
66 #include <dali/internal/system/common/locale-utils.h>
67 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
68 #include <dali/internal/imaging/common/image-loader.h>
70 #include <dali/devel-api/adaptor-framework/file-stream.h>
72 using Dali::TextAbstraction::FontClient;
74 extern std::string GetSystemCachePath();
87 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
88 } // unnamed namespace
90 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
92 Dali::Adaptor* adaptor = new Dali::Adaptor;
93 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
94 adaptor->mImpl = impl;
96 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
97 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
99 impl->Initialize( graphicsFactory, configuration );
100 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
105 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
107 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
108 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
109 windowImpl.SetAdaptor( *adaptor );
113 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
115 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
116 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
117 adaptor->mImpl = impl;
119 impl->Initialize( graphicsFactory, configuration );
124 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
126 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
127 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
128 windowImpl.SetAdaptor( *adaptor );
132 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
134 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
135 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
136 mEnvironmentOptions->SetLogFunction( logFunction );
137 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
139 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
142 GetDataStoragePath( path );
143 mPlatformAbstraction->SetDataStoragePath( path );
145 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
146 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
148 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
151 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
153 if( mEnvironmentOptions->PerformanceServerRequired() )
155 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
158 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
159 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
161 mCallbackManager = CallbackManager::New();
163 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
165 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
167 mGraphics = &( graphicsFactory.Create() );
168 mGraphics->Initialize( mEnvironmentOptions );
170 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
172 // This will only be created once
173 eglGraphics->Create();
175 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
176 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
177 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
179 mCore = Integration::Core::New( *this,
180 *mPlatformAbstraction,
183 eglContextHelperImpl,
184 dataRetentionPolicy ,
185 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
186 mGraphics->GetDepthBufferRequired(),
187 mGraphics->GetStencilBufferRequired() );
189 defaultWindow->SetAdaptor( Get() );
191 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
193 mWindowCreatedSignal.Emit( defaultSceneHolder );
195 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
196 if( 0u < timeInterval )
198 mObjectProfiler = new ObjectProfiler( timeInterval );
201 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
203 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
205 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
207 // Should be called after Core creation
208 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
210 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
212 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
214 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
216 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
218 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
220 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
222 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
224 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
226 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
228 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
230 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
232 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
234 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
236 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
238 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
240 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
242 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
244 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
246 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
248 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
250 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
252 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
254 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
256 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
258 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
260 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
262 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
264 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
266 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
268 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
270 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
272 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
274 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
276 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
278 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
280 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
282 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
285 // Set max texture size
286 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
288 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
291 std::string systemCachePath = GetSystemCachePath();
292 if ( ! systemCachePath.empty() )
294 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
295 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
296 if( stream.is_open() )
299 while( std::getline( stream, line ) )
301 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
302 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
303 if( '#' == *( line.cbegin() ) || line == "" )
308 std::istringstream stream( line );
309 std::string environmentVariableName, environmentVariableValue;
310 std::getline(stream, environmentVariableName, ' ');
311 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
313 std::getline(stream, environmentVariableValue);
314 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
315 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
321 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
328 // Ensure stop status
331 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
332 gThreadLocalAdaptor = NULL;
334 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
336 (*iter)->OnDestroy();
339 // Clear out all the handles to Windows
342 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
343 delete mObjectProfiler;
347 delete mDisplayConnection;
348 delete mPlatformAbstraction;
349 delete mCallbackManager;
350 delete mPerformanceInterface;
352 mGraphics->Destroy();
354 // uninstall it on this thread (main actor thread)
355 Dali::Integration::Log::UninstallLogFunction();
357 // Delete environment options if we own it
358 if( mEnvironmentOptionsOwned )
360 delete mEnvironmentOptions;
364 void Adaptor::Start()
366 // It doesn't support restart after stop at this moment to support restarting, need more testing
367 if( READY != mState )
374 SetupSystemInformation();
376 // Start the callback manager
377 mCallbackManager->Start();
379 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
381 unsigned int dpiHor, dpiVer;
384 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
386 // set the DPI value for font rendering
387 FontClient fontClient = FontClient::Get();
388 fontClient.SetDpi( dpiHor, dpiVer );
390 // Initialize the thread controller
391 mThreadController->Initialize();
393 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
395 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
396 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
397 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
399 std::string systemCachePath = GetSystemCachePath();
400 if( ! systemCachePath.empty() )
402 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
405 printf("Error creating directory!n");
409 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
410 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
411 if( configFile.is_open() )
413 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
418 ProcessCoreEvents(); // Ensure any startup messages are processed.
420 // Initialize the image loader plugin
421 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
423 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
429 // Dali::Internal::Adaptor::Adaptor::Pause
430 void Adaptor::Pause()
432 // Only pause the adaptor if we're actually running.
433 if( RUNNING == mState )
435 // Inform observers that we are about to be paused.
436 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
441 // Pause all windows event handlers when adaptor paused
442 for( auto window : mWindows )
447 mThreadController->Pause();
450 // Ensure any messages queued during pause callbacks are processed by doing another update.
453 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
457 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
461 // Dali::Internal::Adaptor::Adaptor::Resume
462 void Adaptor::Resume()
464 // Only resume the adaptor if we are in the suspended state.
465 if( PAUSED == mState )
469 // Reset the event handlers when adaptor resumed
470 for( auto window : mWindows )
475 // Inform observers that we have resumed.
476 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
481 // Trigger processing of events queued up while paused
482 mCore->ProcessEvents();
484 // Do at end to ensure our first update/render after resumption includes the processed messages as well
485 mThreadController->Resume();
487 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
491 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
497 if( RUNNING == mState ||
499 PAUSED_WHILE_HIDDEN == mState )
501 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
506 mThreadController->Stop();
508 // Delete the TTS player
509 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
513 mTtsPlayers[i].Reset();
517 // Destroy the image loader plugin
518 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
520 delete mNotificationTrigger;
521 mNotificationTrigger = NULL;
523 mCallbackManager->Stop();
527 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
531 void Adaptor::ContextLost()
533 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
536 void Adaptor::ContextRegained()
538 // Inform core, so that texture resources can be reloaded
539 mCore->RecoverFromContextLoss();
541 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
544 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
546 Integration::Point convertedPoint( point );
547 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
550 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
552 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
553 mWindows.front()->FeedWheelEvent( event );
556 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
558 Integration::KeyEvent convertedEvent( keyEvent );
559 mWindows.front()->FeedKeyEvent( convertedEvent );
562 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
564 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
565 for( auto windowPtr : mWindows )
567 if( windowPtr == windowImpl ) // the window is not deleted
569 mResizedSignal.Emit( mAdaptor );
571 windowImpl->SetSurface( &newSurface );
573 // Flush the event queue to give the update-render thread chance
574 // to start processing messages for new camera setup etc as soon as possible
577 // This method blocks until the render thread has completed the replace.
578 mThreadController->ReplaceSurface( &newSurface );
584 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
586 // Flush the event queue to give the update-render thread chance
587 // to start processing messages for new camera setup etc as soon as possible
590 // This method blocks until the render thread has finished rendering the current surface.
591 mThreadController->DeleteSurface( &surface );
594 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
596 return *mWindows.front()->GetSurface();
599 void Adaptor::ReleaseSurfaceLock()
601 mWindows.front()->GetSurface()->ReleaseLock();
604 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
606 if( !mTtsPlayers[mode] )
608 // Create the TTS player when it needed, because it can reduce launching time.
609 mTtsPlayers[mode] = TtsPlayer::New(mode);
612 return mTtsPlayers[mode];
615 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
617 bool idleAdded(false);
619 // Only add an idle if the Adaptor is actually running
620 if( RUNNING == mState || READY == mState || forceAdd )
622 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
628 void Adaptor::RemoveIdle( CallbackBase* callback )
630 mCallbackManager->RemoveIdleCallback( callback );
633 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
635 mThreadController->SetPreRenderCallback( callback );
638 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
640 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
641 windowImpl.SetAdaptor( Get() );
643 // Add the new Window to the container - the order is not important
644 mWindows.push_back( &windowImpl );
646 mWindowCreatedSignal.Emit( childWindow );
651 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
653 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
654 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
656 if( *iter == &windowImpl )
658 mWindows.erase( iter );
666 bool Adaptor::RemoveWindow( std::string childWindowName )
668 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
670 if( ( *iter )->GetName() == childWindowName )
672 mWindows.erase( iter );
680 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
682 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
684 if( ( *iter )->GetId() == childWindow->GetId() )
686 mWindows.erase( iter );
694 Dali::Adaptor& Adaptor::Get()
696 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
697 return gThreadLocalAdaptor->mAdaptor;
700 bool Adaptor::IsAvailable()
702 return gThreadLocalAdaptor != NULL;
705 void Adaptor::SceneCreated()
707 mCore->SceneCreated();
710 Dali::Integration::Core& Adaptor::GetCore()
715 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
717 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
720 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
722 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
723 return *mDisplayConnection;
726 GraphicsInterface& Adaptor::GetGraphicsInterface()
728 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
732 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
734 return *mPlatformAbstraction;
737 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
739 return *mNotificationTrigger;
742 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
744 return mTriggerEventFactory;
747 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
749 return mSocketFactory;
752 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
754 if( !mWindows.empty() )
756 return mWindows.front()->GetSurface();
762 TraceInterface& Adaptor::GetKernelTraceInterface()
764 return mKernelTracer;
767 TraceInterface& Adaptor::GetSystemTraceInterface()
769 return mSystemTracer;
772 PerformanceInterface* Adaptor::GetPerformanceInterface()
774 return mPerformanceInterface;
777 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
779 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
780 return *mPlatformAbstraction;
783 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
785 if( mTtsPlayers[mode] )
787 mTtsPlayers[mode].Reset();
791 Any Adaptor::GetNativeWindowHandle()
793 return mWindows.front()->GetNativeHandle();
796 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
798 Any nativeWindowHandle;
800 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
802 for( auto sceneHolder : mWindows )
804 if ( scene == sceneHolder->GetScene() )
806 nativeWindowHandle = sceneHolder->GetNativeHandle();
811 return nativeWindowHandle;
814 Any Adaptor::GetGraphicsDisplay()
820 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
822 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
823 display = eglImpl.GetDisplay();
829 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
831 mUseRemoteSurface = useRemoteSurface;
834 void Adaptor::AddObserver( LifeCycleObserver& observer )
836 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
838 if ( match == mObservers.end() )
840 mObservers.push_back( &observer );
844 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
846 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
848 if ( match != mObservers.end() )
850 mObservers.erase( match );
854 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
858 mCore->QueueEvent(event);
862 void Adaptor::ProcessCoreEvents()
866 if( mPerformanceInterface )
868 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
871 mCore->ProcessEvents();
873 if( mPerformanceInterface )
875 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
880 void Adaptor::RequestUpdate( bool forceUpdate )
886 mThreadController->RequestUpdate();
890 case PAUSED_WHILE_HIDDEN:
892 // When Dali applications are partially visible behind the lock-screen,
893 // the indicator must be updated (therefore allow updates in the PAUSED state)
896 mThreadController->RequestUpdateOnce();
908 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
910 // Only request a notification if the Adaptor is actually running
911 // and we haven't installed the idle notification
912 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
914 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
918 void Adaptor::OnWindowShown()
920 if( PAUSED_WHILE_HIDDEN == mState )
922 // Adaptor can now be resumed
927 // Force a render task
930 else if( RUNNING == mState )
932 // Force a render task
935 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
939 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
943 void Adaptor::OnWindowHidden()
945 if( RUNNING == mState || READY == mState )
947 bool allWindowsHidden = true;
949 for( auto window : mWindows )
951 if ( window->IsVisible() )
953 allWindowsHidden = false;
958 // Only pause the adaptor when all the windows are hidden
959 if( allWindowsHidden )
961 if( mState == RUNNING )
965 // Adaptor cannot be resumed until any window is shown
966 mState = PAUSED_WHILE_HIDDEN;
968 else // mState is READY
970 // Pause the adaptor after the state gets RUNNING
971 mState = PAUSED_WHILE_INITIALIZING;
976 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
981 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
985 // Dali::Internal::Adaptor::Adaptor::OnDamaged
986 void Adaptor::OnDamaged( const DamageArea& area )
988 // This is needed for the case where Dali window is partially obscured
989 RequestUpdate( false );
992 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
994 mResizedSignal.Emit( mAdaptor );
997 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
999 // Flush the event queue to give the update-render thread chance
1000 // to start processing messages for new camera setup etc as soon as possible
1001 ProcessCoreEvents();
1003 mThreadController->ResizeSurface();
1006 void Adaptor::NotifySceneCreated()
1008 GetCore().SceneCreated();
1010 // Flush the event queue to give the update-render thread chance
1011 // to start processing messages for new camera setup etc as soon as possible
1012 ProcessCoreEvents();
1014 // Start thread controller after the scene has been created
1015 mThreadController->Start();
1017 // Process after surface is created (registering to remote surface provider if required)
1018 SurfaceInitialized();
1020 if( mState != PAUSED_WHILE_INITIALIZING )
1024 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1032 mState = PAUSED_WHILE_HIDDEN;
1034 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1038 void Adaptor::NotifyLanguageChanged()
1040 mLanguageChangedSignal.Emit( mAdaptor );
1043 void Adaptor::RenderOnce()
1045 RequestUpdateOnce();
1048 const LogFactoryInterface& Adaptor::GetLogFactory()
1050 return *mEnvironmentOptions;
1053 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1055 GetCore().RegisterProcessor(processor);
1058 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1060 GetCore().UnregisterProcessor(processor);
1063 void Adaptor::RequestUpdateOnce()
1065 if( mThreadController )
1067 mThreadController->RequestUpdateOnce();
1071 bool Adaptor::ProcessCoreEventsFromIdle()
1073 ProcessCoreEvents();
1075 // the idle handle automatically un-installs itself
1076 mNotificationOnIdleInstalled = false;
1081 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1083 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1085 for( auto window : mWindows )
1087 if ( scene == window->GetScene() )
1096 Dali::WindowContainer Adaptor::GetWindows() const
1098 Dali::WindowContainer windows;
1100 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1102 // Downcast to Dali::Window
1103 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1106 windows.push_back( window );
1113 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1115 Dali::SceneHolderList sceneHolderList;
1117 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1119 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1122 return sceneHolderList;
1125 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1127 mLanguageChangedSignal(),
1128 mWindowCreatedSignal(),
1129 mAdaptor( adaptor ),
1132 mThreadController( nullptr ),
1133 mGraphics( nullptr ),
1134 mDisplayConnection( nullptr ),
1136 mPlatformAbstraction( nullptr ),
1137 mCallbackManager( nullptr ),
1138 mNotificationOnIdleInstalled( false ),
1139 mNotificationTrigger( nullptr ),
1140 mDaliFeedbackPlugin(),
1141 mFeedbackController( nullptr ),
1144 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1145 mPerformanceInterface( nullptr ),
1148 mTriggerEventFactory(),
1149 mObjectProfiler( nullptr ),
1151 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1152 mUseRemoteSurface( false )
1154 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1155 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1157 gThreadLocalAdaptor = this;
1160 void Adaptor::SetRootLayoutDirection( std::string locale )
1162 Dali::Stage stage = Dali::Stage::GetCurrent();
1164 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1165 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1168 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1170 bool idleAdded( false );
1172 // Only add an idle if the Adaptor is actually running
1173 if( RUNNING == mState || READY == mState || forceAdd )
1175 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1181 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1183 mCallbackManager->RemoveIdleEntererCallback( callback );
1186 } // namespace Adaptor
1188 } // namespace Internal