2 * Copyright (c) 2020 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/addons/common/addon-manager-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
27 #include <dali/public-api/actors/layer.h>
28 #include <dali/public-api/object/any.h>
29 #include <dali/public-api/object/object-registry.h>
30 #include <dali/public-api/events/wheel-event.h>
31 #include <dali/devel-api/actors/actor-devel.h>
32 #include <dali/integration-api/debug.h>
33 #include <dali/integration-api/core.h>
34 #include <dali/integration-api/context-notifier.h>
35 #include <dali/integration-api/profiling.h>
36 #include <dali/integration-api/input-options.h>
37 #include <dali/integration-api/events/key-event-integ.h>
38 #include <dali/integration-api/events/touch-event-integ.h>
39 #include <dali/integration-api/events/wheel-event-integ.h>
40 #include <dali/integration-api/processor-interface.h>
41 #include <dali/integration-api/addon-manager.h>
44 #include <dali/public-api/dali-adaptor-common.h>
45 #include <dali/internal/system/common/thread-controller.h>
46 #include <dali/internal/system/common/performance-interface-factory.h>
47 #include <dali/internal/adaptor/common/lifecycle-observer.h>
48 #include <dali/internal/adaptor/common/thread-controller-interface.h>
50 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
51 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
53 #include <dali/devel-api/text-abstraction/font-client.h>
55 #include <dali/internal/system/common/callback-manager.h>
56 #include <dali/internal/accessibility/common/tts-player-impl.h>
57 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
58 #include <dali/internal/window-system/common/event-handler.h>
59 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
60 #include <dali/internal/graphics/gles/gl-implementation.h>
61 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
62 #include <dali/internal/graphics/common/egl-image-extensions.h>
63 #include <dali/internal/clipboard/common/clipboard-impl.h>
64 #include <dali/internal/system/common/object-profiler.h>
65 #include <dali/internal/window-system/common/display-connection.h>
66 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
67 #include <dali/internal/window-system/common/window-impl.h>
68 #include <dali/internal/window-system/common/window-render-surface.h>
70 #include <dali/internal/system/common/logging.h>
72 #include <dali/internal/system/common/locale-utils.h>
73 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
74 #include <dali/internal/imaging/common/image-loader.h>
76 #include <dali/internal/system/common/configuration-manager.h>
77 #include <dali/internal/system/common/environment-variables.h>
79 using Dali::TextAbstraction::FontClient;
81 extern std::string GetSystemCachePath();
95 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
97 } // unnamed namespace
99 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
101 Dali::Adaptor* adaptor = new Dali::Adaptor;
102 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode );
103 adaptor->mImpl = impl;
105 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
106 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
108 impl->Initialize( graphicsFactory );
109 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
114 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
116 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
117 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
118 windowImpl.SetAdaptor( *adaptor );
122 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
124 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
125 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode ); // Impl adaptor
126 adaptor->mImpl = impl;
128 impl->Initialize( graphicsFactory );
133 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
135 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
136 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
137 windowImpl.SetAdaptor( *adaptor );
141 void Adaptor::Initialize( GraphicsFactory& graphicsFactory )
143 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
144 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
145 mEnvironmentOptions->SetLogFunction( logFunction );
146 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
148 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
151 GetDataStoragePath( path );
152 mPlatformAbstraction->SetDataStoragePath( path );
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 = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
169 mGraphics->Initialize( mEnvironmentOptions );
171 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
172 auto eglGraphics = static_cast<EglGraphics *>( graphics );
174 // This will only be created once
175 eglGraphics->Create();
177 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
178 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
179 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
181 // Create the AddOnManager
182 mAddOnManager.reset( Dali::Internal::AddOnManagerFactory::CreateAddOnManager() );
184 mCore = Integration::Core::New( *this,
185 *mPlatformAbstraction,
188 eglContextHelperImpl,
189 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
190 mGraphics->GetDepthBufferRequired(),
191 mGraphics->GetStencilBufferRequired(),
192 mGraphics->GetPartialUpdateRequired() );
195 defaultWindow->SetAdaptor( Get() );
197 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
199 mWindowCreatedSignal.Emit( defaultSceneHolder );
201 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
202 if( 0u < timeInterval )
204 mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
207 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
209 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
211 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
213 // Should be called after Core creation
214 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
216 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
218 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
220 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
222 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
224 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
226 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
228 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
230 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
232 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
234 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
236 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
238 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
240 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
242 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
244 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
246 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
248 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
250 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
252 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
254 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
256 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
258 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
260 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
262 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
264 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
266 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
268 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
270 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
272 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
274 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
276 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
278 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
280 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
282 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
284 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
286 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
288 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
290 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
292 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
294 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
296 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
298 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
300 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
302 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
304 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
306 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
308 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
311 std::string systemCachePath = GetSystemCachePath();
312 if( ! systemCachePath.empty() )
314 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
315 if ( 0 != dir_err && errno != EEXIST )
317 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
322 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
327 // Ensure stop status
330 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
331 gThreadLocalAdaptor = NULL;
333 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
335 (*iter)->OnDestroy();
338 // Clear out all the handles to Windows
341 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
342 delete mObjectProfiler;
346 delete mDisplayConnection;
347 delete mPlatformAbstraction;
348 delete mCallbackManager;
349 delete mPerformanceInterface;
351 mGraphics->Destroy();
353 // uninstall it on this thread (main actor thread)
354 Dali::Integration::Log::UninstallLogFunction();
356 // Delete environment options if we own it
357 if( mEnvironmentOptionsOwned )
359 delete mEnvironmentOptions;
363 void Adaptor::Start()
365 // It doesn't support restart after stop at this moment to support restarting, need more testing
366 if( READY != mState )
373 SetupSystemInformation();
375 // Start the callback manager
376 mCallbackManager->Start();
378 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
380 unsigned int dpiHor, dpiVer;
383 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
385 // set the DPI value for font rendering
386 FontClient fontClient = FontClient::Get();
387 fontClient.SetDpi( dpiHor, dpiVer );
389 // Initialize the thread controller
390 mThreadController->Initialize();
392 // Set max texture size
393 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
395 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
399 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
400 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
403 // Set cached isAdvancedBlendEquationSupported
404 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
405 auto eglGraphics = static_cast<EglGraphics *>( graphics );
406 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
407 mGLES.SetIsAdvancedBlendEquationSupported( mConfigurationManager->IsAdvancedBlendEquationSupported() );
408 mGLES.SetShadingLanguageVersion( mConfigurationManager->GetShadingLanguageVersion() );
410 ProcessCoreEvents(); // Ensure any startup messages are processed.
412 // Initialize the image loader plugin
413 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
415 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
422 mAddOnManager->Start();
426 // Dali::Internal::Adaptor::Adaptor::Pause
427 void Adaptor::Pause()
429 // Only pause the adaptor if we're actually running.
430 if( RUNNING == mState )
432 // Inform observers that we are about to be paused.
433 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
441 mAddOnManager->Pause();
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 // Resume AddOnManager
481 mAddOnManager->Resume();
484 // Inform observers that we have resumed.
485 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
490 // Trigger processing of events queued up while paused
491 mCore->ProcessEvents();
493 // Do at end to ensure our first update/render after resumption includes the processed messages as well
494 mThreadController->Resume();
496 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
500 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
506 if( RUNNING == mState ||
508 PAUSED_WHILE_HIDDEN == mState )
510 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
517 mAddOnManager->Stop();
520 mThreadController->Stop();
522 // Delete the TTS player
523 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
527 mTtsPlayers[i].Reset();
531 // Destroy the image loader plugin
532 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
534 delete mNotificationTrigger;
535 mNotificationTrigger = NULL;
537 mCallbackManager->Stop();
541 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
545 void Adaptor::ContextLost()
547 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
550 void Adaptor::ContextRegained()
552 // Inform core, so that texture resources can be reloaded
553 mCore->RecoverFromContextLoss();
555 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
558 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
560 Integration::Point convertedPoint( point );
561 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
564 void Adaptor::FeedWheelEvent( Dali::WheelEvent& wheelEvent )
566 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >( wheelEvent.GetType() ), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime() );
567 mWindows.front()->FeedWheelEvent( event );
570 void Adaptor::FeedKeyEvent( Dali::KeyEvent& keyEvent )
572 Integration::KeyEvent convertedEvent( keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast< Integration::KeyEvent::State >( keyEvent.GetState() ), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass() );
573 mWindows.front()->FeedKeyEvent( convertedEvent );
576 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
578 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
579 for( auto windowPtr : mWindows )
581 if( windowPtr == windowImpl ) // the window is not deleted
583 mResizedSignal.Emit( mAdaptor );
585 windowImpl->SetSurface( &newSurface );
587 // Flush the event queue to give the update-render thread chance
588 // to start processing messages for new camera setup etc as soon as possible
591 // This method blocks until the render thread has completed the replace.
592 mThreadController->ReplaceSurface( &newSurface );
598 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
600 // Flush the event queue to give the update-render thread chance
601 // to start processing messages for new camera setup etc as soon as possible
604 // This method blocks until the render thread has finished rendering the current surface.
605 mThreadController->DeleteSurface( &surface );
608 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
610 return *mWindows.front()->GetSurface();
613 void Adaptor::ReleaseSurfaceLock()
615 mWindows.front()->GetSurface()->ReleaseLock();
618 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
620 if( !mTtsPlayers[mode] )
622 // Create the TTS player when it needed, because it can reduce launching time.
623 mTtsPlayers[mode] = TtsPlayer::New(mode);
626 return mTtsPlayers[mode];
629 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
631 bool idleAdded(false);
633 // Only add an idle if the Adaptor is actually running
634 if( RUNNING == mState || READY == mState || forceAdd )
636 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
642 void Adaptor::RemoveIdle( CallbackBase* callback )
644 mCallbackManager->RemoveIdleCallback( callback );
647 void Adaptor::ProcessIdle()
649 bool idleProcessed = mCallbackManager->ProcessIdle();
650 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
653 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
655 mThreadController->SetPreRenderCallback( callback );
658 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
660 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
661 windowImpl.SetAdaptor( Get() );
663 // ChildWindow is set to the layout direction of the default window.
664 windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
666 // Add the new Window to the container - the order is not important
667 mWindows.push_back( &windowImpl );
669 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
671 mThreadController->AddSurface( surface );
673 mWindowCreatedSignal.Emit( childWindow );
678 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
680 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
681 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
683 if( *iter == &windowImpl )
685 mWindows.erase( iter );
693 bool Adaptor::RemoveWindow( std::string childWindowName )
695 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
697 if( ( *iter )->GetName() == childWindowName )
699 mWindows.erase( iter );
707 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
709 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
711 if( ( *iter )->GetId() == childWindow->GetId() )
713 mWindows.erase( iter );
721 Dali::Adaptor& Adaptor::Get()
723 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
724 return gThreadLocalAdaptor->mAdaptor;
727 bool Adaptor::IsAvailable()
729 return gThreadLocalAdaptor != NULL;
732 void Adaptor::SceneCreated()
734 mCore->SceneCreated();
737 Dali::Integration::Core& Adaptor::GetCore()
742 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
744 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
747 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
749 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
750 return *mDisplayConnection;
753 GraphicsInterface& Adaptor::GetGraphicsInterface()
755 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
756 return *( mGraphics.get() );
759 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
761 return *mPlatformAbstraction;
764 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
766 return *mNotificationTrigger;
769 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
771 return mSocketFactory;
774 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
776 if( !mWindows.empty() )
778 return mWindows.front()->GetSurface();
784 TraceInterface& Adaptor::GetKernelTraceInterface()
786 return mKernelTracer;
789 TraceInterface& Adaptor::GetSystemTraceInterface()
791 return mSystemTracer;
794 PerformanceInterface* Adaptor::GetPerformanceInterface()
796 return mPerformanceInterface;
799 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
801 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
802 return *mPlatformAbstraction;
805 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
810 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
812 if( mTtsPlayers[mode] )
814 mTtsPlayers[mode].Reset();
818 Any Adaptor::GetNativeWindowHandle()
820 return mWindows.front()->GetNativeHandle();
823 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
825 Any nativeWindowHandle;
827 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
829 for( auto sceneHolder : mWindows )
831 if ( scene == sceneHolder->GetScene() )
833 nativeWindowHandle = sceneHolder->GetNativeHandle();
838 return nativeWindowHandle;
841 Any Adaptor::GetGraphicsDisplay()
847 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
848 auto eglGraphics = static_cast<EglGraphics *>( graphics );
850 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
851 display = eglImpl.GetDisplay();
857 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
859 mUseRemoteSurface = useRemoteSurface;
862 void Adaptor::AddObserver( LifeCycleObserver& observer )
864 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
866 if ( match == mObservers.end() )
868 mObservers.push_back( &observer );
872 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
874 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
876 if ( match != mObservers.end() )
878 mObservers.erase( match );
882 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
886 mCore->QueueEvent(event);
890 void Adaptor::ProcessCoreEvents()
894 if( mPerformanceInterface )
896 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
899 mCore->ProcessEvents();
901 if( mPerformanceInterface )
903 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
908 void Adaptor::RequestUpdate( bool forceUpdate )
914 mThreadController->RequestUpdate();
918 case PAUSED_WHILE_HIDDEN:
922 // Update (and resource upload) without rendering
923 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
935 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
937 // Only request a notification if the Adaptor is actually running
938 // and we haven't installed the idle notification
939 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
941 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
945 void Adaptor::OnWindowShown()
947 if( PAUSED_WHILE_HIDDEN == mState )
949 // Adaptor can now be resumed
954 // Force a render task
957 else if( RUNNING == mState )
959 // Force a render task
962 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
964 else if( PAUSED_WHILE_INITIALIZING == mState )
966 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
971 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
975 void Adaptor::OnWindowHidden()
977 if( RUNNING == mState || READY == mState )
979 bool allWindowsHidden = true;
981 for( auto window : mWindows )
983 if ( window->IsVisible() )
985 allWindowsHidden = false;
990 // Only pause the adaptor when all the windows are hidden
991 if( allWindowsHidden )
993 if( mState == RUNNING )
997 // Adaptor cannot be resumed until any window is shown
998 mState = PAUSED_WHILE_HIDDEN;
1000 else // mState is READY
1002 // Pause the adaptor after the state gets RUNNING
1003 mState = PAUSED_WHILE_INITIALIZING;
1008 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1013 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1017 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1018 void Adaptor::OnDamaged( const DamageArea& area )
1020 // This is needed for the case where Dali window is partially obscured
1021 RequestUpdate( false );
1024 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1026 mResizedSignal.Emit( mAdaptor );
1029 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1031 // Nofify surface resizing before flushing event queue
1032 mThreadController->ResizeSurface();
1034 // Flush the event queue to give the update-render thread chance
1035 // to start processing messages for new camera setup etc as soon as possible
1036 ProcessCoreEvents();
1039 void Adaptor::NotifySceneCreated()
1041 GetCore().SceneCreated();
1043 // Flush the event queue to give the update-render thread chance
1044 // to start processing messages for new camera setup etc as soon as possible
1045 ProcessCoreEvents();
1047 // Start thread controller after the scene has been created
1048 mThreadController->Start();
1050 // Process after surface is created (registering to remote surface provider if required)
1051 SurfaceInitialized();
1053 if( mState != PAUSED_WHILE_INITIALIZING )
1057 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1065 mState = PAUSED_WHILE_HIDDEN;
1067 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1071 void Adaptor::NotifyLanguageChanged()
1073 mLanguageChangedSignal.Emit( mAdaptor );
1076 void Adaptor::RenderOnce()
1078 if( mThreadController )
1080 UpdateMode updateMode;
1081 if( mThreadMode == ThreadMode::NORMAL )
1083 updateMode = UpdateMode::NORMAL;
1087 updateMode = UpdateMode::FORCE_RENDER;
1089 ProcessCoreEvents();
1091 mThreadController->RequestUpdateOnce( updateMode );
1095 const LogFactoryInterface& Adaptor::GetLogFactory()
1097 return *mEnvironmentOptions;
1100 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1102 GetCore().RegisterProcessor(processor);
1105 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1107 GetCore().UnregisterProcessor(processor);
1110 bool Adaptor::IsMultipleWindowSupported() const
1112 return mConfigurationManager->IsMultipleWindowSupported();
1115 void Adaptor::RequestUpdateOnce()
1117 if( mThreadController )
1119 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1123 bool Adaptor::ProcessCoreEventsFromIdle()
1125 ProcessCoreEvents();
1127 // the idle handle automatically un-installs itself
1128 mNotificationOnIdleInstalled = false;
1133 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1135 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1137 for( auto window : mWindows )
1139 if ( scene == window->GetScene() )
1148 Dali::WindowContainer Adaptor::GetWindows() const
1150 Dali::WindowContainer windows;
1152 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1154 // Downcast to Dali::Window
1155 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1158 windows.push_back( window );
1165 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1167 Dali::SceneHolderList sceneHolderList;
1169 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1171 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1174 return sceneHolderList;
1177 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1179 Dali::ObjectRegistry registry;
1182 registry = mCore->GetObjectRegistry();
1187 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1189 mLanguageChangedSignal(),
1190 mWindowCreatedSignal(),
1191 mAdaptor( adaptor ),
1194 mThreadController( nullptr ),
1195 mGraphics( nullptr ),
1196 mDisplayConnection( nullptr ),
1198 mConfigurationManager( nullptr ),
1199 mPlatformAbstraction( nullptr ),
1200 mCallbackManager( nullptr ),
1201 mNotificationOnIdleInstalled( false ),
1202 mNotificationTrigger( nullptr ),
1203 mDaliFeedbackPlugin(),
1204 mFeedbackController( nullptr ),
1207 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1208 mPerformanceInterface( nullptr ),
1211 mObjectProfiler( nullptr ),
1213 mThreadMode( threadMode ),
1214 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1215 mUseRemoteSurface( false ),
1216 mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1218 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1219 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1221 gThreadLocalAdaptor = this;
1224 void Adaptor::SetRootLayoutDirection( std::string locale )
1226 mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1227 for ( auto& window : mWindows )
1229 Dali::Actor root = window->GetRootLayer();
1230 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1234 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1236 bool idleAdded( false );
1238 // Only add an idle if the Adaptor is actually running
1239 if( RUNNING == mState || READY == mState || forceAdd )
1241 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1253 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1255 mCallbackManager->RemoveIdleEntererCallback( callback );
1258 } // namespace Adaptor
1260 } // namespace Internal