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 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
562 // Flush the event queue to give the update-render thread chance
563 // to start processing messages for new camera setup etc as soon as possible
566 // This method blocks until the render thread has finished rendering the current surface.
567 mThreadController->DeleteSurface( &surface );
570 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
572 return *mWindows.front()->GetSurface();
575 void Adaptor::ReleaseSurfaceLock()
577 mWindows.front()->GetSurface()->ReleaseLock();
580 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
582 if( !mTtsPlayers[mode] )
584 // Create the TTS player when it needed, because it can reduce launching time.
585 mTtsPlayers[mode] = TtsPlayer::New(mode);
588 return mTtsPlayers[mode];
591 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
593 bool idleAdded(false);
595 // Only add an idle if the Adaptor is actually running
596 if( RUNNING == mState || READY == mState || forceAdd )
598 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
604 void Adaptor::RemoveIdle( CallbackBase* callback )
606 mCallbackManager->RemoveIdleCallback( callback );
609 void Adaptor::ProcessIdle()
611 bool idleProcessed = mCallbackManager->ProcessIdle();
612 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
615 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
617 mThreadController->SetPreRenderCallback( callback );
620 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
622 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
623 windowImpl.SetAdaptor( Get() );
625 // Add the new Window to the container - the order is not important
626 mWindows.push_back( &windowImpl );
628 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
630 mThreadController->AddSurface( surface );
632 mWindowCreatedSignal.Emit( childWindow );
637 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
639 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
640 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
642 if( *iter == &windowImpl )
644 mWindows.erase( iter );
652 bool Adaptor::RemoveWindow( std::string childWindowName )
654 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
656 if( ( *iter )->GetName() == childWindowName )
658 mWindows.erase( iter );
666 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
668 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
670 if( ( *iter )->GetId() == childWindow->GetId() )
672 mWindows.erase( iter );
680 Dali::Adaptor& Adaptor::Get()
682 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
683 return gThreadLocalAdaptor->mAdaptor;
686 bool Adaptor::IsAvailable()
688 return gThreadLocalAdaptor != NULL;
691 void Adaptor::SceneCreated()
693 mCore->SceneCreated();
696 Dali::Integration::Core& Adaptor::GetCore()
701 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
703 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
706 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
708 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
709 return *mDisplayConnection;
712 GraphicsInterface& Adaptor::GetGraphicsInterface()
714 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
718 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
720 return *mPlatformAbstraction;
723 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
725 return *mNotificationTrigger;
728 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
730 return mSocketFactory;
733 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
735 if( !mWindows.empty() )
737 return mWindows.front()->GetSurface();
743 TraceInterface& Adaptor::GetKernelTraceInterface()
745 return mKernelTracer;
748 TraceInterface& Adaptor::GetSystemTraceInterface()
750 return mSystemTracer;
753 PerformanceInterface* Adaptor::GetPerformanceInterface()
755 return mPerformanceInterface;
758 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
760 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
761 return *mPlatformAbstraction;
764 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
769 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
771 if( mTtsPlayers[mode] )
773 mTtsPlayers[mode].Reset();
777 Any Adaptor::GetNativeWindowHandle()
779 return mWindows.front()->GetNativeHandle();
782 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
784 Any nativeWindowHandle;
786 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
788 for( auto sceneHolder : mWindows )
790 if ( scene == sceneHolder->GetScene() )
792 nativeWindowHandle = sceneHolder->GetNativeHandle();
797 return nativeWindowHandle;
800 Any Adaptor::GetGraphicsDisplay()
806 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
808 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
809 display = eglImpl.GetDisplay();
815 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
817 mUseRemoteSurface = useRemoteSurface;
820 void Adaptor::AddObserver( LifeCycleObserver& observer )
822 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
824 if ( match == mObservers.end() )
826 mObservers.push_back( &observer );
830 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
832 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
834 if ( match != mObservers.end() )
836 mObservers.erase( match );
840 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
844 mCore->QueueEvent(event);
848 void Adaptor::ProcessCoreEvents()
852 if( mPerformanceInterface )
854 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
857 mCore->ProcessEvents();
859 if( mPerformanceInterface )
861 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
866 void Adaptor::RequestUpdate( bool forceUpdate )
872 mThreadController->RequestUpdate();
876 case PAUSED_WHILE_HIDDEN:
880 // Update (and resource upload) without rendering
881 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
893 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
895 // Only request a notification if the Adaptor is actually running
896 // and we haven't installed the idle notification
897 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
899 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
903 void Adaptor::OnWindowShown()
905 if( PAUSED_WHILE_HIDDEN == mState )
907 // Adaptor can now be resumed
912 // Force a render task
915 else if( RUNNING == mState )
917 // Force a render task
920 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
924 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
928 void Adaptor::OnWindowHidden()
930 if( RUNNING == mState || READY == mState )
932 bool allWindowsHidden = true;
934 for( auto window : mWindows )
936 if ( window->IsVisible() )
938 allWindowsHidden = false;
943 // Only pause the adaptor when all the windows are hidden
944 if( allWindowsHidden )
946 if( mState == RUNNING )
950 // Adaptor cannot be resumed until any window is shown
951 mState = PAUSED_WHILE_HIDDEN;
953 else // mState is READY
955 // Pause the adaptor after the state gets RUNNING
956 mState = PAUSED_WHILE_INITIALIZING;
961 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
966 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
970 // Dali::Internal::Adaptor::Adaptor::OnDamaged
971 void Adaptor::OnDamaged( const DamageArea& area )
973 // This is needed for the case where Dali window is partially obscured
974 RequestUpdate( false );
977 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
979 mResizedSignal.Emit( mAdaptor );
982 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
984 // Nofify surface resizing before flushing event queue
985 mThreadController->ResizeSurface();
987 // Flush the event queue to give the update-render thread chance
988 // to start processing messages for new camera setup etc as soon as possible
992 void Adaptor::NotifySceneCreated()
994 GetCore().SceneCreated();
996 // Flush the event queue to give the update-render thread chance
997 // to start processing messages for new camera setup etc as soon as possible
1000 // Start thread controller after the scene has been created
1001 mThreadController->Start();
1003 // Process after surface is created (registering to remote surface provider if required)
1004 SurfaceInitialized();
1006 if( mState != PAUSED_WHILE_INITIALIZING )
1010 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1018 mState = PAUSED_WHILE_HIDDEN;
1020 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1024 void Adaptor::NotifyLanguageChanged()
1026 mLanguageChangedSignal.Emit( mAdaptor );
1029 void Adaptor::RenderOnce()
1031 RequestUpdateOnce();
1034 const LogFactoryInterface& Adaptor::GetLogFactory()
1036 return *mEnvironmentOptions;
1039 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1041 GetCore().RegisterProcessor(processor);
1044 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1046 GetCore().UnregisterProcessor(processor);
1049 bool Adaptor::IsMultipleWindowSupported() const
1051 return mConfigurationManager->IsMultipleWindowSupported();
1054 void Adaptor::RequestUpdateOnce()
1056 if( mThreadController )
1058 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1062 bool Adaptor::ProcessCoreEventsFromIdle()
1064 ProcessCoreEvents();
1066 // the idle handle automatically un-installs itself
1067 mNotificationOnIdleInstalled = false;
1072 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1074 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1076 for( auto window : mWindows )
1078 if ( scene == window->GetScene() )
1087 Dali::WindowContainer Adaptor::GetWindows() const
1089 Dali::WindowContainer windows;
1091 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1093 // Downcast to Dali::Window
1094 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1097 windows.push_back( window );
1104 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1106 Dali::SceneHolderList sceneHolderList;
1108 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1110 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1113 return sceneHolderList;
1116 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1118 mLanguageChangedSignal(),
1119 mWindowCreatedSignal(),
1120 mAdaptor( adaptor ),
1123 mThreadController( nullptr ),
1124 mGraphics( nullptr ),
1125 mDisplayConnection( nullptr ),
1127 mConfigurationManager( nullptr ),
1128 mPlatformAbstraction( nullptr ),
1129 mCallbackManager( nullptr ),
1130 mNotificationOnIdleInstalled( false ),
1131 mNotificationTrigger( nullptr ),
1132 mDaliFeedbackPlugin(),
1133 mFeedbackController( nullptr ),
1136 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1137 mPerformanceInterface( nullptr ),
1140 mObjectProfiler( nullptr ),
1142 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1143 mUseRemoteSurface( false )
1145 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1146 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1148 gThreadLocalAdaptor = this;
1151 void Adaptor::SetRootLayoutDirection( std::string locale )
1153 Dali::Stage stage = Dali::Stage::GetCurrent();
1155 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1156 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1159 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1161 bool idleAdded( false );
1163 // Only add an idle if the Adaptor is actually running
1164 if( RUNNING == mState || READY == mState || forceAdd )
1166 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1172 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1174 mCallbackManager->RemoveIdleEntererCallback( callback );
1177 } // namespace Adaptor
1179 } // namespace Internal