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();
173 mCore = Integration::Core::New( *this,
174 *mPlatformAbstraction,
177 dataRetentionPolicy ,
178 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
179 mGraphics->GetDepthBufferRequired(),
180 mGraphics->GetStencilBufferRequired() );
182 defaultWindow->SetAdaptor( Get() );
184 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( defaultWindow ) );
187 mWindowCreatedSignal.Emit( window );
190 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
191 if( 0u < timeInterval )
193 mObjectProfiler = new ObjectProfiler( timeInterval );
196 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
198 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
200 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
202 // Should be called after Core creation
203 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
205 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
207 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
209 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
211 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
213 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
215 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
217 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
219 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
221 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
223 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
225 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
227 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
229 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
231 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
233 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
235 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
237 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
239 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
241 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
243 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
245 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
247 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
249 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
251 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
253 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
255 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
257 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
259 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
261 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
263 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
265 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
267 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
269 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
271 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
273 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
275 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
277 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
280 // Set max texture size
281 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
283 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
289 // Ensure stop status
292 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
293 gThreadLocalAdaptor = NULL;
295 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
297 (*iter)->OnDestroy();
300 // Clear out all the handles to Windows
303 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
304 delete mObjectProfiler;
308 delete mDisplayConnection;
309 delete mPlatformAbstraction;
310 delete mCallbackManager;
311 delete mPerformanceInterface;
313 mGraphics->Destroy();
315 // uninstall it on this thread (main actor thread)
316 Dali::Integration::Log::UninstallLogFunction();
318 // Delete environment options if we own it
319 if( mEnvironmentOptionsOwned )
321 delete mEnvironmentOptions;
325 void Adaptor::Start()
327 // It doesn't support restart after stop at this moment to support restarting, need more testing
328 if( READY != mState )
335 SetupSystemInformation();
337 // Start the callback manager
338 mCallbackManager->Start();
340 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
342 unsigned int dpiHor, dpiVer;
345 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
347 // set the DPI value for font rendering
348 FontClient fontClient = FontClient::Get();
349 fontClient.SetDpi( dpiHor, dpiVer );
351 // Tell the core the size of the surface just before we start the render-thread
352 mCore->SurfaceResized( defaultWindow->GetSurface() );
354 // Initialize the thread controller
355 mThreadController->Initialize();
357 ProcessCoreEvents(); // Ensure any startup messages are processed.
359 // Initialize the image loader plugin
360 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
362 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
368 // Dali::Internal::Adaptor::Adaptor::Pause
369 void Adaptor::Pause()
371 // Only pause the adaptor if we're actually running.
372 if( RUNNING == mState )
374 // Inform observers that we are about to be paused.
375 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
380 // Pause all windows event handlers when adaptor paused
381 for( auto window : mWindows )
386 mThreadController->Pause();
389 // Ensure any messages queued during pause callbacks are processed by doing another update.
392 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
396 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
400 // Dali::Internal::Adaptor::Adaptor::Resume
401 void Adaptor::Resume()
403 // Only resume the adaptor if we are in the suspended state.
404 if( PAUSED == mState )
408 // Reset the event handlers when adaptor resumed
409 for( auto window : mWindows )
414 // Inform observers that we have resumed.
415 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
420 // Trigger processing of events queued up while paused
421 mCore->ProcessEvents();
423 // Do at end to ensure our first update/render after resumption includes the processed messages as well
424 mThreadController->Resume();
426 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
430 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
436 if( RUNNING == mState ||
438 PAUSED_WHILE_HIDDEN == mState )
440 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
445 mThreadController->Stop();
447 // Delete the TTS player
448 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
452 mTtsPlayers[i].Reset();
456 // Destroy the image loader plugin
457 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
459 delete mNotificationTrigger;
460 mNotificationTrigger = NULL;
462 mCallbackManager->Stop();
466 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
470 void Adaptor::ContextLost()
472 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
475 void Adaptor::ContextRegained()
477 // Inform core, so that texture resources can be reloaded
478 mCore->RecoverFromContextLoss();
480 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
483 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
485 Integration::Point convertedPoint( point );
486 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
489 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
491 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
492 mWindows.front()->FeedWheelEvent( event );
495 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
497 Integration::KeyEvent convertedEvent( keyEvent );
498 mWindows.front()->FeedKeyEvent( convertedEvent );
501 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
503 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
504 for( auto windowPtr : mWindows )
506 if( windowPtr == windowImpl ) // the window is not deleted
508 // Let the core know the surface size has changed
509 mCore->SurfaceResized( &newSurface );
511 mResizedSignal.Emit( mAdaptor );
513 windowImpl->SetSurface( &newSurface );
515 // Flush the event queue to give the update-render thread chance
516 // to start processing messages for new camera setup etc as soon as possible
519 // This method blocks until the render thread has completed the replace.
520 mThreadController->ReplaceSurface( &newSurface );
526 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
528 // Flush the event queue to give the update-render thread chance
529 // to start processing messages for new camera setup etc as soon as possible
532 // This method blocks until the render thread has finished rendering the current surface.
533 mThreadController->DeleteSurface( &surface );
536 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
538 return *mWindows.front()->GetSurface();
541 void Adaptor::ReleaseSurfaceLock()
543 mWindows.front()->GetSurface()->ReleaseLock();
546 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
548 if( !mTtsPlayers[mode] )
550 // Create the TTS player when it needed, because it can reduce launching time.
551 mTtsPlayers[mode] = TtsPlayer::New(mode);
554 return mTtsPlayers[mode];
557 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
559 bool idleAdded(false);
561 // Only add an idle if the Adaptor is actually running
562 if( RUNNING == mState || READY == mState || forceAdd )
564 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
570 void Adaptor::RemoveIdle( CallbackBase* callback )
572 mCallbackManager->RemoveIdleCallback( callback );
575 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
577 mThreadController->SetPreRenderCallback( callback );
580 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
582 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
583 windowImpl.SetAdaptor( Get() );
585 // Add the new Window to the container - the order is not important
586 mWindows.push_back( &windowImpl );
588 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( &windowImpl ) );
591 mWindowCreatedSignal.Emit( window );
597 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
599 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
600 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
602 if( *iter == &windowImpl )
604 mWindows.erase( iter );
612 bool Adaptor::RemoveWindow( std::string childWindowName )
614 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
616 if( ( *iter )->GetName() == childWindowName )
618 mWindows.erase( iter );
626 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
628 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
630 if( ( *iter )->GetId() == childWindow->GetId() )
632 mWindows.erase( iter );
640 Dali::Adaptor& Adaptor::Get()
642 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
643 return gThreadLocalAdaptor->mAdaptor;
646 bool Adaptor::IsAvailable()
648 return gThreadLocalAdaptor != NULL;
651 void Adaptor::SceneCreated()
653 mCore->SceneCreated();
656 Dali::Integration::Core& Adaptor::GetCore()
661 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
663 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
666 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
668 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
669 return *mDisplayConnection;
672 GraphicsInterface& Adaptor::GetGraphicsInterface()
674 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
678 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
680 return *mPlatformAbstraction;
683 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
685 return *mNotificationTrigger;
688 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
690 return mTriggerEventFactory;
693 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
695 return mSocketFactory;
698 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
700 if( !mWindows.empty() )
702 return mWindows.front()->GetSurface();
708 TraceInterface& Adaptor::GetKernelTraceInterface()
710 return mKernelTracer;
713 TraceInterface& Adaptor::GetSystemTraceInterface()
715 return mSystemTracer;
718 PerformanceInterface* Adaptor::GetPerformanceInterface()
720 return mPerformanceInterface;
723 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
725 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
726 return *mPlatformAbstraction;
729 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
731 if( mTtsPlayers[mode] )
733 mTtsPlayers[mode].Reset();
737 Any Adaptor::GetNativeWindowHandle()
739 return mWindows.front()->GetNativeHandle();
742 Any Adaptor::GetGraphicsDisplay()
748 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
750 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
751 display = eglImpl.GetDisplay();
757 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
759 mUseRemoteSurface = useRemoteSurface;
762 void Adaptor::AddObserver( LifeCycleObserver& observer )
764 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
766 if ( match == mObservers.end() )
768 mObservers.push_back( &observer );
772 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
774 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
776 if ( match != mObservers.end() )
778 mObservers.erase( match );
782 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
786 mCore->QueueEvent(event);
790 void Adaptor::ProcessCoreEvents()
794 if( mPerformanceInterface )
796 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
799 mCore->ProcessEvents();
801 if( mPerformanceInterface )
803 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
808 void Adaptor::RequestUpdate( bool forceUpdate )
814 mThreadController->RequestUpdate();
818 case PAUSED_WHILE_HIDDEN:
820 // When Dali applications are partially visible behind the lock-screen,
821 // the indicator must be updated (therefore allow updates in the PAUSED state)
824 mThreadController->RequestUpdateOnce();
836 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
838 // Only request a notification if the Adaptor is actually running
839 // and we haven't installed the idle notification
840 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
842 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
846 void Adaptor::OnWindowShown()
848 if( PAUSED_WHILE_HIDDEN == mState )
850 // Adaptor can now be resumed
855 // Force a render task
858 else if( RUNNING == mState )
860 // Force a render task
863 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
867 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
871 void Adaptor::OnWindowHidden()
873 if( RUNNING == mState || READY == mState )
875 bool allWindowsHidden = true;
877 for( auto window : mWindows )
879 if ( window->IsVisible() )
881 allWindowsHidden = false;
886 // Only pause the adaptor when all the windows are hidden
887 if( allWindowsHidden )
889 if( mState == RUNNING )
893 // Adaptor cannot be resumed until any window is shown
894 mState = PAUSED_WHILE_HIDDEN;
896 else // mState is READY
898 // Pause the adaptor after the state gets RUNNING
899 mState = PAUSED_WHILE_INITIALIZING;
904 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
909 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
913 // Dali::Internal::Adaptor::Adaptor::OnDamaged
914 void Adaptor::OnDamaged( const DamageArea& area )
916 // This is needed for the case where Dali window is partially obscured
917 RequestUpdate( false );
920 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
922 // Let the core know the surface size has changed
923 mCore->SurfaceResized( surface );
925 mResizedSignal.Emit( mAdaptor );
928 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
930 // Flush the event queue to give the update-render thread chance
931 // to start processing messages for new camera setup etc as soon as possible
934 mThreadController->ResizeSurface();
937 void Adaptor::NotifySceneCreated()
939 GetCore().SceneCreated();
941 // Flush the event queue to give the update-render thread chance
942 // to start processing messages for new camera setup etc as soon as possible
945 // Start thread controller after the scene has been created
946 mThreadController->Start();
948 // Process after surface is created (registering to remote surface provider if required)
949 SurfaceInitialized();
951 if( mState != PAUSED_WHILE_INITIALIZING )
955 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
963 mState = PAUSED_WHILE_HIDDEN;
965 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
969 void Adaptor::NotifyLanguageChanged()
971 mLanguageChangedSignal.Emit( mAdaptor );
974 void Adaptor::RenderOnce()
979 const LogFactoryInterface& Adaptor::GetLogFactory()
981 return *mEnvironmentOptions;
984 void Adaptor::RegisterProcessor( Integration::Processor& processor )
986 GetCore().RegisterProcessor(processor);
989 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
991 GetCore().UnregisterProcessor(processor);
994 void Adaptor::RequestUpdateOnce()
996 if( mThreadController )
998 mThreadController->RequestUpdateOnce();
1002 bool Adaptor::ProcessCoreEventsFromIdle()
1004 ProcessCoreEvents();
1006 // the idle handle automatically un-installs itself
1007 mNotificationOnIdleInstalled = false;
1012 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1014 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1016 for( auto window : mWindows )
1018 if ( scene == window->GetScene() )
1027 Dali::WindowContainer Adaptor::GetWindows() const
1029 Dali::WindowContainer windows;
1031 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1033 // Downcast to Dali::Window
1034 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1037 windows.push_back( window );
1044 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1046 mLanguageChangedSignal(),
1047 mWindowCreatedSignal(),
1048 mAdaptor( adaptor ),
1051 mThreadController( nullptr ),
1052 mGraphics( nullptr ),
1053 mDisplayConnection( nullptr ),
1055 mPlatformAbstraction( nullptr ),
1056 mCallbackManager( nullptr ),
1057 mNotificationOnIdleInstalled( false ),
1058 mNotificationTrigger( nullptr ),
1059 mDaliFeedbackPlugin(),
1060 mFeedbackController( nullptr ),
1063 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1064 mPerformanceInterface( nullptr ),
1067 mTriggerEventFactory(),
1068 mObjectProfiler( nullptr ),
1070 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1071 mUseRemoteSurface( false )
1073 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1074 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1076 gThreadLocalAdaptor = this;
1079 void Adaptor::SetRootLayoutDirection( std::string locale )
1081 Dali::Stage stage = Dali::Stage::GetCurrent();
1083 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1084 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1087 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1089 bool idleAdded( false );
1091 // Only add an idle if the Adaptor is actually running
1092 if( RUNNING == mState || READY == mState || forceAdd )
1094 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1100 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1102 mCallbackManager->RemoveIdleEntererCallback( callback );
1105 } // namespace Adaptor
1107 } // namespace Internal