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, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
101 Dali::Adaptor* adaptor = new Dali::Adaptor;
102 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
103 adaptor->mImpl = impl;
105 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
106 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
108 impl->Initialize( graphicsFactory, configuration );
109 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
114 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
116 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
117 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
118 windowImpl.SetAdaptor( *adaptor );
122 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
124 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
125 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
126 adaptor->mImpl = impl;
128 impl->Initialize( graphicsFactory, configuration );
133 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
135 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
136 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
137 windowImpl.SetAdaptor( *adaptor );
141 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
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 ProcessCoreEvents(); // Ensure any startup messages are processed.
405 // Initialize the image loader plugin
406 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
408 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
415 mAddOnManager->Start();
419 // Dali::Internal::Adaptor::Adaptor::Pause
420 void Adaptor::Pause()
422 // Only pause the adaptor if we're actually running.
423 if( RUNNING == mState )
425 // Inform observers that we are about to be paused.
426 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
434 mAddOnManager->Pause();
437 // Pause all windows event handlers when adaptor paused
438 for( auto window : mWindows )
443 mThreadController->Pause();
446 // Ensure any messages queued during pause callbacks are processed by doing another update.
449 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
453 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
457 // Dali::Internal::Adaptor::Adaptor::Resume
458 void Adaptor::Resume()
460 // Only resume the adaptor if we are in the suspended state.
461 if( PAUSED == mState )
465 // Reset the event handlers when adaptor resumed
466 for( auto window : mWindows )
471 // Resume AddOnManager
474 mAddOnManager->Resume();
477 // Inform observers that we have resumed.
478 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
483 // Trigger processing of events queued up while paused
484 mCore->ProcessEvents();
486 // Do at end to ensure our first update/render after resumption includes the processed messages as well
487 mThreadController->Resume();
489 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
493 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
499 if( RUNNING == mState ||
501 PAUSED_WHILE_HIDDEN == mState )
503 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
510 mAddOnManager->Stop();
513 mThreadController->Stop();
515 // Delete the TTS player
516 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
520 mTtsPlayers[i].Reset();
524 // Destroy the image loader plugin
525 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
527 delete mNotificationTrigger;
528 mNotificationTrigger = NULL;
530 mCallbackManager->Stop();
534 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
538 void Adaptor::ContextLost()
540 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
543 void Adaptor::ContextRegained()
545 // Inform core, so that texture resources can be reloaded
546 mCore->RecoverFromContextLoss();
548 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
551 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
553 Integration::Point convertedPoint( point );
554 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
557 void Adaptor::FeedWheelEvent( Dali::WheelEvent& wheelEvent )
559 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >( wheelEvent.GetType() ), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime() );
560 mWindows.front()->FeedWheelEvent( event );
563 void Adaptor::FeedKeyEvent( Dali::KeyEvent& keyEvent )
565 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() );
566 mWindows.front()->FeedKeyEvent( convertedEvent );
569 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
571 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
572 for( auto windowPtr : mWindows )
574 if( windowPtr == windowImpl ) // the window is not deleted
576 mResizedSignal.Emit( mAdaptor );
578 windowImpl->SetSurface( &newSurface );
580 // Flush the event queue to give the update-render thread chance
581 // to start processing messages for new camera setup etc as soon as possible
584 // This method blocks until the render thread has completed the replace.
585 mThreadController->ReplaceSurface( &newSurface );
591 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
593 // Flush the event queue to give the update-render thread chance
594 // to start processing messages for new camera setup etc as soon as possible
597 // This method blocks until the render thread has finished rendering the current surface.
598 mThreadController->DeleteSurface( &surface );
601 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
603 return *mWindows.front()->GetSurface();
606 void Adaptor::ReleaseSurfaceLock()
608 mWindows.front()->GetSurface()->ReleaseLock();
611 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
613 if( !mTtsPlayers[mode] )
615 // Create the TTS player when it needed, because it can reduce launching time.
616 mTtsPlayers[mode] = TtsPlayer::New(mode);
619 return mTtsPlayers[mode];
622 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
624 bool idleAdded(false);
626 // Only add an idle if the Adaptor is actually running
627 if( RUNNING == mState || READY == mState || forceAdd )
629 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
635 void Adaptor::RemoveIdle( CallbackBase* callback )
637 mCallbackManager->RemoveIdleCallback( callback );
640 void Adaptor::ProcessIdle()
642 bool idleProcessed = mCallbackManager->ProcessIdle();
643 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
646 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
648 mThreadController->SetPreRenderCallback( callback );
651 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
653 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
654 windowImpl.SetAdaptor( Get() );
656 // Add the new Window to the container - the order is not important
657 mWindows.push_back( &windowImpl );
659 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
661 mThreadController->AddSurface( surface );
663 mWindowCreatedSignal.Emit( childWindow );
668 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
670 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
671 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
673 if( *iter == &windowImpl )
675 mWindows.erase( iter );
683 bool Adaptor::RemoveWindow( std::string childWindowName )
685 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
687 if( ( *iter )->GetName() == childWindowName )
689 mWindows.erase( iter );
697 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
699 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
701 if( ( *iter )->GetId() == childWindow->GetId() )
703 mWindows.erase( iter );
711 Dali::Adaptor& Adaptor::Get()
713 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
714 return gThreadLocalAdaptor->mAdaptor;
717 bool Adaptor::IsAvailable()
719 return gThreadLocalAdaptor != NULL;
722 void Adaptor::SceneCreated()
724 mCore->SceneCreated();
727 Dali::Integration::Core& Adaptor::GetCore()
732 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
734 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
737 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
739 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
740 return *mDisplayConnection;
743 GraphicsInterface& Adaptor::GetGraphicsInterface()
745 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
746 return *( mGraphics.get() );
749 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
751 return *mPlatformAbstraction;
754 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
756 return *mNotificationTrigger;
759 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
761 return mSocketFactory;
764 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
766 if( !mWindows.empty() )
768 return mWindows.front()->GetSurface();
774 TraceInterface& Adaptor::GetKernelTraceInterface()
776 return mKernelTracer;
779 TraceInterface& Adaptor::GetSystemTraceInterface()
781 return mSystemTracer;
784 PerformanceInterface* Adaptor::GetPerformanceInterface()
786 return mPerformanceInterface;
789 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
791 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
792 return *mPlatformAbstraction;
795 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
800 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
802 if( mTtsPlayers[mode] )
804 mTtsPlayers[mode].Reset();
808 Any Adaptor::GetNativeWindowHandle()
810 return mWindows.front()->GetNativeHandle();
813 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
815 Any nativeWindowHandle;
817 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
819 for( auto sceneHolder : mWindows )
821 if ( scene == sceneHolder->GetScene() )
823 nativeWindowHandle = sceneHolder->GetNativeHandle();
828 return nativeWindowHandle;
831 Any Adaptor::GetGraphicsDisplay()
837 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
838 auto eglGraphics = static_cast<EglGraphics *>( graphics );
840 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
841 display = eglImpl.GetDisplay();
847 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
849 mUseRemoteSurface = useRemoteSurface;
852 void Adaptor::AddObserver( LifeCycleObserver& observer )
854 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
856 if ( match == mObservers.end() )
858 mObservers.push_back( &observer );
862 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
864 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
866 if ( match != mObservers.end() )
868 mObservers.erase( match );
872 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
876 mCore->QueueEvent(event);
880 void Adaptor::ProcessCoreEvents()
884 if( mPerformanceInterface )
886 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
889 mCore->ProcessEvents();
891 if( mPerformanceInterface )
893 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
898 void Adaptor::RequestUpdate( bool forceUpdate )
904 mThreadController->RequestUpdate();
908 case PAUSED_WHILE_HIDDEN:
912 // Update (and resource upload) without rendering
913 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
925 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
927 // Only request a notification if the Adaptor is actually running
928 // and we haven't installed the idle notification
929 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
931 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
935 void Adaptor::OnWindowShown()
937 if( PAUSED_WHILE_HIDDEN == mState )
939 // Adaptor can now be resumed
944 // Force a render task
947 else if( RUNNING == mState )
949 // Force a render task
952 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
954 else if( PAUSED_WHILE_INITIALIZING == mState )
956 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
961 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
965 void Adaptor::OnWindowHidden()
967 if( RUNNING == mState || READY == mState )
969 bool allWindowsHidden = true;
971 for( auto window : mWindows )
973 if ( window->IsVisible() )
975 allWindowsHidden = false;
980 // Only pause the adaptor when all the windows are hidden
981 if( allWindowsHidden )
983 if( mState == RUNNING )
987 // Adaptor cannot be resumed until any window is shown
988 mState = PAUSED_WHILE_HIDDEN;
990 else // mState is READY
992 // Pause the adaptor after the state gets RUNNING
993 mState = PAUSED_WHILE_INITIALIZING;
998 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1003 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1007 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1008 void Adaptor::OnDamaged( const DamageArea& area )
1010 // This is needed for the case where Dali window is partially obscured
1011 RequestUpdate( false );
1014 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1016 mResizedSignal.Emit( mAdaptor );
1019 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1021 // Nofify surface resizing before flushing event queue
1022 mThreadController->ResizeSurface();
1024 // Flush the event queue to give the update-render thread chance
1025 // to start processing messages for new camera setup etc as soon as possible
1026 ProcessCoreEvents();
1029 void Adaptor::NotifySceneCreated()
1031 GetCore().SceneCreated();
1033 // Flush the event queue to give the update-render thread chance
1034 // to start processing messages for new camera setup etc as soon as possible
1035 ProcessCoreEvents();
1037 // Start thread controller after the scene has been created
1038 mThreadController->Start();
1040 // Process after surface is created (registering to remote surface provider if required)
1041 SurfaceInitialized();
1043 if( mState != PAUSED_WHILE_INITIALIZING )
1047 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1055 mState = PAUSED_WHILE_HIDDEN;
1057 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1061 void Adaptor::NotifyLanguageChanged()
1063 mLanguageChangedSignal.Emit( mAdaptor );
1066 void Adaptor::RenderOnce()
1068 if( mThreadController )
1070 UpdateMode updateMode;
1071 if( mThreadMode == ThreadMode::NORMAL )
1073 updateMode = UpdateMode::NORMAL;
1077 updateMode = UpdateMode::FORCE_RENDER;
1079 ProcessCoreEvents();
1081 mThreadController->RequestUpdateOnce( updateMode );
1085 const LogFactoryInterface& Adaptor::GetLogFactory()
1087 return *mEnvironmentOptions;
1090 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1092 GetCore().RegisterProcessor(processor);
1095 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1097 GetCore().UnregisterProcessor(processor);
1100 bool Adaptor::IsMultipleWindowSupported() const
1102 return mConfigurationManager->IsMultipleWindowSupported();
1105 void Adaptor::RequestUpdateOnce()
1107 if( mThreadController )
1109 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1113 bool Adaptor::ProcessCoreEventsFromIdle()
1115 ProcessCoreEvents();
1117 // the idle handle automatically un-installs itself
1118 mNotificationOnIdleInstalled = false;
1123 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1125 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1127 for( auto window : mWindows )
1129 if ( scene == window->GetScene() )
1138 Dali::WindowContainer Adaptor::GetWindows() const
1140 Dali::WindowContainer windows;
1142 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1144 // Downcast to Dali::Window
1145 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1148 windows.push_back( window );
1155 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1157 Dali::SceneHolderList sceneHolderList;
1159 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1161 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1164 return sceneHolderList;
1167 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1169 Dali::ObjectRegistry registry;
1172 registry = mCore->GetObjectRegistry();
1177 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1179 mLanguageChangedSignal(),
1180 mWindowCreatedSignal(),
1181 mAdaptor( adaptor ),
1184 mThreadController( nullptr ),
1185 mGraphics( nullptr ),
1186 mDisplayConnection( nullptr ),
1188 mConfigurationManager( nullptr ),
1189 mPlatformAbstraction( nullptr ),
1190 mCallbackManager( nullptr ),
1191 mNotificationOnIdleInstalled( false ),
1192 mNotificationTrigger( nullptr ),
1193 mDaliFeedbackPlugin(),
1194 mFeedbackController( nullptr ),
1197 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1198 mPerformanceInterface( nullptr ),
1201 mObjectProfiler( nullptr ),
1203 mThreadMode( ThreadMode::NORMAL ),
1204 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1205 mUseRemoteSurface( false )
1207 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1208 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1210 gThreadLocalAdaptor = this;
1213 void Adaptor::SetRootLayoutDirection( std::string locale )
1215 for ( auto& window : mWindows )
1217 Dali::Actor root = window->GetRootLayer();
1218 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1219 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1223 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1225 bool idleAdded( false );
1227 // Only add an idle if the Adaptor is actually running
1228 if( RUNNING == mState || READY == mState || forceAdd )
1230 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1242 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1244 mCallbackManager->RemoveIdleEntererCallback( callback );
1247 } // namespace Adaptor
1249 } // namespace Internal