2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/addons/common/addon-manager-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
27 #include <dali/public-api/actors/layer.h>
28 #include <dali/public-api/object/any.h>
29 #include <dali/public-api/object/object-registry.h>
30 #include <dali/public-api/events/wheel-event.h>
31 #include <dali/devel-api/actors/actor-devel.h>
32 #include <dali/integration-api/debug.h>
33 #include <dali/integration-api/core.h>
34 #include <dali/integration-api/context-notifier.h>
35 #include <dali/integration-api/profiling.h>
36 #include <dali/integration-api/input-options.h>
37 #include <dali/integration-api/events/key-event-integ.h>
38 #include <dali/integration-api/events/touch-event-integ.h>
39 #include <dali/integration-api/events/wheel-event-integ.h>
40 #include <dali/integration-api/processor-interface.h>
41 #include <dali/integration-api/addon-manager.h>
44 #include <dali/public-api/dali-adaptor-common.h>
45 #include <dali/internal/system/common/thread-controller.h>
46 #include <dali/internal/system/common/performance-interface-factory.h>
47 #include <dali/internal/adaptor/common/lifecycle-observer.h>
48 #include <dali/internal/adaptor/common/thread-controller-interface.h>
50 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
51 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
53 #include <dali/devel-api/text-abstraction/font-client.h>
55 #include <dali/internal/system/common/callback-manager.h>
56 #include <dali/internal/accessibility/common/tts-player-impl.h>
57 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
58 #include <dali/internal/window-system/common/event-handler.h>
59 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
60 #include <dali/internal/graphics/gles/gl-implementation.h>
61 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
62 #include <dali/internal/graphics/common/egl-image-extensions.h>
63 #include <dali/internal/clipboard/common/clipboard-impl.h>
64 #include <dali/internal/system/common/object-profiler.h>
65 #include <dali/internal/window-system/common/display-connection.h>
66 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
67 #include <dali/internal/window-system/common/window-impl.h>
68 #include <dali/internal/window-system/common/window-render-surface.h>
70 #include <dali/internal/system/common/logging.h>
72 #include <dali/internal/system/common/locale-utils.h>
73 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
74 #include <dali/internal/imaging/common/image-loader.h>
76 #include <dali/internal/system/common/configuration-manager.h>
77 #include <dali/internal/system/common/environment-variables.h>
79 using Dali::TextAbstraction::FontClient;
81 extern std::string GetSystemCachePath();
95 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
97 } // unnamed namespace
99 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
101 Dali::Adaptor* adaptor = new Dali::Adaptor;
102 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode );
103 adaptor->mImpl = impl;
105 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
106 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
108 impl->Initialize( graphicsFactory );
109 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
114 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
116 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
117 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
118 windowImpl.SetAdaptor( *adaptor );
122 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
124 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
125 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode ); // Impl adaptor
126 adaptor->mImpl = impl;
128 impl->Initialize( graphicsFactory );
133 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
135 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
136 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
137 windowImpl.SetAdaptor( *adaptor );
141 void Adaptor::Initialize( GraphicsFactory& graphicsFactory )
143 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
144 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
145 mEnvironmentOptions->SetLogFunction( logFunction );
146 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
148 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
151 GetDataStoragePath( path );
152 mPlatformAbstraction->SetDataStoragePath( path );
154 if( mEnvironmentOptions->PerformanceServerRequired() )
156 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
159 mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
160 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
162 mCallbackManager = CallbackManager::New();
164 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
166 DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
168 mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
169 mGraphics->Initialize( mEnvironmentOptions );
171 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
172 auto eglGraphics = static_cast<EglGraphics *>( graphics );
174 // This will only be created once
175 eglGraphics->Create();
177 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
178 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
179 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
181 // Create the AddOnManager
182 mAddOnManager.reset( Dali::Internal::AddOnManagerFactory::CreateAddOnManager() );
184 mCore = Integration::Core::New( *this,
185 *mPlatformAbstraction,
188 eglContextHelperImpl,
189 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
190 mGraphics->GetDepthBufferRequired(),
191 mGraphics->GetStencilBufferRequired(),
192 mGraphics->GetPartialUpdateRequired() );
195 defaultWindow->SetAdaptor( Get() );
197 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
199 mWindowCreatedSignal.Emit( defaultSceneHolder );
201 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
202 if( 0u < timeInterval )
204 mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
207 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
209 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
211 mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
213 // Should be called after Core creation
214 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
216 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
218 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
220 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
222 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
224 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
226 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
228 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
230 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
232 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
234 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
236 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
238 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
240 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
242 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
244 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
246 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
248 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
250 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
252 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
254 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
256 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
258 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
260 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
262 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
264 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
266 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
268 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
270 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
272 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
274 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
276 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
278 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
280 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
282 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
284 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
286 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
288 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
290 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
292 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
294 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
296 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
298 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
300 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
302 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
304 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
306 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
308 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
311 std::string systemCachePath = GetSystemCachePath();
312 if( ! systemCachePath.empty() )
314 const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
315 if ( 0 != dir_err && errno != EEXIST )
317 DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
322 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
327 // Ensure stop status
330 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
331 gThreadLocalAdaptor = NULL;
333 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
335 (*iter)->OnDestroy();
338 // Clear out all the handles to Windows
341 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
342 delete mObjectProfiler;
346 delete mDisplayConnection;
347 delete mPlatformAbstraction;
348 delete mCallbackManager;
349 delete mPerformanceInterface;
351 mGraphics->Destroy();
353 // uninstall it on this thread (main actor thread)
354 Dali::Integration::Log::UninstallLogFunction();
356 // Delete environment options if we own it
357 if( mEnvironmentOptionsOwned )
359 delete mEnvironmentOptions;
363 void Adaptor::Start()
365 // It doesn't support restart after stop at this moment to support restarting, need more testing
366 if( READY != mState )
373 SetupSystemInformation();
375 // Start the callback manager
376 mCallbackManager->Start();
378 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
380 unsigned int dpiHor, dpiVer;
383 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
385 // set the DPI value for font rendering
386 FontClient fontClient = FontClient::Get();
387 fontClient.SetDpi( dpiHor, dpiVer );
389 // Initialize the thread controller
390 mThreadController->Initialize();
392 // Set max texture size
393 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
395 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
399 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
400 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
403 ProcessCoreEvents(); // Ensure any startup messages are processed.
405 // Initialize the image loader plugin
406 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
408 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
415 mAddOnManager->Start();
419 // Dali::Internal::Adaptor::Adaptor::Pause
420 void Adaptor::Pause()
422 // Only pause the adaptor if we're actually running.
423 if( RUNNING == mState )
425 // Inform observers that we are about to be paused.
426 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
434 mAddOnManager->Pause();
437 // Pause all windows event handlers when adaptor paused
438 for( auto window : mWindows )
443 mThreadController->Pause();
446 // Ensure any messages queued during pause callbacks are processed by doing another update.
449 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
453 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
457 // Dali::Internal::Adaptor::Adaptor::Resume
458 void Adaptor::Resume()
460 // Only resume the adaptor if we are in the suspended state.
461 if( PAUSED == mState )
465 // Reset the event handlers when adaptor resumed
466 for( auto window : mWindows )
471 // Resume AddOnManager
474 mAddOnManager->Resume();
477 // Inform observers that we have resumed.
478 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
483 // Trigger processing of events queued up while paused
484 mCore->ProcessEvents();
486 // Do at end to ensure our first update/render after resumption includes the processed messages as well
487 mThreadController->Resume();
489 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
493 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
499 if( RUNNING == mState ||
501 PAUSED_WHILE_HIDDEN == mState )
503 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
510 mAddOnManager->Stop();
513 mThreadController->Stop();
515 // Delete the TTS player
516 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
520 mTtsPlayers[i].Reset();
524 // Destroy the image loader plugin
525 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
527 delete mNotificationTrigger;
528 mNotificationTrigger = NULL;
530 mCallbackManager->Stop();
534 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
538 void Adaptor::ContextLost()
540 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
543 void Adaptor::ContextRegained()
545 // Inform core, so that texture resources can be reloaded
546 mCore->RecoverFromContextLoss();
548 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
551 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
553 Integration::Point convertedPoint( point );
554 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
557 void Adaptor::FeedWheelEvent( Dali::WheelEvent& wheelEvent )
559 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >( wheelEvent.GetType() ), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime() );
560 mWindows.front()->FeedWheelEvent( event );
563 void Adaptor::FeedKeyEvent( Dali::KeyEvent& keyEvent )
565 Integration::KeyEvent convertedEvent( keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast< Integration::KeyEvent::State >( keyEvent.GetState() ), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass() );
566 mWindows.front()->FeedKeyEvent( convertedEvent );
569 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
571 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
572 for( auto windowPtr : mWindows )
574 if( windowPtr == windowImpl ) // the window is not deleted
576 mResizedSignal.Emit( mAdaptor );
578 windowImpl->SetSurface( &newSurface );
580 // Flush the event queue to give the update-render thread chance
581 // to start processing messages for new camera setup etc as soon as possible
584 // This method blocks until the render thread has completed the replace.
585 mThreadController->ReplaceSurface( &newSurface );
591 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
593 // Flush the event queue to give the update-render thread chance
594 // to start processing messages for new camera setup etc as soon as possible
597 // This method blocks until the render thread has finished rendering the current surface.
598 mThreadController->DeleteSurface( &surface );
601 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
603 return *mWindows.front()->GetSurface();
606 void Adaptor::ReleaseSurfaceLock()
608 mWindows.front()->GetSurface()->ReleaseLock();
611 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
613 if( !mTtsPlayers[mode] )
615 // Create the TTS player when it needed, because it can reduce launching time.
616 mTtsPlayers[mode] = TtsPlayer::New(mode);
619 return mTtsPlayers[mode];
622 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
624 bool idleAdded(false);
626 // Only add an idle if the Adaptor is actually running
627 if( RUNNING == mState || READY == mState || forceAdd )
629 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
635 void Adaptor::RemoveIdle( CallbackBase* callback )
637 mCallbackManager->RemoveIdleCallback( callback );
640 void Adaptor::ProcessIdle()
642 bool idleProcessed = mCallbackManager->ProcessIdle();
643 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
646 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
648 mThreadController->SetPreRenderCallback( callback );
651 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
653 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
654 windowImpl.SetAdaptor( Get() );
656 // ChildWindow is set to the layout direction of the default window.
657 windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
659 // Add the new Window to the container - the order is not important
660 mWindows.push_back( &windowImpl );
662 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
664 mThreadController->AddSurface( surface );
666 mWindowCreatedSignal.Emit( childWindow );
671 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
673 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
674 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
676 if( *iter == &windowImpl )
678 mWindows.erase( iter );
686 bool Adaptor::RemoveWindow( std::string childWindowName )
688 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
690 if( ( *iter )->GetName() == childWindowName )
692 mWindows.erase( iter );
700 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
702 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
704 if( ( *iter )->GetId() == childWindow->GetId() )
706 mWindows.erase( iter );
714 Dali::Adaptor& Adaptor::Get()
716 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
717 return gThreadLocalAdaptor->mAdaptor;
720 bool Adaptor::IsAvailable()
722 return gThreadLocalAdaptor != NULL;
725 void Adaptor::SceneCreated()
727 mCore->SceneCreated();
730 Dali::Integration::Core& Adaptor::GetCore()
735 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
737 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
740 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
742 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
743 return *mDisplayConnection;
746 GraphicsInterface& Adaptor::GetGraphicsInterface()
748 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
749 return *( mGraphics.get() );
752 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
754 return *mPlatformAbstraction;
757 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
759 return *mNotificationTrigger;
762 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
764 return mSocketFactory;
767 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
769 if( !mWindows.empty() )
771 return mWindows.front()->GetSurface();
777 TraceInterface& Adaptor::GetKernelTraceInterface()
779 return mKernelTracer;
782 TraceInterface& Adaptor::GetSystemTraceInterface()
784 return mSystemTracer;
787 PerformanceInterface* Adaptor::GetPerformanceInterface()
789 return mPerformanceInterface;
792 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
794 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
795 return *mPlatformAbstraction;
798 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
803 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
805 if( mTtsPlayers[mode] )
807 mTtsPlayers[mode].Reset();
811 Any Adaptor::GetNativeWindowHandle()
813 return mWindows.front()->GetNativeHandle();
816 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
818 Any nativeWindowHandle;
820 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
822 for( auto sceneHolder : mWindows )
824 if ( scene == sceneHolder->GetScene() )
826 nativeWindowHandle = sceneHolder->GetNativeHandle();
831 return nativeWindowHandle;
834 Any Adaptor::GetGraphicsDisplay()
840 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
841 auto eglGraphics = static_cast<EglGraphics *>( graphics );
843 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
844 display = eglImpl.GetDisplay();
850 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
852 mUseRemoteSurface = useRemoteSurface;
855 void Adaptor::AddObserver( LifeCycleObserver& observer )
857 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
859 if ( match == mObservers.end() )
861 mObservers.push_back( &observer );
865 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
867 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
869 if ( match != mObservers.end() )
871 mObservers.erase( match );
875 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
879 mCore->QueueEvent(event);
883 void Adaptor::ProcessCoreEvents()
887 if( mPerformanceInterface )
889 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
892 mCore->ProcessEvents();
894 if( mPerformanceInterface )
896 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
901 void Adaptor::RequestUpdate( bool forceUpdate )
907 mThreadController->RequestUpdate();
911 case PAUSED_WHILE_HIDDEN:
915 // Update (and resource upload) without rendering
916 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
928 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
930 // Only request a notification if the Adaptor is actually running
931 // and we haven't installed the idle notification
932 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
934 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
938 void Adaptor::OnWindowShown()
940 if( PAUSED_WHILE_HIDDEN == mState )
942 // Adaptor can now be resumed
947 // Force a render task
950 else if( RUNNING == mState )
952 // Force a render task
955 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
957 else if( PAUSED_WHILE_INITIALIZING == mState )
959 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
964 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
968 void Adaptor::OnWindowHidden()
970 if( RUNNING == mState || READY == mState )
972 bool allWindowsHidden = true;
974 for( auto window : mWindows )
976 if ( window->IsVisible() )
978 allWindowsHidden = false;
983 // Only pause the adaptor when all the windows are hidden
984 if( allWindowsHidden )
986 if( mState == RUNNING )
990 // Adaptor cannot be resumed until any window is shown
991 mState = PAUSED_WHILE_HIDDEN;
993 else // mState is READY
995 // Pause the adaptor after the state gets RUNNING
996 mState = PAUSED_WHILE_INITIALIZING;
1001 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1006 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1010 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1011 void Adaptor::OnDamaged( const DamageArea& area )
1013 // This is needed for the case where Dali window is partially obscured
1014 RequestUpdate( false );
1017 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1019 mResizedSignal.Emit( mAdaptor );
1022 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1024 // Nofify surface resizing before flushing event queue
1025 mThreadController->ResizeSurface();
1027 // Flush the event queue to give the update-render thread chance
1028 // to start processing messages for new camera setup etc as soon as possible
1029 ProcessCoreEvents();
1032 void Adaptor::NotifySceneCreated()
1034 GetCore().SceneCreated();
1036 // Flush the event queue to give the update-render thread chance
1037 // to start processing messages for new camera setup etc as soon as possible
1038 ProcessCoreEvents();
1040 // Start thread controller after the scene has been created
1041 mThreadController->Start();
1043 // Process after surface is created (registering to remote surface provider if required)
1044 SurfaceInitialized();
1046 if( mState != PAUSED_WHILE_INITIALIZING )
1050 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1058 mState = PAUSED_WHILE_HIDDEN;
1060 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1064 void Adaptor::NotifyLanguageChanged()
1066 mLanguageChangedSignal.Emit( mAdaptor );
1069 void Adaptor::RenderOnce()
1071 if( mThreadController )
1073 UpdateMode updateMode;
1074 if( mThreadMode == ThreadMode::NORMAL )
1076 updateMode = UpdateMode::NORMAL;
1080 updateMode = UpdateMode::FORCE_RENDER;
1082 ProcessCoreEvents();
1084 mThreadController->RequestUpdateOnce( updateMode );
1088 const LogFactoryInterface& Adaptor::GetLogFactory()
1090 return *mEnvironmentOptions;
1093 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1095 GetCore().RegisterProcessor(processor);
1098 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1100 GetCore().UnregisterProcessor(processor);
1103 bool Adaptor::IsMultipleWindowSupported() const
1105 return mConfigurationManager->IsMultipleWindowSupported();
1108 void Adaptor::RequestUpdateOnce()
1110 if( mThreadController )
1112 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1116 bool Adaptor::ProcessCoreEventsFromIdle()
1118 ProcessCoreEvents();
1120 // the idle handle automatically un-installs itself
1121 mNotificationOnIdleInstalled = false;
1126 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1128 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1130 for( auto window : mWindows )
1132 if ( scene == window->GetScene() )
1141 Dali::WindowContainer Adaptor::GetWindows() const
1143 Dali::WindowContainer windows;
1145 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1147 // Downcast to Dali::Window
1148 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1151 windows.push_back( window );
1158 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1160 Dali::SceneHolderList sceneHolderList;
1162 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1164 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1167 return sceneHolderList;
1170 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1172 Dali::ObjectRegistry registry;
1175 registry = mCore->GetObjectRegistry();
1180 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1182 mLanguageChangedSignal(),
1183 mWindowCreatedSignal(),
1184 mAdaptor( adaptor ),
1187 mThreadController( nullptr ),
1188 mGraphics( nullptr ),
1189 mDisplayConnection( nullptr ),
1191 mConfigurationManager( nullptr ),
1192 mPlatformAbstraction( nullptr ),
1193 mCallbackManager( nullptr ),
1194 mNotificationOnIdleInstalled( false ),
1195 mNotificationTrigger( nullptr ),
1196 mDaliFeedbackPlugin(),
1197 mFeedbackController( nullptr ),
1200 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1201 mPerformanceInterface( nullptr ),
1204 mObjectProfiler( nullptr ),
1206 mThreadMode( threadMode ),
1207 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1208 mUseRemoteSurface( false ),
1209 mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1211 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1212 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1214 gThreadLocalAdaptor = this;
1217 void Adaptor::SetRootLayoutDirection( std::string locale )
1219 mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1220 for ( auto& window : mWindows )
1222 Dali::Actor root = window->GetRootLayer();
1223 root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1227 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1229 bool idleAdded( false );
1231 // Only add an idle if the Adaptor is actually running
1232 if( RUNNING == mState || READY == mState || forceAdd )
1234 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1246 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1248 mCallbackManager->RemoveIdleEntererCallback( callback );
1251 } // namespace Adaptor
1253 } // namespace Internal