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(),
188 mGraphics->PartialUpdateAvailable() );
190 defaultWindow->SetAdaptor( Get() );
192 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( defaultWindow ) );
195 mWindowCreatedSignal.Emit( window );
198 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
199 if( 0u < timeInterval )
201 mObjectProfiler = new ObjectProfiler( timeInterval );
204 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
206 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
208 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
210 // Should be called after Core creation
211 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
213 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
215 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
217 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
219 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
221 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
223 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
225 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
227 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
229 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
231 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
233 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
235 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
237 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
239 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
241 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
243 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
245 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
247 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
249 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
251 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
253 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
255 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
257 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
259 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
261 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
263 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
265 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
267 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
269 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
271 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
273 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
275 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
277 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
279 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
281 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
283 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
285 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
288 // Set max texture size
289 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
291 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
294 std::string systemCachePath = GetSystemCachePath();
295 if ( ! systemCachePath.empty() )
297 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
298 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
299 if( stream.is_open() )
302 while( std::getline( stream, line ) )
304 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
305 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
306 if( '#' == *( line.cbegin() ) || line == "" )
311 std::istringstream stream( line );
312 std::string environmentVariableName, environmentVariableValue;
313 std::getline(stream, environmentVariableName, ' ');
314 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
316 std::getline(stream, environmentVariableValue);
317 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
318 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
324 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
331 // Ensure stop status
334 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
335 gThreadLocalAdaptor = NULL;
337 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
339 (*iter)->OnDestroy();
342 // Clear out all the handles to Windows
345 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
346 delete mObjectProfiler;
350 delete mDisplayConnection;
351 delete mPlatformAbstraction;
352 delete mCallbackManager;
353 delete mPerformanceInterface;
355 mGraphics->Destroy();
357 // uninstall it on this thread (main actor thread)
358 Dali::Integration::Log::UninstallLogFunction();
360 // Delete environment options if we own it
361 if( mEnvironmentOptionsOwned )
363 delete mEnvironmentOptions;
367 void Adaptor::Start()
369 // It doesn't support restart after stop at this moment to support restarting, need more testing
370 if( READY != mState )
377 SetupSystemInformation();
379 // Start the callback manager
380 mCallbackManager->Start();
382 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
384 unsigned int dpiHor, dpiVer;
387 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
389 // set the DPI value for font rendering
390 FontClient fontClient = FontClient::Get();
391 fontClient.SetDpi( dpiHor, dpiVer );
393 // Initialize the thread controller
394 mThreadController->Initialize();
396 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
398 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
399 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
400 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
402 std::string systemCachePath = GetSystemCachePath();
403 if( ! systemCachePath.empty() )
405 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
408 printf("Error creating directory!n");
412 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
413 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
414 if( configFile.is_open() )
416 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
421 ProcessCoreEvents(); // Ensure any startup messages are processed.
423 // Initialize the image loader plugin
424 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
426 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
432 // Dali::Internal::Adaptor::Adaptor::Pause
433 void Adaptor::Pause()
435 // Only pause the adaptor if we're actually running.
436 if( RUNNING == mState )
438 // Inform observers that we are about to be paused.
439 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
444 // Pause all windows event handlers when adaptor paused
445 for( auto window : mWindows )
450 mThreadController->Pause();
453 // Ensure any messages queued during pause callbacks are processed by doing another update.
456 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
460 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
464 // Dali::Internal::Adaptor::Adaptor::Resume
465 void Adaptor::Resume()
467 // Only resume the adaptor if we are in the suspended state.
468 if( PAUSED == mState )
472 // Reset the event handlers when adaptor resumed
473 for( auto window : mWindows )
478 // Inform observers that we have resumed.
479 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
484 // Trigger processing of events queued up while paused
485 mCore->ProcessEvents();
487 // Do at end to ensure our first update/render after resumption includes the processed messages as well
488 mThreadController->Resume();
490 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
494 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
500 if( RUNNING == mState ||
502 PAUSED_WHILE_HIDDEN == mState )
504 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
509 mThreadController->Stop();
511 // Delete the TTS player
512 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
516 mTtsPlayers[i].Reset();
520 // Destroy the image loader plugin
521 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
523 delete mNotificationTrigger;
524 mNotificationTrigger = NULL;
526 mCallbackManager->Stop();
530 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
534 void Adaptor::ContextLost()
536 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
539 void Adaptor::ContextRegained()
541 // Inform core, so that texture resources can be reloaded
542 mCore->RecoverFromContextLoss();
544 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
547 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
549 Integration::Point convertedPoint( point );
550 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
553 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
555 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
556 mWindows.front()->FeedWheelEvent( event );
559 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
561 Integration::KeyEvent convertedEvent( keyEvent );
562 mWindows.front()->FeedKeyEvent( convertedEvent );
565 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
567 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
568 for( auto windowPtr : mWindows )
570 if( windowPtr == windowImpl ) // the window is not deleted
572 mResizedSignal.Emit( mAdaptor );
574 windowImpl->SetSurface( &newSurface );
576 // Flush the event queue to give the update-render thread chance
577 // to start processing messages for new camera setup etc as soon as possible
580 // This method blocks until the render thread has completed the replace.
581 mThreadController->ReplaceSurface( &newSurface );
587 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
589 // Flush the event queue to give the update-render thread chance
590 // to start processing messages for new camera setup etc as soon as possible
593 // This method blocks until the render thread has finished rendering the current surface.
594 mThreadController->DeleteSurface( &surface );
597 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
599 return *mWindows.front()->GetSurface();
602 void Adaptor::ReleaseSurfaceLock()
604 mWindows.front()->GetSurface()->ReleaseLock();
607 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
609 if( !mTtsPlayers[mode] )
611 // Create the TTS player when it needed, because it can reduce launching time.
612 mTtsPlayers[mode] = TtsPlayer::New(mode);
615 return mTtsPlayers[mode];
618 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
620 bool idleAdded(false);
622 // Only add an idle if the Adaptor is actually running
623 if( RUNNING == mState || READY == mState || forceAdd )
625 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
631 void Adaptor::RemoveIdle( CallbackBase* callback )
633 mCallbackManager->RemoveIdleCallback( callback );
636 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
638 mThreadController->SetPreRenderCallback( callback );
641 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
643 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
644 windowImpl.SetAdaptor( Get() );
646 // Add the new Window to the container - the order is not important
647 mWindows.push_back( &windowImpl );
649 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
652 mWindowCreatedSignal.Emit( window );
658 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
660 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
661 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
663 if( *iter == &windowImpl )
665 mWindows.erase( iter );
673 bool Adaptor::RemoveWindow( std::string childWindowName )
675 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
677 if( ( *iter )->GetName() == childWindowName )
679 mWindows.erase( iter );
687 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
689 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
691 if( ( *iter )->GetId() == childWindow->GetId() )
693 mWindows.erase( iter );
701 Dali::Adaptor& Adaptor::Get()
703 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
704 return gThreadLocalAdaptor->mAdaptor;
707 bool Adaptor::IsAvailable()
709 return gThreadLocalAdaptor != NULL;
712 void Adaptor::SceneCreated()
714 mCore->SceneCreated();
717 Dali::Integration::Core& Adaptor::GetCore()
722 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
724 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
727 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
729 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
730 return *mDisplayConnection;
733 GraphicsInterface& Adaptor::GetGraphicsInterface()
735 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
739 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
741 return *mPlatformAbstraction;
744 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
746 return *mNotificationTrigger;
749 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
751 return mTriggerEventFactory;
754 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
756 return mSocketFactory;
759 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
761 if( !mWindows.empty() )
763 return mWindows.front()->GetSurface();
769 TraceInterface& Adaptor::GetKernelTraceInterface()
771 return mKernelTracer;
774 TraceInterface& Adaptor::GetSystemTraceInterface()
776 return mSystemTracer;
779 PerformanceInterface* Adaptor::GetPerformanceInterface()
781 return mPerformanceInterface;
784 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
786 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
787 return *mPlatformAbstraction;
790 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
792 if( mTtsPlayers[mode] )
794 mTtsPlayers[mode].Reset();
798 Any Adaptor::GetNativeWindowHandle()
800 return mWindows.front()->GetNativeHandle();
803 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
805 Any nativeWindowHandle;
807 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
809 for( auto sceneHolder : mWindows )
811 if ( scene == sceneHolder->GetScene() )
813 nativeWindowHandle = sceneHolder->GetNativeHandle();
818 return nativeWindowHandle;
821 Any Adaptor::GetGraphicsDisplay()
827 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
829 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
830 display = eglImpl.GetDisplay();
836 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
838 mUseRemoteSurface = useRemoteSurface;
841 void Adaptor::AddObserver( LifeCycleObserver& observer )
843 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
845 if ( match == mObservers.end() )
847 mObservers.push_back( &observer );
851 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
853 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
855 if ( match != mObservers.end() )
857 mObservers.erase( match );
861 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
865 mCore->QueueEvent(event);
869 void Adaptor::ProcessCoreEvents()
873 if( mPerformanceInterface )
875 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
878 mCore->ProcessEvents();
880 if( mPerformanceInterface )
882 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
887 void Adaptor::RequestUpdate( bool forceUpdate )
893 mThreadController->RequestUpdate();
897 case PAUSED_WHILE_HIDDEN:
899 // When Dali applications are partially visible behind the lock-screen,
900 // the indicator must be updated (therefore allow updates in the PAUSED state)
903 mThreadController->RequestUpdateOnce();
915 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
917 // Only request a notification if the Adaptor is actually running
918 // and we haven't installed the idle notification
919 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
921 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
925 void Adaptor::OnWindowShown()
927 if( PAUSED_WHILE_HIDDEN == mState )
929 // Adaptor can now be resumed
934 // Force a render task
937 else if( RUNNING == mState )
939 // Force a render task
942 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
946 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
950 void Adaptor::OnWindowHidden()
952 if( RUNNING == mState || READY == mState )
954 bool allWindowsHidden = true;
956 for( auto window : mWindows )
958 if ( window->IsVisible() )
960 allWindowsHidden = false;
965 // Only pause the adaptor when all the windows are hidden
966 if( allWindowsHidden )
968 if( mState == RUNNING )
972 // Adaptor cannot be resumed until any window is shown
973 mState = PAUSED_WHILE_HIDDEN;
975 else // mState is READY
977 // Pause the adaptor after the state gets RUNNING
978 mState = PAUSED_WHILE_INITIALIZING;
983 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
988 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
992 // Dali::Internal::Adaptor::Adaptor::OnDamaged
993 void Adaptor::OnDamaged( const DamageArea& area )
995 // This is needed for the case where Dali window is partially obscured
996 RequestUpdate( false );
999 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1001 mResizedSignal.Emit( mAdaptor );
1004 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1006 // Flush the event queue to give the update-render thread chance
1007 // to start processing messages for new camera setup etc as soon as possible
1008 ProcessCoreEvents();
1010 mThreadController->ResizeSurface();
1013 void Adaptor::NotifySceneCreated()
1015 GetCore().SceneCreated();
1017 // Flush the event queue to give the update-render thread chance
1018 // to start processing messages for new camera setup etc as soon as possible
1019 ProcessCoreEvents();
1021 // Start thread controller after the scene has been created
1022 mThreadController->Start();
1024 // Process after surface is created (registering to remote surface provider if required)
1025 SurfaceInitialized();
1027 if( mState != PAUSED_WHILE_INITIALIZING )
1031 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1039 mState = PAUSED_WHILE_HIDDEN;
1041 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1045 void Adaptor::NotifyLanguageChanged()
1047 mLanguageChangedSignal.Emit( mAdaptor );
1050 void Adaptor::RenderOnce()
1052 RequestUpdateOnce();
1055 const LogFactoryInterface& Adaptor::GetLogFactory()
1057 return *mEnvironmentOptions;
1060 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1062 GetCore().RegisterProcessor(processor);
1065 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1067 GetCore().UnregisterProcessor(processor);
1070 void Adaptor::RequestUpdateOnce()
1072 if( mThreadController )
1074 mThreadController->RequestUpdateOnce();
1078 bool Adaptor::ProcessCoreEventsFromIdle()
1080 ProcessCoreEvents();
1082 // the idle handle automatically un-installs itself
1083 mNotificationOnIdleInstalled = false;
1088 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1090 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1092 for( auto window : mWindows )
1094 if ( scene == window->GetScene() )
1103 Dali::WindowContainer Adaptor::GetWindows() const
1105 Dali::WindowContainer windows;
1107 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1109 // Downcast to Dali::Window
1110 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1113 windows.push_back( window );
1120 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1122 mLanguageChangedSignal(),
1123 mWindowCreatedSignal(),
1124 mAdaptor( adaptor ),
1127 mThreadController( nullptr ),
1128 mGraphics( nullptr ),
1129 mDisplayConnection( nullptr ),
1131 mPlatformAbstraction( nullptr ),
1132 mCallbackManager( nullptr ),
1133 mNotificationOnIdleInstalled( false ),
1134 mNotificationTrigger( nullptr ),
1135 mDaliFeedbackPlugin(),
1136 mFeedbackController( nullptr ),
1139 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1140 mPerformanceInterface( nullptr ),
1143 mTriggerEventFactory(),
1144 mObjectProfiler( nullptr ),
1146 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1147 mUseRemoteSurface( false )
1149 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1150 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1152 gThreadLocalAdaptor = this;
1155 void Adaptor::SetRootLayoutDirection( std::string locale )
1157 Dali::Stage stage = Dali::Stage::GetCurrent();
1159 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1160 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1163 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1165 bool idleAdded( false );
1167 // Only add an idle if the Adaptor is actually running
1168 if( RUNNING == mState || READY == mState || forceAdd )
1170 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1176 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1178 mCallbackManager->RemoveIdleEntererCallback( callback );
1181 } // namespace Adaptor
1183 } // namespace Internal