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>
44 #include <dali/internal/adaptor/common/thread-controller-interface.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-stream.h>
73 using Dali::TextAbstraction::FontClient;
75 extern std::string GetSystemCachePath();
88 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
89 } // unnamed namespace
91 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
93 Dali::Adaptor* adaptor = new Dali::Adaptor;
94 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
95 adaptor->mImpl = impl;
97 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
98 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
100 impl->Initialize( graphicsFactory, configuration );
101 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
106 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
108 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
109 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
110 windowImpl.SetAdaptor( *adaptor );
114 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
116 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
117 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
118 adaptor->mImpl = impl;
120 impl->Initialize( graphicsFactory, configuration );
125 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
127 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
128 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
129 windowImpl.SetAdaptor( *adaptor );
133 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
135 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
136 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
137 mEnvironmentOptions->SetLogFunction( logFunction );
138 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
140 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
143 GetDataStoragePath( path );
144 mPlatformAbstraction->SetDataStoragePath( path );
146 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
147 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
149 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
152 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
154 if( mEnvironmentOptions->PerformanceServerRequired() )
156 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
159 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
160 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
162 mCallbackManager = CallbackManager::New();
164 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
166 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
168 mGraphics = &( graphicsFactory.Create() );
169 mGraphics->Initialize( mEnvironmentOptions );
171 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
173 // This will only be created once
174 eglGraphics->Create();
176 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
177 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
178 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
180 mCore = Integration::Core::New( *this,
181 *mPlatformAbstraction,
184 eglContextHelperImpl,
185 dataRetentionPolicy ,
186 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
187 mGraphics->GetDepthBufferRequired(),
188 mGraphics->GetStencilBufferRequired() );
190 defaultWindow->SetAdaptor( Get() );
192 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
194 mWindowCreatedSignal.Emit( defaultSceneHolder );
196 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
197 if( 0u < timeInterval )
199 mObjectProfiler = new ObjectProfiler( timeInterval );
202 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
204 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
206 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
208 // Should be called after Core creation
209 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
211 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
213 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
215 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
217 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
219 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
221 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
223 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
225 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
227 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
229 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
231 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
233 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
235 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
237 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
239 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
241 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
243 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
245 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
247 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
249 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
251 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
253 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
255 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
257 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
259 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
261 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
263 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
265 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
267 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
269 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
271 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
273 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
275 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
277 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
279 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
281 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
283 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
285 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
287 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
290 // Set max texture size
291 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
293 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
296 std::string systemCachePath = GetSystemCachePath();
297 if ( ! systemCachePath.empty() )
299 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
300 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
301 if( stream.is_open() )
304 while( std::getline( stream, line ) )
306 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
307 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
308 if( '#' == *( line.cbegin() ) || line == "" )
313 std::istringstream stream( line );
314 std::string environmentVariableName, environmentVariableValue;
315 std::getline(stream, environmentVariableName, ' ');
316 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
318 std::getline(stream, environmentVariableValue);
319 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
320 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
326 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
333 // Ensure stop status
336 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
337 gThreadLocalAdaptor = NULL;
339 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
341 (*iter)->OnDestroy();
344 // Clear out all the handles to Windows
347 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
348 delete mObjectProfiler;
352 delete mDisplayConnection;
353 delete mPlatformAbstraction;
354 delete mCallbackManager;
355 delete mPerformanceInterface;
357 mGraphics->Destroy();
359 // uninstall it on this thread (main actor thread)
360 Dali::Integration::Log::UninstallLogFunction();
362 // Delete environment options if we own it
363 if( mEnvironmentOptionsOwned )
365 delete mEnvironmentOptions;
369 void Adaptor::Start()
371 // It doesn't support restart after stop at this moment to support restarting, need more testing
372 if( READY != mState )
379 SetupSystemInformation();
381 // Start the callback manager
382 mCallbackManager->Start();
384 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
386 unsigned int dpiHor, dpiVer;
389 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
391 // set the DPI value for font rendering
392 FontClient fontClient = FontClient::Get();
393 fontClient.SetDpi( dpiHor, dpiVer );
395 // Initialize the thread controller
396 mThreadController->Initialize();
398 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
400 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
401 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
402 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
404 std::string systemCachePath = GetSystemCachePath();
405 if( ! systemCachePath.empty() )
407 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
410 printf("Error creating directory!n");
414 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
415 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
416 if( configFile.is_open() )
418 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 mWindowCreatedSignal.Emit( childWindow );
656 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
658 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
659 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
661 if( *iter == &windowImpl )
663 mWindows.erase( iter );
671 bool Adaptor::RemoveWindow( std::string childWindowName )
673 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
675 if( ( *iter )->GetName() == childWindowName )
677 mWindows.erase( iter );
685 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
687 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
689 if( ( *iter )->GetId() == childWindow->GetId() )
691 mWindows.erase( iter );
699 Dali::Adaptor& Adaptor::Get()
701 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
702 return gThreadLocalAdaptor->mAdaptor;
705 bool Adaptor::IsAvailable()
707 return gThreadLocalAdaptor != NULL;
710 void Adaptor::SceneCreated()
712 mCore->SceneCreated();
715 Dali::Integration::Core& Adaptor::GetCore()
720 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
722 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
725 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
727 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
728 return *mDisplayConnection;
731 GraphicsInterface& Adaptor::GetGraphicsInterface()
733 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
737 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
739 return *mPlatformAbstraction;
742 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
744 return *mNotificationTrigger;
747 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
749 return mTriggerEventFactory;
752 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
754 return mSocketFactory;
757 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
759 if( !mWindows.empty() )
761 return mWindows.front()->GetSurface();
767 TraceInterface& Adaptor::GetKernelTraceInterface()
769 return mKernelTracer;
772 TraceInterface& Adaptor::GetSystemTraceInterface()
774 return mSystemTracer;
777 PerformanceInterface* Adaptor::GetPerformanceInterface()
779 return mPerformanceInterface;
782 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
784 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
785 return *mPlatformAbstraction;
788 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
790 if( mTtsPlayers[mode] )
792 mTtsPlayers[mode].Reset();
796 Any Adaptor::GetNativeWindowHandle()
798 return mWindows.front()->GetNativeHandle();
801 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
803 Any nativeWindowHandle;
805 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
807 for( auto sceneHolder : mWindows )
809 if ( scene == sceneHolder->GetScene() )
811 nativeWindowHandle = sceneHolder->GetNativeHandle();
816 return nativeWindowHandle;
819 Any Adaptor::GetGraphicsDisplay()
825 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
827 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
828 display = eglImpl.GetDisplay();
834 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
836 mUseRemoteSurface = useRemoteSurface;
839 void Adaptor::AddObserver( LifeCycleObserver& observer )
841 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
843 if ( match == mObservers.end() )
845 mObservers.push_back( &observer );
849 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
851 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
853 if ( match != mObservers.end() )
855 mObservers.erase( match );
859 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
863 mCore->QueueEvent(event);
867 void Adaptor::ProcessCoreEvents()
871 if( mPerformanceInterface )
873 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
876 mCore->ProcessEvents();
878 if( mPerformanceInterface )
880 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
885 void Adaptor::RequestUpdate( bool forceUpdate )
891 mThreadController->RequestUpdate();
895 case PAUSED_WHILE_HIDDEN:
899 // Update (and resource upload) without rendering
900 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
912 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
914 // Only request a notification if the Adaptor is actually running
915 // and we haven't installed the idle notification
916 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
918 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
922 void Adaptor::OnWindowShown()
924 if( PAUSED_WHILE_HIDDEN == mState )
926 // Adaptor can now be resumed
931 // Force a render task
934 else if( RUNNING == mState )
936 // Force a render task
939 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
943 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
947 void Adaptor::OnWindowHidden()
949 if( RUNNING == mState || READY == mState )
951 bool allWindowsHidden = true;
953 for( auto window : mWindows )
955 if ( window->IsVisible() )
957 allWindowsHidden = false;
962 // Only pause the adaptor when all the windows are hidden
963 if( allWindowsHidden )
965 if( mState == RUNNING )
969 // Adaptor cannot be resumed until any window is shown
970 mState = PAUSED_WHILE_HIDDEN;
972 else // mState is READY
974 // Pause the adaptor after the state gets RUNNING
975 mState = PAUSED_WHILE_INITIALIZING;
980 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
985 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
989 // Dali::Internal::Adaptor::Adaptor::OnDamaged
990 void Adaptor::OnDamaged( const DamageArea& area )
992 // This is needed for the case where Dali window is partially obscured
993 RequestUpdate( false );
996 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
998 mResizedSignal.Emit( mAdaptor );
1001 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1003 // Flush the event queue to give the update-render thread chance
1004 // to start processing messages for new camera setup etc as soon as possible
1005 ProcessCoreEvents();
1007 mThreadController->ResizeSurface();
1010 void Adaptor::NotifySceneCreated()
1012 GetCore().SceneCreated();
1014 // Flush the event queue to give the update-render thread chance
1015 // to start processing messages for new camera setup etc as soon as possible
1016 ProcessCoreEvents();
1018 // Start thread controller after the scene has been created
1019 mThreadController->Start();
1021 // Process after surface is created (registering to remote surface provider if required)
1022 SurfaceInitialized();
1024 if( mState != PAUSED_WHILE_INITIALIZING )
1028 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1036 mState = PAUSED_WHILE_HIDDEN;
1038 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1042 void Adaptor::NotifyLanguageChanged()
1044 mLanguageChangedSignal.Emit( mAdaptor );
1047 void Adaptor::RenderOnce()
1049 RequestUpdateOnce();
1052 const LogFactoryInterface& Adaptor::GetLogFactory()
1054 return *mEnvironmentOptions;
1057 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1059 GetCore().RegisterProcessor(processor);
1062 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1064 GetCore().UnregisterProcessor(processor);
1067 bool Adaptor::IsMultipleWindowSupported() const
1069 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
1070 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
1071 bool ret = eglImpl.IsSurfacelessContextSupported();
1075 void Adaptor::RequestUpdateOnce()
1077 if( mThreadController )
1079 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1083 bool Adaptor::ProcessCoreEventsFromIdle()
1085 ProcessCoreEvents();
1087 // the idle handle automatically un-installs itself
1088 mNotificationOnIdleInstalled = false;
1093 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1095 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1097 for( auto window : mWindows )
1099 if ( scene == window->GetScene() )
1108 Dali::WindowContainer Adaptor::GetWindows() const
1110 Dali::WindowContainer windows;
1112 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1114 // Downcast to Dali::Window
1115 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1118 windows.push_back( window );
1125 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1127 Dali::SceneHolderList sceneHolderList;
1129 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1131 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1134 return sceneHolderList;
1137 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1139 mLanguageChangedSignal(),
1140 mWindowCreatedSignal(),
1141 mAdaptor( adaptor ),
1144 mThreadController( nullptr ),
1145 mGraphics( nullptr ),
1146 mDisplayConnection( nullptr ),
1148 mPlatformAbstraction( nullptr ),
1149 mCallbackManager( nullptr ),
1150 mNotificationOnIdleInstalled( false ),
1151 mNotificationTrigger( nullptr ),
1152 mDaliFeedbackPlugin(),
1153 mFeedbackController( nullptr ),
1156 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1157 mPerformanceInterface( nullptr ),
1160 mTriggerEventFactory(),
1161 mObjectProfiler( nullptr ),
1163 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1164 mUseRemoteSurface( false )
1166 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1167 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1169 gThreadLocalAdaptor = this;
1172 void Adaptor::SetRootLayoutDirection( std::string locale )
1174 Dali::Stage stage = Dali::Stage::GetCurrent();
1176 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1177 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1180 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1182 bool idleAdded( false );
1184 // Only add an idle if the Adaptor is actually running
1185 if( RUNNING == mState || READY == mState || forceAdd )
1187 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1193 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1195 mCallbackManager->RemoveIdleEntererCallback( callback );
1198 } // namespace Adaptor
1200 } // namespace Internal