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/adaptor/common/adaptor-builder-impl.h>
25 #include <dali/public-api/common/stage.h>
26 #include <dali/public-api/actors/layer.h>
27 #include <dali/public-api/object/any.h>
28 #include <dali/devel-api/actors/actor-devel.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/integration-api/core.h>
31 #include <dali/integration-api/context-notifier.h>
32 #include <dali/integration-api/profiling.h>
33 #include <dali/integration-api/input-options.h>
34 #include <dali/integration-api/events/key-event-integ.h>
35 #include <dali/integration-api/events/touch-event-integ.h>
36 #include <dali/integration-api/events/wheel-event-integ.h>
37 #include <dali/integration-api/processor-interface.h>
40 #include <dali/public-api/dali-adaptor-common.h>
41 #include <dali/internal/system/common/thread-controller.h>
42 #include <dali/internal/system/common/performance-interface-factory.h>
43 #include <dali/internal/adaptor/common/lifecycle-observer.h>
44 #include <dali/internal/adaptor/common/thread-controller-interface.h>
46 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
47 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
49 #include <dali/devel-api/text-abstraction/font-client.h>
51 #include <dali/internal/system/common/callback-manager.h>
52 #include <dali/internal/accessibility/common/tts-player-impl.h>
53 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
54 #include <dali/internal/window-system/common/event-handler.h>
55 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
56 #include <dali/internal/graphics/gles/gl-implementation.h>
57 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
58 #include <dali/internal/graphics/common/egl-image-extensions.h>
59 #include <dali/internal/clipboard/common/clipboard-impl.h>
60 #include <dali/internal/system/common/object-profiler.h>
61 #include <dali/internal/window-system/common/display-connection.h>
62 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
63 #include <dali/internal/window-system/common/window-impl.h>
64 #include <dali/internal/window-system/common/window-render-surface.h>
66 #include <dali/internal/system/common/logging.h>
68 #include <dali/internal/system/common/locale-utils.h>
69 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
70 #include <dali/internal/imaging/common/image-loader.h>
72 #include <dali/internal/system/common/configuration-manager.h>
73 #include <dali/internal/system/common/environment-variables.h>
75 using Dali::TextAbstraction::FontClient;
77 extern std::string GetSystemCachePath();
91 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
93 } // unnamed namespace
95 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
97 Dali::Adaptor* adaptor = new Dali::Adaptor;
98 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
99 adaptor->mImpl = impl;
101 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
102 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
104 impl->Initialize( graphicsFactory, configuration );
105 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
110 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
112 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
113 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
114 windowImpl.SetAdaptor( *adaptor );
118 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
120 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
121 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
122 adaptor->mImpl = impl;
124 impl->Initialize( graphicsFactory, configuration );
129 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
131 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
132 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
133 windowImpl.SetAdaptor( *adaptor );
137 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
139 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
140 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
141 mEnvironmentOptions->SetLogFunction( logFunction );
142 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
144 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
147 GetDataStoragePath( path );
148 mPlatformAbstraction->SetDataStoragePath( path );
150 if( mEnvironmentOptions->PerformanceServerRequired() )
152 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
155 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
156 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
158 mCallbackManager = CallbackManager::New();
160 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
162 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
164 mGraphics = &( graphicsFactory.Create() );
165 mGraphics->Initialize( mEnvironmentOptions );
167 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
169 // This will only be created once
170 eglGraphics->Create();
172 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
173 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
174 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
176 mCore = Integration::Core::New( *this,
177 *mPlatformAbstraction,
180 eglContextHelperImpl,
181 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
182 mGraphics->GetDepthBufferRequired(),
183 mGraphics->GetStencilBufferRequired() );
185 defaultWindow->SetAdaptor( Get() );
187 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
189 mWindowCreatedSignal.Emit( defaultSceneHolder );
191 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
192 if( 0u < timeInterval )
194 mObjectProfiler = new ObjectProfiler( timeInterval );
197 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
199 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
201 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
203 // Should be called after Core creation
204 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
206 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
208 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
210 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
212 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
214 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
216 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
218 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
220 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
222 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
224 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
226 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
228 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
230 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
232 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
234 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
236 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
238 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
240 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
242 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
244 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
246 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
248 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
250 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
252 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
254 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
256 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
258 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
260 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
262 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
264 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
266 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
268 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
270 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
272 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
274 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
276 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
278 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
280 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
282 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
284 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
286 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
288 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
290 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
292 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
294 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
296 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
298 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
301 std::string systemCachePath = GetSystemCachePath();
302 if( ! systemCachePath.empty() )
304 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
305 if ( 0 != dir_err && errno != EEXIST )
307 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
312 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
317 // Ensure stop status
320 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
321 gThreadLocalAdaptor = NULL;
323 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
325 (*iter)->OnDestroy();
328 // Clear out all the handles to Windows
331 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
332 delete mObjectProfiler;
336 delete mDisplayConnection;
337 delete mPlatformAbstraction;
338 delete mCallbackManager;
339 delete mPerformanceInterface;
341 mGraphics->Destroy();
343 // uninstall it on this thread (main actor thread)
344 Dali::Integration::Log::UninstallLogFunction();
346 // Delete environment options if we own it
347 if( mEnvironmentOptionsOwned )
349 delete mEnvironmentOptions;
353 void Adaptor::Start()
355 // It doesn't support restart after stop at this moment to support restarting, need more testing
356 if( READY != mState )
363 SetupSystemInformation();
365 // Start the callback manager
366 mCallbackManager->Start();
368 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
370 unsigned int dpiHor, dpiVer;
373 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
375 // set the DPI value for font rendering
376 FontClient fontClient = FontClient::Get();
377 fontClient.SetDpi( dpiHor, dpiVer );
379 // Initialize the thread controller
380 mThreadController->Initialize();
382 // Set max texture size
383 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
385 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
389 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
390 setenv( DALI_ENV_MAX_TEXTURE_SIZE, std::to_string( maxTextureSize ).c_str(), 1 );
391 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
394 ProcessCoreEvents(); // Ensure any startup messages are processed.
396 // Initialize the image loader plugin
397 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
399 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
405 // Dali::Internal::Adaptor::Adaptor::Pause
406 void Adaptor::Pause()
408 // Only pause the adaptor if we're actually running.
409 if( RUNNING == mState )
411 // Inform observers that we are about to be paused.
412 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
417 // Pause all windows event handlers when adaptor paused
418 for( auto window : mWindows )
423 mThreadController->Pause();
426 // Ensure any messages queued during pause callbacks are processed by doing another update.
429 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
433 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
437 // Dali::Internal::Adaptor::Adaptor::Resume
438 void Adaptor::Resume()
440 // Only resume the adaptor if we are in the suspended state.
441 if( PAUSED == mState )
445 // Reset the event handlers when adaptor resumed
446 for( auto window : mWindows )
451 // Inform observers that we have resumed.
452 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
457 // Trigger processing of events queued up while paused
458 mCore->ProcessEvents();
460 // Do at end to ensure our first update/render after resumption includes the processed messages as well
461 mThreadController->Resume();
463 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
467 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
473 if( RUNNING == mState ||
475 PAUSED_WHILE_HIDDEN == mState )
477 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
482 mThreadController->Stop();
484 // Delete the TTS player
485 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
489 mTtsPlayers[i].Reset();
493 // Destroy the image loader plugin
494 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
496 delete mNotificationTrigger;
497 mNotificationTrigger = NULL;
499 mCallbackManager->Stop();
503 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
507 void Adaptor::ContextLost()
509 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
512 void Adaptor::ContextRegained()
514 // Inform core, so that texture resources can be reloaded
515 mCore->RecoverFromContextLoss();
517 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
520 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
522 Integration::Point convertedPoint( point );
523 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
526 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
528 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
529 mWindows.front()->FeedWheelEvent( event );
532 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
534 Integration::KeyEvent convertedEvent( keyEvent );
535 mWindows.front()->FeedKeyEvent( convertedEvent );
538 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
540 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
541 for( auto windowPtr : mWindows )
543 if( windowPtr == windowImpl ) // the window is not deleted
545 mResizedSignal.Emit( mAdaptor );
547 windowImpl->SetSurface( &newSurface );
549 // Flush the event queue to give the update-render thread chance
550 // to start processing messages for new camera setup etc as soon as possible
553 // This method blocks until the render thread has completed the replace.
554 mThreadController->ReplaceSurface( &newSurface );
560 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
562 return *mWindows.front()->GetSurface();
565 void Adaptor::ReleaseSurfaceLock()
567 mWindows.front()->GetSurface()->ReleaseLock();
570 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
572 if( !mTtsPlayers[mode] )
574 // Create the TTS player when it needed, because it can reduce launching time.
575 mTtsPlayers[mode] = TtsPlayer::New(mode);
578 return mTtsPlayers[mode];
581 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
583 bool idleAdded(false);
585 // Only add an idle if the Adaptor is actually running
586 if( RUNNING == mState || READY == mState || forceAdd )
588 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
594 void Adaptor::RemoveIdle( CallbackBase* callback )
596 mCallbackManager->RemoveIdleCallback( callback );
599 void Adaptor::ProcessIdle()
601 bool idleProcessed = mCallbackManager->ProcessIdle();
602 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
605 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
607 mThreadController->SetPreRenderCallback( callback );
610 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
612 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
613 windowImpl.SetAdaptor( Get() );
615 // Add the new Window to the container - the order is not important
616 mWindows.push_back( &windowImpl );
618 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
620 mThreadController->AddSurface( surface );
622 mWindowCreatedSignal.Emit( childWindow );
627 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
629 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
630 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
632 if( *iter == &windowImpl )
634 mWindows.erase( iter );
642 bool Adaptor::RemoveWindow( std::string childWindowName )
644 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
646 if( ( *iter )->GetName() == childWindowName )
648 mWindows.erase( iter );
656 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
658 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
660 if( ( *iter )->GetId() == childWindow->GetId() )
662 mWindows.erase( iter );
670 Dali::Adaptor& Adaptor::Get()
672 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
673 return gThreadLocalAdaptor->mAdaptor;
676 bool Adaptor::IsAvailable()
678 return gThreadLocalAdaptor != NULL;
681 void Adaptor::SceneCreated()
683 mCore->SceneCreated();
686 Dali::Integration::Core& Adaptor::GetCore()
691 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
693 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
696 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
698 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
699 return *mDisplayConnection;
702 GraphicsInterface& Adaptor::GetGraphicsInterface()
704 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
708 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
710 return *mPlatformAbstraction;
713 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
715 return *mNotificationTrigger;
718 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
720 return mSocketFactory;
723 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
725 if( !mWindows.empty() )
727 return mWindows.front()->GetSurface();
733 TraceInterface& Adaptor::GetKernelTraceInterface()
735 return mKernelTracer;
738 TraceInterface& Adaptor::GetSystemTraceInterface()
740 return mSystemTracer;
743 PerformanceInterface* Adaptor::GetPerformanceInterface()
745 return mPerformanceInterface;
748 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
750 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
751 return *mPlatformAbstraction;
754 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
759 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
761 if( mTtsPlayers[mode] )
763 mTtsPlayers[mode].Reset();
767 Any Adaptor::GetNativeWindowHandle()
769 return mWindows.front()->GetNativeHandle();
772 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
774 Any nativeWindowHandle;
776 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
778 for( auto sceneHolder : mWindows )
780 if ( scene == sceneHolder->GetScene() )
782 nativeWindowHandle = sceneHolder->GetNativeHandle();
787 return nativeWindowHandle;
790 Any Adaptor::GetGraphicsDisplay()
796 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
798 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
799 display = eglImpl.GetDisplay();
805 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
807 mUseRemoteSurface = useRemoteSurface;
810 void Adaptor::AddObserver( LifeCycleObserver& observer )
812 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
814 if ( match == mObservers.end() )
816 mObservers.push_back( &observer );
820 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
822 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
824 if ( match != mObservers.end() )
826 mObservers.erase( match );
830 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
834 mCore->QueueEvent(event);
838 void Adaptor::ProcessCoreEvents()
842 if( mPerformanceInterface )
844 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
847 mCore->ProcessEvents();
849 if( mPerformanceInterface )
851 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
856 void Adaptor::RequestUpdate( bool forceUpdate )
862 mThreadController->RequestUpdate();
866 case PAUSED_WHILE_HIDDEN:
870 // Update (and resource upload) without rendering
871 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
883 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
885 // Only request a notification if the Adaptor is actually running
886 // and we haven't installed the idle notification
887 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
889 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
893 void Adaptor::OnWindowShown()
895 if( PAUSED_WHILE_HIDDEN == mState )
897 // Adaptor can now be resumed
902 // Force a render task
905 else if( RUNNING == mState )
907 // Force a render task
910 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
914 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
918 void Adaptor::OnWindowHidden()
920 if( RUNNING == mState || READY == mState )
922 bool allWindowsHidden = true;
924 for( auto window : mWindows )
926 if ( window->IsVisible() )
928 allWindowsHidden = false;
933 // Only pause the adaptor when all the windows are hidden
934 if( allWindowsHidden )
936 if( mState == RUNNING )
940 // Adaptor cannot be resumed until any window is shown
941 mState = PAUSED_WHILE_HIDDEN;
943 else // mState is READY
945 // Pause the adaptor after the state gets RUNNING
946 mState = PAUSED_WHILE_INITIALIZING;
951 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
956 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
960 // Dali::Internal::Adaptor::Adaptor::OnDamaged
961 void Adaptor::OnDamaged( const DamageArea& area )
963 // This is needed for the case where Dali window is partially obscured
964 RequestUpdate( false );
967 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
969 mResizedSignal.Emit( mAdaptor );
972 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
974 // Nofify surface resizing before flushing event queue
975 mThreadController->ResizeSurface();
977 // Flush the event queue to give the update-render thread chance
978 // to start processing messages for new camera setup etc as soon as possible
982 void Adaptor::NotifySceneCreated()
984 GetCore().SceneCreated();
986 // Flush the event queue to give the update-render thread chance
987 // to start processing messages for new camera setup etc as soon as possible
990 // Start thread controller after the scene has been created
991 mThreadController->Start();
993 // Process after surface is created (registering to remote surface provider if required)
994 SurfaceInitialized();
996 if( mState != PAUSED_WHILE_INITIALIZING )
1000 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1008 mState = PAUSED_WHILE_HIDDEN;
1010 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1014 void Adaptor::NotifyLanguageChanged()
1016 mLanguageChangedSignal.Emit( mAdaptor );
1019 void Adaptor::RenderOnce()
1021 RequestUpdateOnce();
1024 const LogFactoryInterface& Adaptor::GetLogFactory()
1026 return *mEnvironmentOptions;
1029 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1031 GetCore().RegisterProcessor(processor);
1034 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1036 GetCore().UnregisterProcessor(processor);
1039 bool Adaptor::IsMultipleWindowSupported() const
1041 return mConfigurationManager->IsMultipleWindowSupported();
1044 bool Adaptor::IsRenderingWindows() const
1046 return ( mThreadController && mThreadController->IsRenderingWindows() );
1049 void Adaptor::RequestUpdateOnce()
1051 if( mThreadController )
1053 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1057 bool Adaptor::ProcessCoreEventsFromIdle()
1059 ProcessCoreEvents();
1061 // the idle handle automatically un-installs itself
1062 mNotificationOnIdleInstalled = false;
1067 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1069 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1071 for( auto window : mWindows )
1073 if ( scene == window->GetScene() )
1082 Dali::WindowContainer Adaptor::GetWindows() const
1084 Dali::WindowContainer windows;
1086 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1088 // Downcast to Dali::Window
1089 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1092 windows.push_back( window );
1099 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1101 Dali::SceneHolderList sceneHolderList;
1103 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1105 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1108 return sceneHolderList;
1111 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1113 mLanguageChangedSignal(),
1114 mWindowCreatedSignal(),
1115 mAdaptor( adaptor ),
1118 mThreadController( nullptr ),
1119 mGraphics( nullptr ),
1120 mDisplayConnection( nullptr ),
1122 mConfigurationManager( nullptr ),
1123 mPlatformAbstraction( nullptr ),
1124 mCallbackManager( nullptr ),
1125 mNotificationOnIdleInstalled( false ),
1126 mNotificationTrigger( nullptr ),
1127 mDaliFeedbackPlugin(),
1128 mFeedbackController( nullptr ),
1131 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1132 mPerformanceInterface( nullptr ),
1135 mObjectProfiler( nullptr ),
1137 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1138 mUseRemoteSurface( false )
1140 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1141 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1143 gThreadLocalAdaptor = this;
1146 void Adaptor::SetRootLayoutDirection( std::string locale )
1148 Dali::Stage stage = Dali::Stage::GetCurrent();
1150 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1151 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1154 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1156 bool idleAdded( false );
1158 // Only add an idle if the Adaptor is actually running
1159 if( RUNNING == mState || READY == mState || forceAdd )
1161 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1167 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1169 mCallbackManager->RemoveIdleEntererCallback( callback );
1172 } // namespace Adaptor
1174 } // namespace Internal