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 ProcessCoreEvents(); // Ensure any startup messages are processed.
432 // Initialize the image loader plugin
433 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
435 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
442 mAddOnManager->Start();
446 // Dali::Internal::Adaptor::Adaptor::Pause
447 void Adaptor::Pause()
449 // Only pause the adaptor if we're actually running.
450 if( RUNNING == mState )
452 // Inform observers that we are about to be paused.
453 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
461 mAddOnManager->Pause();
464 // Pause all windows event handlers when adaptor paused
465 for( auto window : mWindows )
470 mThreadController->Pause();
473 // Ensure any messages queued during pause callbacks are processed by doing another update.
476 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
480 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
484 // Dali::Internal::Adaptor::Adaptor::Resume
485 void Adaptor::Resume()
487 // Only resume the adaptor if we are in the suspended state.
488 if( PAUSED == mState )
492 // Reset the event handlers when adaptor resumed
493 for( auto window : mWindows )
498 // Resume AddOnManager
501 mAddOnManager->Resume();
504 // Inform observers that we have resumed.
505 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
510 // Trigger processing of events queued up while paused
511 mCore->ProcessEvents();
513 // Do at end to ensure our first update/render after resumption includes the processed messages as well
514 mThreadController->Resume();
516 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
520 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
526 if( RUNNING == mState ||
528 PAUSED_WHILE_HIDDEN == mState )
530 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
537 mAddOnManager->Stop();
540 mThreadController->Stop();
542 // Delete the TTS player
543 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
547 mTtsPlayers[i].Reset();
551 // Destroy the image loader plugin
552 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
554 delete mNotificationTrigger;
555 mNotificationTrigger = NULL;
557 mCallbackManager->Stop();
561 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
565 void Adaptor::ContextLost()
567 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
570 void Adaptor::ContextRegained()
572 // Inform core, so that texture resources can be reloaded
573 mCore->RecoverFromContextLoss();
575 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
578 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
580 Integration::Point convertedPoint( point );
581 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
584 void Adaptor::FeedWheelEvent( Dali::WheelEvent& wheelEvent )
586 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >( wheelEvent.GetType() ), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime() );
587 mWindows.front()->FeedWheelEvent( event );
590 void Adaptor::FeedKeyEvent( Dali::KeyEvent& keyEvent )
592 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() );
593 mWindows.front()->FeedKeyEvent( convertedEvent );
596 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
598 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
599 for( auto windowPtr : mWindows )
601 if( windowPtr == windowImpl ) // the window is not deleted
603 mResizedSignal.Emit( mAdaptor );
605 windowImpl->SetSurface( &newSurface );
607 // Flush the event queue to give the update-render thread chance
608 // to start processing messages for new camera setup etc as soon as possible
611 // This method blocks until the render thread has completed the replace.
612 mThreadController->ReplaceSurface( &newSurface );
618 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
620 // Flush the event queue to give the update-render thread chance
621 // to start processing messages for new camera setup etc as soon as possible
624 // This method blocks until the render thread has finished rendering the current surface.
625 mThreadController->DeleteSurface( &surface );
628 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
630 return *mWindows.front()->GetSurface();
633 void Adaptor::ReleaseSurfaceLock()
635 mWindows.front()->GetSurface()->ReleaseLock();
638 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
640 if( !mTtsPlayers[mode] )
642 // Create the TTS player when it needed, because it can reduce launching time.
643 mTtsPlayers[mode] = TtsPlayer::New(mode);
646 return mTtsPlayers[mode];
649 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
651 bool idleAdded(false);
653 // Only add an idle if the Adaptor is actually running
654 if( RUNNING == mState || READY == mState || forceAdd )
656 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
662 void Adaptor::RemoveIdle( CallbackBase* callback )
664 mCallbackManager->RemoveIdleCallback( callback );
667 void Adaptor::ProcessIdle()
669 bool idleProcessed = mCallbackManager->ProcessIdle();
670 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
673 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
675 mThreadController->SetPreRenderCallback( callback );
678 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
680 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
681 windowImpl.SetAdaptor( Get() );
683 // ChildWindow is set to the layout direction of the default window.
684 windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
686 // Add the new Window to the container - the order is not important
687 mWindows.push_back( &windowImpl );
689 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
691 mThreadController->AddSurface( surface );
693 mWindowCreatedSignal.Emit( childWindow );
698 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
700 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
701 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
703 if( *iter == &windowImpl )
705 mWindows.erase( iter );
713 bool Adaptor::RemoveWindow( std::string childWindowName )
715 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
717 if( ( *iter )->GetName() == childWindowName )
719 mWindows.erase( iter );
727 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
729 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
731 if( ( *iter )->GetId() == childWindow->GetId() )
733 mWindows.erase( iter );
741 Dali::Adaptor& Adaptor::Get()
743 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
744 return gThreadLocalAdaptor->mAdaptor;
747 bool Adaptor::IsAvailable()
749 return gThreadLocalAdaptor != NULL;
752 void Adaptor::SceneCreated()
754 mCore->SceneCreated();
757 Dali::Integration::Core& Adaptor::GetCore()
762 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
764 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
767 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
769 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
770 return *mDisplayConnection;
773 GraphicsInterface& Adaptor::GetGraphicsInterface()
775 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
776 return *( mGraphics.get() );
779 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
781 return *mPlatformAbstraction;
784 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
786 return *mNotificationTrigger;
789 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
791 return mSocketFactory;
794 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
796 if( !mWindows.empty() )
798 return mWindows.front()->GetSurface();
804 TraceInterface& Adaptor::GetKernelTraceInterface()
806 return mKernelTracer;
809 TraceInterface& Adaptor::GetSystemTraceInterface()
811 return mSystemTracer;
814 PerformanceInterface* Adaptor::GetPerformanceInterface()
816 return mPerformanceInterface;
819 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
821 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
822 return *mPlatformAbstraction;
825 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
830 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
832 if( mTtsPlayers[mode] )
834 mTtsPlayers[mode].Reset();
838 Any Adaptor::GetNativeWindowHandle()
840 return mWindows.front()->GetNativeHandle();
843 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
845 Any nativeWindowHandle;
847 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
849 for( auto sceneHolder : mWindows )
851 if ( scene == sceneHolder->GetScene() )
853 nativeWindowHandle = sceneHolder->GetNativeHandle();
858 return nativeWindowHandle;
861 Any Adaptor::GetGraphicsDisplay()
867 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
868 auto eglGraphics = static_cast<EglGraphics *>( graphics );
870 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
871 display = eglImpl.GetDisplay();
877 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
879 mUseRemoteSurface = useRemoteSurface;
882 void Adaptor::AddObserver( LifeCycleObserver& observer )
884 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
886 if ( match == mObservers.end() )
888 mObservers.push_back( &observer );
892 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
894 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
896 if ( match != mObservers.end() )
898 mObservers.erase( match );
902 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
906 mCore->QueueEvent(event);
910 void Adaptor::ProcessCoreEvents()
914 if( mPerformanceInterface )
916 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
919 mCore->ProcessEvents();
921 if( mPerformanceInterface )
923 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
928 void Adaptor::RequestUpdate( bool forceUpdate )
934 mThreadController->RequestUpdate();
938 case PAUSED_WHILE_HIDDEN:
942 // Update (and resource upload) without rendering
943 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
955 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
957 // Only request a notification if the Adaptor is actually running
958 // and we haven't installed the idle notification
959 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
961 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
965 void Adaptor::OnWindowShown()
967 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
969 if( PAUSED_WHILE_HIDDEN == mState )
971 // Adaptor can now be resumed
976 // Force a render task
979 else if( RUNNING == mState )
981 // Force a render task
984 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
986 else if( PAUSED_WHILE_INITIALIZING == mState )
988 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
993 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
997 void Adaptor::OnWindowHidden()
999 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
1001 if( RUNNING == mState || READY == mState )
1003 bool allWindowsHidden = true;
1005 for( auto window : mWindows )
1007 if ( window->IsVisible() )
1009 allWindowsHidden = false;
1014 // Only pause the adaptor when all the windows are hidden
1015 if( allWindowsHidden )
1017 if( mState == RUNNING )
1021 // Adaptor cannot be resumed until any window is shown
1022 mState = PAUSED_WHILE_HIDDEN;
1024 else // mState is READY
1026 // Pause the adaptor after the state gets RUNNING
1027 mState = PAUSED_WHILE_INITIALIZING;
1032 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1037 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1041 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1042 void Adaptor::OnDamaged( const DamageArea& area )
1044 // This is needed for the case where Dali window is partially obscured
1045 RequestUpdate( false );
1048 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1050 mResizedSignal.Emit( mAdaptor );
1053 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1055 // Nofify surface resizing before flushing event queue
1056 mThreadController->ResizeSurface();
1058 // Flush the event queue to give the update-render thread chance
1059 // to start processing messages for new camera setup etc as soon as possible
1060 ProcessCoreEvents();
1063 void Adaptor::NotifySceneCreated()
1065 GetCore().SceneCreated();
1067 // Flush the event queue to give the update-render thread chance
1068 // to start processing messages for new camera setup etc as soon as possible
1069 ProcessCoreEvents();
1071 // Start thread controller after the scene has been created
1072 mThreadController->Start();
1074 // Process after surface is created (registering to remote surface provider if required)
1075 SurfaceInitialized();
1077 if( mState != PAUSED_WHILE_INITIALIZING )
1081 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1089 mState = PAUSED_WHILE_HIDDEN;
1091 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1095 void Adaptor::NotifyLanguageChanged()
1097 mLanguageChangedSignal.Emit( mAdaptor );
1100 void Adaptor::RenderOnce()
1102 if( mThreadController )
1104 UpdateMode updateMode;
1105 if( mThreadMode == ThreadMode::NORMAL )
1107 updateMode = UpdateMode::NORMAL;
1111 updateMode = UpdateMode::FORCE_RENDER;
1113 ProcessCoreEvents();
1115 mThreadController->RequestUpdateOnce( updateMode );
1119 const LogFactoryInterface& Adaptor::GetLogFactory()
1121 return *mEnvironmentOptions;
1124 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1126 GetCore().RegisterProcessor(processor);
1129 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1131 GetCore().UnregisterProcessor(processor);
1134 bool Adaptor::IsMultipleWindowSupported() const
1136 return mConfigurationManager->IsMultipleWindowSupported();
1139 void Adaptor::RequestUpdateOnce()
1141 if( mThreadController )
1143 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1147 bool Adaptor::ProcessCoreEventsFromIdle()
1149 ProcessCoreEvents();
1151 // the idle handle automatically un-installs itself
1152 mNotificationOnIdleInstalled = false;
1157 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1159 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1161 for( auto window : mWindows )
1163 if ( scene == window->GetScene() )
1172 Dali::WindowContainer Adaptor::GetWindows() const
1174 Dali::WindowContainer windows;
1176 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1178 // Downcast to Dali::Window
1179 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1182 windows.push_back( window );
1189 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1191 Dali::SceneHolderList sceneHolderList;
1193 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1195 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1198 return sceneHolderList;
1201 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1203 Dali::ObjectRegistry registry;
1206 registry = mCore->GetObjectRegistry();
1211 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1213 mLanguageChangedSignal(),
1214 mWindowCreatedSignal(),
1215 mAdaptor( adaptor ),
1218 mThreadController( nullptr ),
1219 mGraphics( nullptr ),
1220 mDisplayConnection( nullptr ),
1222 mConfigurationManager( nullptr ),
1223 mPlatformAbstraction( nullptr ),
1224 mCallbackManager( nullptr ),
1225 mNotificationOnIdleInstalled( false ),
1226 mNotificationTrigger( nullptr ),
1227 mDaliFeedbackPlugin(),
1228 mFeedbackController( nullptr ),
1231 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1232 mPerformanceInterface( nullptr ),
1235 mObjectProfiler( nullptr ),
1237 mThreadMode( threadMode ),
1238 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1239 mUseRemoteSurface( false ),
1240 mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1242 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1243 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1245 gThreadLocalAdaptor = this;
1248 void Adaptor::SetRootLayoutDirection( std::string locale )
1250 mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1251 for ( auto& window : mWindows )
1253 Dali::Actor root = window->GetRootLayer();
1254 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1258 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1260 bool idleAdded( false );
1262 // Only add an idle if the Adaptor is actually running
1263 if( RUNNING == mState || READY == mState || forceAdd )
1265 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1277 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1279 mCallbackManager->RemoveIdleEntererCallback( callback );
1282 } // namespace Adaptor
1284 } // namespace Internal