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(),
189 mGraphics->PartialUpdateAvailable() );
191 defaultWindow->SetAdaptor( Get() );
193 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
195 mWindowCreatedSignal.Emit( defaultSceneHolder );
197 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
198 if( 0u < timeInterval )
200 mObjectProfiler = new ObjectProfiler( timeInterval );
203 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
205 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
207 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
209 // Should be called after Core creation
210 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
212 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
214 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
216 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
218 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
220 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
222 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
224 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
226 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
228 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
230 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
232 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
234 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
236 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
238 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
240 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
242 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
244 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
246 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
248 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
250 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
252 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
254 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
256 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
258 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
260 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
262 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
264 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
266 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
268 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
270 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
272 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
274 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
276 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
278 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
280 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
282 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
284 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
286 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
288 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
291 // Set max texture size
292 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
294 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
297 std::string systemCachePath = GetSystemCachePath();
298 if ( ! systemCachePath.empty() )
300 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
301 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
302 if( stream.is_open() )
305 while( std::getline( stream, line ) )
307 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
308 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
309 if( '#' == *( line.cbegin() ) || line == "" )
314 std::istringstream stream( line );
315 std::string environmentVariableName, environmentVariableValue;
316 std::getline(stream, environmentVariableName, ' ');
317 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
319 std::getline(stream, environmentVariableValue);
320 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
321 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
327 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
334 // Ensure stop status
337 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
338 gThreadLocalAdaptor = NULL;
340 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
342 (*iter)->OnDestroy();
345 // Clear out all the handles to Windows
348 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
349 delete mObjectProfiler;
353 delete mDisplayConnection;
354 delete mPlatformAbstraction;
355 delete mCallbackManager;
356 delete mPerformanceInterface;
358 mGraphics->Destroy();
360 // uninstall it on this thread (main actor thread)
361 Dali::Integration::Log::UninstallLogFunction();
363 // Delete environment options if we own it
364 if( mEnvironmentOptionsOwned )
366 delete mEnvironmentOptions;
370 void Adaptor::Start()
372 // It doesn't support restart after stop at this moment to support restarting, need more testing
373 if( READY != mState )
380 SetupSystemInformation();
382 // Start the callback manager
383 mCallbackManager->Start();
385 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
387 unsigned int dpiHor, dpiVer;
390 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
392 // set the DPI value for font rendering
393 FontClient fontClient = FontClient::Get();
394 fontClient.SetDpi( dpiHor, dpiVer );
396 // Initialize the thread controller
397 mThreadController->Initialize();
399 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
401 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
402 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
403 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
405 std::string systemCachePath = GetSystemCachePath();
406 if( ! systemCachePath.empty() )
408 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
411 printf("Error creating directory!n");
415 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
416 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
417 if( configFile.is_open() )
419 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
424 ProcessCoreEvents(); // Ensure any startup messages are processed.
426 // Initialize the image loader plugin
427 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
429 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
435 // Dali::Internal::Adaptor::Adaptor::Pause
436 void Adaptor::Pause()
438 // Only pause the adaptor if we're actually running.
439 if( RUNNING == mState )
441 // Inform observers that we are about to be paused.
442 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
447 // Pause all windows event handlers when adaptor paused
448 for( auto window : mWindows )
453 mThreadController->Pause();
456 // Ensure any messages queued during pause callbacks are processed by doing another update.
459 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
463 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
467 // Dali::Internal::Adaptor::Adaptor::Resume
468 void Adaptor::Resume()
470 // Only resume the adaptor if we are in the suspended state.
471 if( PAUSED == mState )
475 // Reset the event handlers when adaptor resumed
476 for( auto window : mWindows )
481 // Inform observers that we have resumed.
482 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
487 // Trigger processing of events queued up while paused
488 mCore->ProcessEvents();
490 // Do at end to ensure our first update/render after resumption includes the processed messages as well
491 mThreadController->Resume();
493 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
497 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
503 if( RUNNING == mState ||
505 PAUSED_WHILE_HIDDEN == mState )
507 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
512 mThreadController->Stop();
514 // Delete the TTS player
515 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
519 mTtsPlayers[i].Reset();
523 // Destroy the image loader plugin
524 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
526 delete mNotificationTrigger;
527 mNotificationTrigger = NULL;
529 mCallbackManager->Stop();
533 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
537 void Adaptor::ContextLost()
539 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
542 void Adaptor::ContextRegained()
544 // Inform core, so that texture resources can be reloaded
545 mCore->RecoverFromContextLoss();
547 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
550 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
552 Integration::Point convertedPoint( point );
553 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
556 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
558 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
559 mWindows.front()->FeedWheelEvent( event );
562 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
564 Integration::KeyEvent convertedEvent( keyEvent );
565 mWindows.front()->FeedKeyEvent( convertedEvent );
568 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
570 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
571 for( auto windowPtr : mWindows )
573 if( windowPtr == windowImpl ) // the window is not deleted
575 mResizedSignal.Emit( mAdaptor );
577 windowImpl->SetSurface( &newSurface );
579 // Flush the event queue to give the update-render thread chance
580 // to start processing messages for new camera setup etc as soon as possible
583 // This method blocks until the render thread has completed the replace.
584 mThreadController->ReplaceSurface( &newSurface );
590 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
592 // Flush the event queue to give the update-render thread chance
593 // to start processing messages for new camera setup etc as soon as possible
596 // This method blocks until the render thread has finished rendering the current surface.
597 mThreadController->DeleteSurface( &surface );
600 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
602 return *mWindows.front()->GetSurface();
605 void Adaptor::ReleaseSurfaceLock()
607 mWindows.front()->GetSurface()->ReleaseLock();
610 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
612 if( !mTtsPlayers[mode] )
614 // Create the TTS player when it needed, because it can reduce launching time.
615 mTtsPlayers[mode] = TtsPlayer::New(mode);
618 return mTtsPlayers[mode];
621 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
623 bool idleAdded(false);
625 // Only add an idle if the Adaptor is actually running
626 if( RUNNING == mState || READY == mState || forceAdd )
628 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
634 void Adaptor::RemoveIdle( CallbackBase* callback )
636 mCallbackManager->RemoveIdleCallback( callback );
639 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
641 mThreadController->SetPreRenderCallback( callback );
644 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
646 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
647 windowImpl.SetAdaptor( Get() );
649 // Add the new Window to the container - the order is not important
650 mWindows.push_back( &windowImpl );
652 mWindowCreatedSignal.Emit( childWindow );
657 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
659 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
660 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
662 if( *iter == &windowImpl )
664 mWindows.erase( iter );
672 bool Adaptor::RemoveWindow( std::string childWindowName )
674 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
676 if( ( *iter )->GetName() == childWindowName )
678 mWindows.erase( iter );
686 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
688 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
690 if( ( *iter )->GetId() == childWindow->GetId() )
692 mWindows.erase( iter );
700 Dali::Adaptor& Adaptor::Get()
702 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
703 return gThreadLocalAdaptor->mAdaptor;
706 bool Adaptor::IsAvailable()
708 return gThreadLocalAdaptor != NULL;
711 void Adaptor::SceneCreated()
713 mCore->SceneCreated();
716 Dali::Integration::Core& Adaptor::GetCore()
721 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
723 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
726 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
728 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
729 return *mDisplayConnection;
732 GraphicsInterface& Adaptor::GetGraphicsInterface()
734 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
738 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
740 return *mPlatformAbstraction;
743 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
745 return *mNotificationTrigger;
748 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
750 return mTriggerEventFactory;
753 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
755 return mSocketFactory;
758 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
760 if( !mWindows.empty() )
762 return mWindows.front()->GetSurface();
768 TraceInterface& Adaptor::GetKernelTraceInterface()
770 return mKernelTracer;
773 TraceInterface& Adaptor::GetSystemTraceInterface()
775 return mSystemTracer;
778 PerformanceInterface* Adaptor::GetPerformanceInterface()
780 return mPerformanceInterface;
783 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
785 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
786 return *mPlatformAbstraction;
789 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
791 if( mTtsPlayers[mode] )
793 mTtsPlayers[mode].Reset();
797 Any Adaptor::GetNativeWindowHandle()
799 return mWindows.front()->GetNativeHandle();
802 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
804 Any nativeWindowHandle;
806 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
808 for( auto sceneHolder : mWindows )
810 if ( scene == sceneHolder->GetScene() )
812 nativeWindowHandle = sceneHolder->GetNativeHandle();
817 return nativeWindowHandle;
820 Any Adaptor::GetGraphicsDisplay()
826 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
828 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
829 display = eglImpl.GetDisplay();
835 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
837 mUseRemoteSurface = useRemoteSurface;
840 void Adaptor::AddObserver( LifeCycleObserver& observer )
842 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
844 if ( match == mObservers.end() )
846 mObservers.push_back( &observer );
850 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
852 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
854 if ( match != mObservers.end() )
856 mObservers.erase( match );
860 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
864 mCore->QueueEvent(event);
868 void Adaptor::ProcessCoreEvents()
872 if( mPerformanceInterface )
874 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
877 mCore->ProcessEvents();
879 if( mPerformanceInterface )
881 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
886 void Adaptor::RequestUpdate( bool forceUpdate )
892 mThreadController->RequestUpdate();
896 case PAUSED_WHILE_HIDDEN:
900 // Update (and resource upload) without rendering
901 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
913 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
915 // Only request a notification if the Adaptor is actually running
916 // and we haven't installed the idle notification
917 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
919 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
923 void Adaptor::OnWindowShown()
925 if( PAUSED_WHILE_HIDDEN == mState )
927 // Adaptor can now be resumed
932 // Force a render task
935 else if( RUNNING == mState )
937 // Force a render task
940 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
944 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
948 void Adaptor::OnWindowHidden()
950 if( RUNNING == mState || READY == mState )
952 bool allWindowsHidden = true;
954 for( auto window : mWindows )
956 if ( window->IsVisible() )
958 allWindowsHidden = false;
963 // Only pause the adaptor when all the windows are hidden
964 if( allWindowsHidden )
966 if( mState == RUNNING )
970 // Adaptor cannot be resumed until any window is shown
971 mState = PAUSED_WHILE_HIDDEN;
973 else // mState is READY
975 // Pause the adaptor after the state gets RUNNING
976 mState = PAUSED_WHILE_INITIALIZING;
981 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
986 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
990 // Dali::Internal::Adaptor::Adaptor::OnDamaged
991 void Adaptor::OnDamaged( const DamageArea& area )
993 // This is needed for the case where Dali window is partially obscured
994 RequestUpdate( false );
997 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
999 mResizedSignal.Emit( mAdaptor );
1002 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1004 // Flush the event queue to give the update-render thread chance
1005 // to start processing messages for new camera setup etc as soon as possible
1006 ProcessCoreEvents();
1008 mThreadController->ResizeSurface();
1011 void Adaptor::NotifySceneCreated()
1013 GetCore().SceneCreated();
1015 // Flush the event queue to give the update-render thread chance
1016 // to start processing messages for new camera setup etc as soon as possible
1017 ProcessCoreEvents();
1019 // Start thread controller after the scene has been created
1020 mThreadController->Start();
1022 // Process after surface is created (registering to remote surface provider if required)
1023 SurfaceInitialized();
1025 if( mState != PAUSED_WHILE_INITIALIZING )
1029 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1037 mState = PAUSED_WHILE_HIDDEN;
1039 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1043 void Adaptor::NotifyLanguageChanged()
1045 mLanguageChangedSignal.Emit( mAdaptor );
1048 void Adaptor::RenderOnce()
1050 RequestUpdateOnce();
1053 const LogFactoryInterface& Adaptor::GetLogFactory()
1055 return *mEnvironmentOptions;
1058 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1060 GetCore().RegisterProcessor(processor);
1063 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1065 GetCore().UnregisterProcessor(processor);
1068 bool Adaptor::IsMultipleWindowSupported() const
1070 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
1071 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
1072 bool ret = eglImpl.IsSurfacelessContextSupported();
1076 void Adaptor::RequestUpdateOnce()
1078 if( mThreadController )
1080 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1084 bool Adaptor::ProcessCoreEventsFromIdle()
1086 ProcessCoreEvents();
1088 // the idle handle automatically un-installs itself
1089 mNotificationOnIdleInstalled = false;
1094 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1096 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1098 for( auto window : mWindows )
1100 if ( scene == window->GetScene() )
1109 Dali::WindowContainer Adaptor::GetWindows() const
1111 Dali::WindowContainer windows;
1113 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1115 // Downcast to Dali::Window
1116 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1119 windows.push_back( window );
1126 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1128 Dali::SceneHolderList sceneHolderList;
1130 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1132 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1135 return sceneHolderList;
1138 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1140 mLanguageChangedSignal(),
1141 mWindowCreatedSignal(),
1142 mAdaptor( adaptor ),
1145 mThreadController( nullptr ),
1146 mGraphics( nullptr ),
1147 mDisplayConnection( nullptr ),
1149 mPlatformAbstraction( nullptr ),
1150 mCallbackManager( nullptr ),
1151 mNotificationOnIdleInstalled( false ),
1152 mNotificationTrigger( nullptr ),
1153 mDaliFeedbackPlugin(),
1154 mFeedbackController( nullptr ),
1157 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1158 mPerformanceInterface( nullptr ),
1161 mTriggerEventFactory(),
1162 mObjectProfiler( nullptr ),
1164 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1165 mUseRemoteSurface( false )
1167 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1168 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1170 gThreadLocalAdaptor = this;
1173 void Adaptor::SetRootLayoutDirection( std::string locale )
1175 Dali::Stage stage = Dali::Stage::GetCurrent();
1177 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1178 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1181 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1183 bool idleAdded( false );
1185 // Only add an idle if the Adaptor is actually running
1186 if( RUNNING == mState || READY == mState || forceAdd )
1188 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1194 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1196 mCallbackManager->RemoveIdleEntererCallback( callback );
1199 } // namespace Adaptor
1201 } // namespace Internal