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/devel-api/common/stage.h>
33 #include <dali/integration-api/debug.h>
34 #include <dali/integration-api/core.h>
35 #include <dali/integration-api/context-notifier.h>
36 #include <dali/integration-api/profiling.h>
37 #include <dali/integration-api/input-options.h>
38 #include <dali/integration-api/events/key-event-integ.h>
39 #include <dali/integration-api/events/touch-event-integ.h>
40 #include <dali/integration-api/events/wheel-event-integ.h>
41 #include <dali/integration-api/processor-interface.h>
42 #include <dali/integration-api/addon-manager.h>
45 #include <dali/public-api/dali-adaptor-common.h>
46 #include <dali/internal/system/common/thread-controller.h>
47 #include <dali/internal/system/common/performance-interface-factory.h>
48 #include <dali/internal/adaptor/common/lifecycle-observer.h>
49 #include <dali/internal/adaptor/common/thread-controller-interface.h>
51 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
52 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
54 #include <dali/devel-api/text-abstraction/font-client.h>
56 #include <dali/internal/system/common/callback-manager.h>
57 #include <dali/internal/accessibility/common/tts-player-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/devel-api/adaptor-framework/accessibility-impl.h>
71 #include <dali/internal/system/common/logging.h>
73 #include <dali/internal/system/common/locale-utils.h>
74 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
75 #include <dali/internal/imaging/common/image-loader.h>
77 #include <dali/internal/system/common/configuration-manager.h>
78 #include <dali/internal/system/common/environment-variables.h>
80 using Dali::TextAbstraction::FontClient;
82 extern std::string GetSystemCachePath();
96 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
98 } // unnamed namespace
100 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
102 Dali::Adaptor* adaptor = new Dali::Adaptor;
103 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode );
104 adaptor->mImpl = impl;
106 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
107 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
109 impl->Initialize( graphicsFactory );
110 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
115 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
117 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
118 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
119 windowImpl.SetAdaptor( *adaptor );
123 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
125 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
126 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode ); // Impl adaptor
127 adaptor->mImpl = impl;
129 impl->Initialize( graphicsFactory );
134 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
136 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
137 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
138 windowImpl.SetAdaptor( *adaptor );
142 void Adaptor::Initialize( GraphicsFactory& graphicsFactory )
144 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
145 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
146 mEnvironmentOptions->SetLogFunction( logFunction );
147 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
149 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
152 GetDataStoragePath( path );
153 mPlatformAbstraction->SetDataStoragePath( path );
155 if( mEnvironmentOptions->PerformanceServerRequired() )
157 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
160 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
161 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
163 mCallbackManager = CallbackManager::New();
165 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
167 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
169 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
170 mGraphics->Initialize( mEnvironmentOptions );
172 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
173 auto eglGraphics = static_cast<EglGraphics *>( graphics );
175 // This will only be created once
176 eglGraphics->Create();
178 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
179 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
180 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
182 // Create the AddOnManager
183 mAddOnManager.reset( Dali::Internal::AddOnManagerFactory::CreateAddOnManager() );
185 mCore = Integration::Core::New( *this,
186 *mPlatformAbstraction,
189 eglContextHelperImpl,
190 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
191 mGraphics->GetDepthBufferRequired(),
192 mGraphics->GetStencilBufferRequired(),
193 mGraphics->GetPartialUpdateRequired() );
196 defaultWindow->SetAdaptor( Get() );
198 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
200 mWindowCreatedSignal.Emit( defaultSceneHolder );
202 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
203 if( 0u < timeInterval )
205 mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
208 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
210 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
212 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
214 // Should be called after Core creation
215 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
217 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
219 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
221 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
223 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
225 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
227 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
229 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
231 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
233 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
235 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
237 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
239 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
241 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
243 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
245 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
247 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
249 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
251 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
253 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
255 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
257 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
259 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
261 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
263 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
265 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
267 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
269 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
271 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
273 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
275 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
277 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
279 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
281 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
283 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
285 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
287 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
289 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
291 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
293 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
295 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
297 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
299 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
301 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
303 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
305 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
307 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
309 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
312 std::string systemCachePath = GetSystemCachePath();
313 if( ! systemCachePath.empty() )
315 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
316 if ( 0 != dir_err && errno != EEXIST )
318 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
323 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
325 auto appName = GetApplicationPackageName();
326 auto bridge = Accessibility::Bridge::GetCurrentBridge();
327 bridge->SetApplicationName( appName );
328 bridge->Initialize();
329 Dali::Stage::GetCurrent().KeyEventSignal().Connect( &accessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent );
332 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent( const Dali::KeyEvent& event )
334 Accessibility::KeyEventType type;
335 if( event.GetState() == Dali::KeyEvent::DOWN )
337 type = Accessibility::KeyEventType::KEY_PRESSED;
339 else if( event.GetState() == Dali::KeyEvent::UP )
341 type = Accessibility::KeyEventType::KEY_RELEASED;
347 Dali::Accessibility::Bridge::GetCurrentBridge()->Emit( type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty() );
352 Accessibility::Bridge::GetCurrentBridge()->Terminate();
354 // Ensure stop status
357 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
358 gThreadLocalAdaptor = NULL;
360 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
362 (*iter)->OnDestroy();
365 // Clear out all the handles to Windows
368 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
369 delete mObjectProfiler;
373 delete mDisplayConnection;
374 delete mPlatformAbstraction;
375 delete mCallbackManager;
376 delete mPerformanceInterface;
378 mGraphics->Destroy();
380 // uninstall it on this thread (main actor thread)
381 Dali::Integration::Log::UninstallLogFunction();
383 // Delete environment options if we own it
384 if( mEnvironmentOptionsOwned )
386 delete mEnvironmentOptions;
390 void Adaptor::Start()
392 // It doesn't support restart after stop at this moment to support restarting, need more testing
393 if( READY != mState )
400 SetupSystemInformation();
402 // Start the callback manager
403 mCallbackManager->Start();
405 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
407 unsigned int dpiHor, dpiVer;
410 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
412 // set the DPI value for font rendering
413 FontClient fontClient = FontClient::Get();
414 fontClient.SetDpi( dpiHor, dpiVer );
416 // Initialize the thread controller
417 mThreadController->Initialize();
419 // Set max texture size
420 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
422 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
426 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
427 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
430 // Set cached isAdvancedBlendEquationSupported
431 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
432 auto eglGraphics = static_cast<EglGraphics *>( graphics );
433 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
434 mGLES.SetIsAdvancedBlendEquationSupported( mConfigurationManager->IsAdvancedBlendEquationSupported() );
435 mGLES.SetShadingLanguageVersion( mConfigurationManager->GetShadingLanguageVersion() );
437 ProcessCoreEvents(); // Ensure any startup messages are processed.
439 // Initialize the image loader plugin
440 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
442 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
449 mAddOnManager->Start();
453 // Dali::Internal::Adaptor::Adaptor::Pause
454 void Adaptor::Pause()
456 // Only pause the adaptor if we're actually running.
457 if( RUNNING == mState )
459 // Inform observers that we are about to be paused.
460 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
468 mAddOnManager->Pause();
471 // Pause all windows event handlers when adaptor paused
472 for( auto window : mWindows )
477 mThreadController->Pause();
480 // Ensure any messages queued during pause callbacks are processed by doing another update.
483 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
487 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
491 // Dali::Internal::Adaptor::Adaptor::Resume
492 void Adaptor::Resume()
494 // Only resume the adaptor if we are in the suspended state.
495 if( PAUSED == mState )
499 // Reset the event handlers when adaptor resumed
500 for( auto window : mWindows )
505 // Resume AddOnManager
508 mAddOnManager->Resume();
511 // Inform observers that we have resumed.
512 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
517 // Trigger processing of events queued up while paused
518 mCore->ProcessEvents();
520 // Do at end to ensure our first update/render after resumption includes the processed messages as well
521 mThreadController->Resume();
523 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
527 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
533 if( RUNNING == mState ||
535 PAUSED_WHILE_HIDDEN == mState )
537 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
544 mAddOnManager->Stop();
547 mThreadController->Stop();
549 // Delete the TTS player
550 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
554 mTtsPlayers[i].Reset();
558 // Destroy the image loader plugin
559 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
561 delete mNotificationTrigger;
562 mNotificationTrigger = NULL;
564 mCallbackManager->Stop();
568 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
572 void Adaptor::ContextLost()
574 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
577 void Adaptor::ContextRegained()
579 // Inform core, so that texture resources can be reloaded
580 mCore->RecoverFromContextLoss();
582 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
585 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
587 Integration::Point convertedPoint( point );
588 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
591 void Adaptor::FeedWheelEvent( Dali::WheelEvent& wheelEvent )
593 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >( wheelEvent.GetType() ), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime() );
594 mWindows.front()->FeedWheelEvent( event );
597 void Adaptor::FeedKeyEvent( Dali::KeyEvent& keyEvent )
599 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() );
600 mWindows.front()->FeedKeyEvent( convertedEvent );
603 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
605 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
606 for( auto windowPtr : mWindows )
608 if( windowPtr == windowImpl ) // the window is not deleted
610 mResizedSignal.Emit( mAdaptor );
612 windowImpl->SetSurface( &newSurface );
614 // Flush the event queue to give the update-render thread chance
615 // to start processing messages for new camera setup etc as soon as possible
618 // This method blocks until the render thread has completed the replace.
619 mThreadController->ReplaceSurface( &newSurface );
625 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
627 // Flush the event queue to give the update-render thread chance
628 // to start processing messages for new camera setup etc as soon as possible
631 // This method blocks until the render thread has finished rendering the current surface.
632 mThreadController->DeleteSurface( &surface );
635 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
637 return *mWindows.front()->GetSurface();
640 void Adaptor::ReleaseSurfaceLock()
642 mWindows.front()->GetSurface()->ReleaseLock();
645 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
647 if( !mTtsPlayers[mode] )
649 // Create the TTS player when it needed, because it can reduce launching time.
650 mTtsPlayers[mode] = TtsPlayer::New(mode);
653 return mTtsPlayers[mode];
656 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
658 bool idleAdded(false);
660 // Only add an idle if the Adaptor is actually running
661 if( RUNNING == mState || READY == mState || forceAdd )
663 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
669 void Adaptor::RemoveIdle( CallbackBase* callback )
671 mCallbackManager->RemoveIdleCallback( callback );
674 void Adaptor::ProcessIdle()
676 bool idleProcessed = mCallbackManager->ProcessIdle();
677 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
680 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
682 mThreadController->SetPreRenderCallback( callback );
685 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
687 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
688 windowImpl.SetAdaptor( Get() );
690 // ChildWindow is set to the layout direction of the default window.
691 windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
693 // Add the new Window to the container - the order is not important
694 mWindows.push_back( &windowImpl );
696 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
698 mThreadController->AddSurface( surface );
700 mWindowCreatedSignal.Emit( childWindow );
705 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
707 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
708 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
710 if( *iter == &windowImpl )
712 mWindows.erase( iter );
720 bool Adaptor::RemoveWindow( std::string childWindowName )
722 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
724 if( ( *iter )->GetName() == childWindowName )
726 mWindows.erase( iter );
734 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
736 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
738 if( ( *iter )->GetId() == childWindow->GetId() )
740 mWindows.erase( iter );
748 Dali::Adaptor& Adaptor::Get()
750 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
751 return gThreadLocalAdaptor->mAdaptor;
754 bool Adaptor::IsAvailable()
756 return gThreadLocalAdaptor != NULL;
759 void Adaptor::SceneCreated()
761 mCore->SceneCreated();
764 Dali::Integration::Core& Adaptor::GetCore()
769 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
771 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
774 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
776 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
777 return *mDisplayConnection;
780 GraphicsInterface& Adaptor::GetGraphicsInterface()
782 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
783 return *( mGraphics.get() );
786 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
788 return *mPlatformAbstraction;
791 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
793 return *mNotificationTrigger;
796 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
798 return mSocketFactory;
801 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
803 if( !mWindows.empty() )
805 return mWindows.front()->GetSurface();
811 TraceInterface& Adaptor::GetKernelTraceInterface()
813 return mKernelTracer;
816 TraceInterface& Adaptor::GetSystemTraceInterface()
818 return mSystemTracer;
821 PerformanceInterface* Adaptor::GetPerformanceInterface()
823 return mPerformanceInterface;
826 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
828 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
829 return *mPlatformAbstraction;
832 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
837 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
839 if( mTtsPlayers[mode] )
841 mTtsPlayers[mode].Reset();
845 Any Adaptor::GetNativeWindowHandle()
847 return mWindows.front()->GetNativeHandle();
850 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
852 Any nativeWindowHandle;
854 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
856 for( auto sceneHolder : mWindows )
858 if ( scene == sceneHolder->GetScene() )
860 nativeWindowHandle = sceneHolder->GetNativeHandle();
865 return nativeWindowHandle;
868 Any Adaptor::GetGraphicsDisplay()
874 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
875 auto eglGraphics = static_cast<EglGraphics *>( graphics );
877 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
878 display = eglImpl.GetDisplay();
884 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
886 mUseRemoteSurface = useRemoteSurface;
889 void Adaptor::AddObserver( LifeCycleObserver& observer )
891 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
893 if ( match == mObservers.end() )
895 mObservers.push_back( &observer );
899 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
901 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
903 if ( match != mObservers.end() )
905 mObservers.erase( match );
909 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
913 mCore->QueueEvent(event);
917 void Adaptor::ProcessCoreEvents()
921 if( mPerformanceInterface )
923 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
926 mCore->ProcessEvents();
928 if( mPerformanceInterface )
930 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
935 void Adaptor::RequestUpdate( bool forceUpdate )
941 mThreadController->RequestUpdate();
945 case PAUSED_WHILE_HIDDEN:
949 // Update (and resource upload) without rendering
950 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
962 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
964 // Only request a notification if the Adaptor is actually running
965 // and we haven't installed the idle notification
966 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
968 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
972 void Adaptor::OnWindowShown()
974 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
976 if( PAUSED_WHILE_HIDDEN == mState )
978 // Adaptor can now be resumed
983 // Force a render task
986 else if( RUNNING == mState )
988 // Force a render task
991 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
993 else if( PAUSED_WHILE_INITIALIZING == mState )
995 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
1000 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
1004 void Adaptor::OnWindowHidden()
1006 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
1008 if( RUNNING == mState || READY == mState )
1010 bool allWindowsHidden = true;
1012 for( auto window : mWindows )
1014 if ( window->IsVisible() )
1016 allWindowsHidden = false;
1021 // Only pause the adaptor when all the windows are hidden
1022 if( allWindowsHidden )
1024 if( mState == RUNNING )
1028 // Adaptor cannot be resumed until any window is shown
1029 mState = PAUSED_WHILE_HIDDEN;
1031 else // mState is READY
1033 // Pause the adaptor after the state gets RUNNING
1034 mState = PAUSED_WHILE_INITIALIZING;
1039 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1044 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1048 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1049 void Adaptor::OnDamaged( const DamageArea& area )
1051 // This is needed for the case where Dali window is partially obscured
1052 RequestUpdate( false );
1055 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1057 mResizedSignal.Emit( mAdaptor );
1060 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1062 // Nofify surface resizing before flushing event queue
1063 mThreadController->ResizeSurface();
1065 // Flush the event queue to give the update-render thread chance
1066 // to start processing messages for new camera setup etc as soon as possible
1067 ProcessCoreEvents();
1070 void Adaptor::NotifySceneCreated()
1072 GetCore().SceneCreated();
1074 // Flush the event queue to give the update-render thread chance
1075 // to start processing messages for new camera setup etc as soon as possible
1076 ProcessCoreEvents();
1078 // Start thread controller after the scene has been created
1079 mThreadController->Start();
1081 // Process after surface is created (registering to remote surface provider if required)
1082 SurfaceInitialized();
1084 if( mState != PAUSED_WHILE_INITIALIZING )
1088 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1096 mState = PAUSED_WHILE_HIDDEN;
1098 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1102 void Adaptor::NotifyLanguageChanged()
1104 mLanguageChangedSignal.Emit( mAdaptor );
1107 void Adaptor::RenderOnce()
1109 if( mThreadController )
1111 UpdateMode updateMode;
1112 if( mThreadMode == ThreadMode::NORMAL )
1114 updateMode = UpdateMode::NORMAL;
1118 updateMode = UpdateMode::FORCE_RENDER;
1120 ProcessCoreEvents();
1122 mThreadController->RequestUpdateOnce( updateMode );
1126 const LogFactoryInterface& Adaptor::GetLogFactory()
1128 return *mEnvironmentOptions;
1131 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1133 GetCore().RegisterProcessor(processor);
1136 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1138 GetCore().UnregisterProcessor(processor);
1141 bool Adaptor::IsMultipleWindowSupported() const
1143 return mConfigurationManager->IsMultipleWindowSupported();
1146 void Adaptor::RequestUpdateOnce()
1148 if( mThreadController )
1150 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1154 bool Adaptor::ProcessCoreEventsFromIdle()
1156 ProcessCoreEvents();
1158 // the idle handle automatically un-installs itself
1159 mNotificationOnIdleInstalled = false;
1164 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1166 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1168 for( auto window : mWindows )
1170 if ( scene == window->GetScene() )
1179 Dali::WindowContainer Adaptor::GetWindows() const
1181 Dali::WindowContainer windows;
1183 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1185 // Downcast to Dali::Window
1186 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1189 windows.push_back( window );
1196 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1198 Dali::SceneHolderList sceneHolderList;
1200 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1202 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1205 return sceneHolderList;
1208 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1210 Dali::ObjectRegistry registry;
1213 registry = mCore->GetObjectRegistry();
1218 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1220 mLanguageChangedSignal(),
1221 mWindowCreatedSignal(),
1222 mAdaptor( adaptor ),
1225 mThreadController( nullptr ),
1226 mGraphics( nullptr ),
1227 mDisplayConnection( nullptr ),
1229 mConfigurationManager( nullptr ),
1230 mPlatformAbstraction( nullptr ),
1231 mCallbackManager( nullptr ),
1232 mNotificationOnIdleInstalled( false ),
1233 mNotificationTrigger( nullptr ),
1234 mDaliFeedbackPlugin(),
1235 mFeedbackController( nullptr ),
1238 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1239 mPerformanceInterface( nullptr ),
1242 mObjectProfiler( nullptr ),
1244 mThreadMode( threadMode ),
1245 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1246 mUseRemoteSurface( false ),
1247 mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1249 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1250 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1252 gThreadLocalAdaptor = this;
1255 void Adaptor::SetRootLayoutDirection( std::string locale )
1257 mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1258 for ( auto& window : mWindows )
1260 Dali::Actor root = window->GetRootLayer();
1261 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1265 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1267 bool idleAdded( false );
1269 // Only add an idle if the Adaptor is actually running
1270 if( RUNNING == mState || READY == mState || forceAdd )
1272 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1284 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1286 mCallbackManager->RemoveIdleEntererCallback( callback );
1289 } // namespace Adaptor
1291 } // namespace Internal