2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/key-event-integ.h>
33 #include <dali/integration-api/events/touch-event-integ.h>
34 #include <dali/integration-api/events/wheel-event-integ.h>
35 #include <dali/integration-api/processor-interface.h>
38 #include <dali/public-api/dali-adaptor-common.h>
39 #include <dali/internal/system/common/thread-controller.h>
40 #include <dali/internal/system/common/performance-interface-factory.h>
41 #include <dali/internal/adaptor/common/lifecycle-observer.h>
43 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
44 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
46 #include <dali/devel-api/text-abstraction/font-client.h>
48 #include <dali/internal/system/common/callback-manager.h>
49 #include <dali/internal/accessibility/common/tts-player-impl.h>
50 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
51 #include <dali/internal/window-system/common/event-handler.h>
52 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
53 #include <dali/internal/graphics/gles/gl-implementation.h>
54 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
55 #include <dali/internal/graphics/common/egl-image-extensions.h>
56 #include <dali/internal/clipboard/common/clipboard-impl.h>
57 #include <dali/internal/system/common/object-profiler.h>
58 #include <dali/internal/window-system/common/display-connection.h>
59 #include <dali/internal/window-system/common/window-impl.h>
60 #include <dali/internal/window-system/common/window-render-surface.h>
62 #include <dali/internal/system/common/logging.h>
64 #include <dali/internal/system/common/locale-utils.h>
65 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
66 #include <dali/internal/imaging/common/image-loader.h>
69 using Dali::TextAbstraction::FontClient;
82 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
83 } // unnamed namespace
85 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
87 Dali::Adaptor* adaptor = new Dali::Adaptor;
88 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
89 adaptor->mImpl = impl;
91 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
92 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
94 impl->Initialize( graphicsFactory, configuration );
95 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
100 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
102 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
103 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
104 windowImpl.SetAdaptor( *adaptor );
108 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
110 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
111 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
112 adaptor->mImpl = impl;
114 impl->Initialize( graphicsFactory, configuration );
119 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
121 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
122 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
123 windowImpl.SetAdaptor( *adaptor );
127 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
129 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
130 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
131 mEnvironmentOptions->SetLogFunction( logFunction );
132 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
134 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
137 GetDataStoragePath( path );
138 mPlatformAbstraction->SetDataStoragePath( path );
140 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
141 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
143 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
146 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
148 if( mEnvironmentOptions->PerformanceServerRequired() )
150 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
153 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
154 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
156 mCallbackManager = CallbackManager::New();
158 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
160 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
162 mGraphics = &( graphicsFactory.Create() );
163 mGraphics->Initialize( mEnvironmentOptions );
165 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
167 // This will only be created once
168 eglGraphics->Create();
170 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
171 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
172 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
174 mCore = Integration::Core::New( *this,
175 *mPlatformAbstraction,
178 eglContextHelperImpl,
179 dataRetentionPolicy ,
180 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
181 mGraphics->GetDepthBufferRequired(),
182 mGraphics->GetStencilBufferRequired() );
184 defaultWindow->SetAdaptor( Get() );
186 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( defaultWindow ) );
189 mWindowCreatedSignal.Emit( window );
192 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
193 if( 0u < timeInterval )
195 mObjectProfiler = new ObjectProfiler( timeInterval );
198 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
200 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
202 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
204 // Should be called after Core creation
205 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
207 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
209 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
211 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
213 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
215 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
217 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
219 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
221 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
223 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
225 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
227 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
229 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
231 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
233 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
235 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
237 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
239 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
241 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
243 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
245 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
247 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
249 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
251 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
253 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
255 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
257 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
259 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
261 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
263 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
265 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
267 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
269 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
271 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
273 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
275 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
277 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
279 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
282 // Set max texture size
283 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
285 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
291 // Ensure stop status
294 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
295 gThreadLocalAdaptor = NULL;
297 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
299 (*iter)->OnDestroy();
302 // Clear out all the handles to Windows
305 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
306 delete mObjectProfiler;
310 delete mDisplayConnection;
311 delete mPlatformAbstraction;
312 delete mCallbackManager;
313 delete mPerformanceInterface;
315 mGraphics->Destroy();
317 // uninstall it on this thread (main actor thread)
318 Dali::Integration::Log::UninstallLogFunction();
320 // Delete environment options if we own it
321 if( mEnvironmentOptionsOwned )
323 delete mEnvironmentOptions;
327 void Adaptor::Start()
329 // It doesn't support restart after stop at this moment to support restarting, need more testing
330 if( READY != mState )
337 SetupSystemInformation();
339 // Start the callback manager
340 mCallbackManager->Start();
342 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
344 unsigned int dpiHor, dpiVer;
347 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
349 // set the DPI value for font rendering
350 FontClient fontClient = FontClient::Get();
351 fontClient.SetDpi( dpiHor, dpiVer );
353 // Tell the core the size of the surface just before we start the render-thread
354 mCore->SurfaceResized( defaultWindow->GetSurface() );
356 // Initialize the thread controller
357 mThreadController->Initialize();
359 ProcessCoreEvents(); // Ensure any startup messages are processed.
361 // Initialize the image loader plugin
362 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
364 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
370 // Dali::Internal::Adaptor::Adaptor::Pause
371 void Adaptor::Pause()
373 // Only pause the adaptor if we're actually running.
374 if( RUNNING == mState )
376 // Inform observers that we are about to be paused.
377 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
382 // Pause all windows event handlers when adaptor paused
383 for( auto window : mWindows )
388 mThreadController->Pause();
391 // Ensure any messages queued during pause callbacks are processed by doing another update.
394 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
398 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
402 // Dali::Internal::Adaptor::Adaptor::Resume
403 void Adaptor::Resume()
405 // Only resume the adaptor if we are in the suspended state.
406 if( PAUSED == mState )
410 // Reset the event handlers when adaptor resumed
411 for( auto window : mWindows )
416 // Inform observers that we have resumed.
417 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
422 // Trigger processing of events queued up while paused
423 mCore->ProcessEvents();
425 // Do at end to ensure our first update/render after resumption includes the processed messages as well
426 mThreadController->Resume();
428 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
432 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
438 if( RUNNING == mState ||
440 PAUSED_WHILE_HIDDEN == mState )
442 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
447 mThreadController->Stop();
449 // Delete the TTS player
450 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
454 mTtsPlayers[i].Reset();
458 // Destroy the image loader plugin
459 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
461 delete mNotificationTrigger;
462 mNotificationTrigger = NULL;
464 mCallbackManager->Stop();
468 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
472 void Adaptor::ContextLost()
474 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
477 void Adaptor::ContextRegained()
479 // Inform core, so that texture resources can be reloaded
480 mCore->RecoverFromContextLoss();
482 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
485 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
487 Integration::Point convertedPoint( point );
488 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
491 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
493 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
494 mWindows.front()->FeedWheelEvent( event );
497 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
499 Integration::KeyEvent convertedEvent( keyEvent );
500 mWindows.front()->FeedKeyEvent( convertedEvent );
503 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
505 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
506 for( auto windowPtr : mWindows )
508 if( windowPtr == windowImpl ) // the window is not deleted
510 // Let the core know the surface size has changed
511 mCore->SurfaceResized( &newSurface );
513 mResizedSignal.Emit( mAdaptor );
515 windowImpl->SetSurface( &newSurface );
517 // Flush the event queue to give the update-render thread chance
518 // to start processing messages for new camera setup etc as soon as possible
521 // This method blocks until the render thread has completed the replace.
522 mThreadController->ReplaceSurface( &newSurface );
528 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
530 // Flush the event queue to give the update-render thread chance
531 // to start processing messages for new camera setup etc as soon as possible
534 // This method blocks until the render thread has finished rendering the current surface.
535 mThreadController->DeleteSurface( &surface );
538 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
540 return *mWindows.front()->GetSurface();
543 void Adaptor::ReleaseSurfaceLock()
545 mWindows.front()->GetSurface()->ReleaseLock();
548 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
550 if( !mTtsPlayers[mode] )
552 // Create the TTS player when it needed, because it can reduce launching time.
553 mTtsPlayers[mode] = TtsPlayer::New(mode);
556 return mTtsPlayers[mode];
559 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
561 bool idleAdded(false);
563 // Only add an idle if the Adaptor is actually running
564 if( RUNNING == mState || READY == mState || forceAdd )
566 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
572 void Adaptor::RemoveIdle( CallbackBase* callback )
574 mCallbackManager->RemoveIdleCallback( callback );
577 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
579 mThreadController->SetPreRenderCallback( callback );
582 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
584 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
585 windowImpl.SetAdaptor( Get() );
587 // Add the new Window to the container - the order is not important
588 mWindows.push_back( &windowImpl );
590 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
593 mWindowCreatedSignal.Emit( window );
599 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
601 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
602 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
604 if( *iter == &windowImpl )
606 mWindows.erase( iter );
614 bool Adaptor::RemoveWindow( std::string childWindowName )
616 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
618 if( ( *iter )->GetName() == childWindowName )
620 mWindows.erase( iter );
628 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
630 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
632 if( ( *iter )->GetId() == childWindow->GetId() )
634 mWindows.erase( iter );
642 Dali::Adaptor& Adaptor::Get()
644 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
645 return gThreadLocalAdaptor->mAdaptor;
648 bool Adaptor::IsAvailable()
650 return gThreadLocalAdaptor != NULL;
653 void Adaptor::SceneCreated()
655 mCore->SceneCreated();
658 Dali::Integration::Core& Adaptor::GetCore()
663 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
665 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
668 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
670 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
671 return *mDisplayConnection;
674 GraphicsInterface& Adaptor::GetGraphicsInterface()
676 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
680 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
682 return *mPlatformAbstraction;
685 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
687 return *mNotificationTrigger;
690 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
692 return mTriggerEventFactory;
695 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
697 return mSocketFactory;
700 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
702 if( !mWindows.empty() )
704 return mWindows.front()->GetSurface();
710 TraceInterface& Adaptor::GetKernelTraceInterface()
712 return mKernelTracer;
715 TraceInterface& Adaptor::GetSystemTraceInterface()
717 return mSystemTracer;
720 PerformanceInterface* Adaptor::GetPerformanceInterface()
722 return mPerformanceInterface;
725 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
727 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
728 return *mPlatformAbstraction;
731 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
733 if( mTtsPlayers[mode] )
735 mTtsPlayers[mode].Reset();
739 Any Adaptor::GetNativeWindowHandle()
741 return mWindows.front()->GetNativeHandle();
744 Any Adaptor::GetGraphicsDisplay()
750 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
752 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
753 display = eglImpl.GetDisplay();
759 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
761 mUseRemoteSurface = useRemoteSurface;
764 void Adaptor::AddObserver( LifeCycleObserver& observer )
766 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
768 if ( match == mObservers.end() )
770 mObservers.push_back( &observer );
774 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
776 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
778 if ( match != mObservers.end() )
780 mObservers.erase( match );
784 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
788 mCore->QueueEvent(event);
792 void Adaptor::ProcessCoreEvents()
796 if( mPerformanceInterface )
798 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
801 mCore->ProcessEvents();
803 if( mPerformanceInterface )
805 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
810 void Adaptor::RequestUpdate( bool forceUpdate )
816 mThreadController->RequestUpdate();
820 case PAUSED_WHILE_HIDDEN:
822 // When Dali applications are partially visible behind the lock-screen,
823 // the indicator must be updated (therefore allow updates in the PAUSED state)
826 mThreadController->RequestUpdateOnce();
838 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
840 // Only request a notification if the Adaptor is actually running
841 // and we haven't installed the idle notification
842 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
844 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
848 void Adaptor::OnWindowShown()
850 if( PAUSED_WHILE_HIDDEN == mState )
852 // Adaptor can now be resumed
857 // Force a render task
860 else if( RUNNING == mState )
862 // Force a render task
865 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
869 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
873 void Adaptor::OnWindowHidden()
875 if( RUNNING == mState || READY == mState )
877 bool allWindowsHidden = true;
879 for( auto window : mWindows )
881 if ( window->IsVisible() )
883 allWindowsHidden = false;
888 // Only pause the adaptor when all the windows are hidden
889 if( allWindowsHidden )
891 if( mState == RUNNING )
895 // Adaptor cannot be resumed until any window is shown
896 mState = PAUSED_WHILE_HIDDEN;
898 else // mState is READY
900 // Pause the adaptor after the state gets RUNNING
901 mState = PAUSED_WHILE_INITIALIZING;
906 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
911 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
915 // Dali::Internal::Adaptor::Adaptor::OnDamaged
916 void Adaptor::OnDamaged( const DamageArea& area )
918 // This is needed for the case where Dali window is partially obscured
919 RequestUpdate( false );
922 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
924 // Let the core know the surface size has changed
925 mCore->SurfaceResized( surface );
927 mResizedSignal.Emit( mAdaptor );
930 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
932 // Flush the event queue to give the update-render thread chance
933 // to start processing messages for new camera setup etc as soon as possible
936 mThreadController->ResizeSurface();
939 void Adaptor::NotifySceneCreated()
941 GetCore().SceneCreated();
943 // Flush the event queue to give the update-render thread chance
944 // to start processing messages for new camera setup etc as soon as possible
947 // Start thread controller after the scene has been created
948 mThreadController->Start();
950 // Process after surface is created (registering to remote surface provider if required)
951 SurfaceInitialized();
953 if( mState != PAUSED_WHILE_INITIALIZING )
957 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
965 mState = PAUSED_WHILE_HIDDEN;
967 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
971 void Adaptor::NotifyLanguageChanged()
973 mLanguageChangedSignal.Emit( mAdaptor );
976 void Adaptor::RenderOnce()
981 const LogFactoryInterface& Adaptor::GetLogFactory()
983 return *mEnvironmentOptions;
986 void Adaptor::RegisterProcessor( Integration::Processor& processor )
988 GetCore().RegisterProcessor(processor);
991 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
993 GetCore().UnregisterProcessor(processor);
996 void Adaptor::RequestUpdateOnce()
998 if( mThreadController )
1000 mThreadController->RequestUpdateOnce();
1004 bool Adaptor::ProcessCoreEventsFromIdle()
1006 ProcessCoreEvents();
1008 // the idle handle automatically un-installs itself
1009 mNotificationOnIdleInstalled = false;
1014 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1016 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1018 for( auto window : mWindows )
1020 if ( scene == window->GetScene() )
1029 Dali::WindowContainer Adaptor::GetWindows() const
1031 Dali::WindowContainer windows;
1033 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1035 // Downcast to Dali::Window
1036 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1039 windows.push_back( window );
1046 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1048 mLanguageChangedSignal(),
1049 mWindowCreatedSignal(),
1050 mAdaptor( adaptor ),
1053 mThreadController( nullptr ),
1054 mGraphics( nullptr ),
1055 mDisplayConnection( nullptr ),
1057 mPlatformAbstraction( nullptr ),
1058 mCallbackManager( nullptr ),
1059 mNotificationOnIdleInstalled( false ),
1060 mNotificationTrigger( nullptr ),
1061 mDaliFeedbackPlugin(),
1062 mFeedbackController( nullptr ),
1065 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1066 mPerformanceInterface( nullptr ),
1069 mTriggerEventFactory(),
1070 mObjectProfiler( nullptr ),
1072 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1073 mUseRemoteSurface( false )
1075 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1076 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1078 gThreadLocalAdaptor = this;
1081 void Adaptor::SetRootLayoutDirection( std::string locale )
1083 Dali::Stage stage = Dali::Stage::GetCurrent();
1085 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1086 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1089 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1091 bool idleAdded( false );
1093 // Only add an idle if the Adaptor is actually running
1094 if( RUNNING == mState || READY == mState || forceAdd )
1096 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1102 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1104 mCallbackManager->RemoveIdleEntererCallback( callback );
1107 } // namespace Adaptor
1109 } // namespace Internal