2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/key-event-integ.h>
33 #include <dali/integration-api/events/touch-event-integ.h>
34 #include <dali/integration-api/events/wheel-event-integ.h>
35 #include <dali/integration-api/processor-interface.h>
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/window-impl.h>
63 #include <dali/internal/window-system/common/window-render-surface.h>
65 #include <dali/internal/system/common/logging.h>
67 #include <dali/internal/system/common/locale-utils.h>
68 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
69 #include <dali/internal/imaging/common/image-loader.h>
71 #include <dali/devel-api/adaptor-framework/file-stream.h>
73 using Dali::TextAbstraction::FontClient;
75 extern std::string GetSystemCachePath();
88 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
89 } // unnamed namespace
91 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
93 Dali::Adaptor* adaptor = new Dali::Adaptor;
94 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
95 adaptor->mImpl = impl;
97 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
98 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
100 impl->Initialize( graphicsFactory, configuration );
101 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
106 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
108 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
109 Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
110 windowImpl.SetAdaptor( *adaptor );
114 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
116 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
117 Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
118 adaptor->mImpl = impl;
120 impl->Initialize( graphicsFactory, configuration );
125 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
127 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
128 Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
129 windowImpl.SetAdaptor( *adaptor );
133 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
135 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
136 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
137 mEnvironmentOptions->SetLogFunction( logFunction );
138 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
140 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
143 GetDataStoragePath( path );
144 mPlatformAbstraction->SetDataStoragePath( path );
146 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
147 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
149 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
152 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
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 = &( graphicsFactory.Create() );
169 mGraphics->Initialize( mEnvironmentOptions );
171 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
173 // This will only be created once
174 eglGraphics->Create();
176 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
177 EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
178 EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
180 mCore = Integration::Core::New( *this,
181 *mPlatformAbstraction,
184 eglContextHelperImpl,
185 dataRetentionPolicy ,
186 ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
187 mGraphics->GetDepthBufferRequired(),
188 mGraphics->GetStencilBufferRequired() );
190 defaultWindow->SetAdaptor( Get() );
192 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
194 mWindowCreatedSignal.Emit( defaultSceneHolder );
196 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
197 if( 0u < timeInterval )
199 mObjectProfiler = new ObjectProfiler( timeInterval );
202 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
204 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
206 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
208 // Should be called after Core creation
209 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
211 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
213 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
215 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
217 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
219 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
221 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
223 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
225 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
227 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
229 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
231 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
233 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
235 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
237 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
239 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
241 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
243 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
245 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
247 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
249 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
251 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
253 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
255 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
257 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
259 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
261 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
263 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
265 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
267 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
269 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
271 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
273 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
275 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
277 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
279 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
281 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
283 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
285 if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
287 Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
289 if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
291 Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
293 if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
295 Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
297 if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
299 Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
301 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
303 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
306 // Set max texture size
307 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
309 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
312 std::string systemCachePath = GetSystemCachePath();
313 if ( ! systemCachePath.empty() )
315 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
316 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
317 if( stream.is_open() )
320 while( std::getline( stream, line ) )
322 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
323 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
324 if( '#' == *( line.cbegin() ) || line == "" )
329 std::istringstream stream( line );
330 std::string environmentVariableName, environmentVariableValue;
331 std::getline(stream, environmentVariableName, ' ');
332 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
334 std::getline(stream, environmentVariableValue);
335 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
336 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
342 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
349 // Ensure stop status
352 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
353 gThreadLocalAdaptor = NULL;
355 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
357 (*iter)->OnDestroy();
360 // Clear out all the handles to Windows
363 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
364 delete mObjectProfiler;
368 delete mDisplayConnection;
369 delete mPlatformAbstraction;
370 delete mCallbackManager;
371 delete mPerformanceInterface;
373 mGraphics->Destroy();
375 // uninstall it on this thread (main actor thread)
376 Dali::Integration::Log::UninstallLogFunction();
378 // Delete environment options if we own it
379 if( mEnvironmentOptionsOwned )
381 delete mEnvironmentOptions;
385 void Adaptor::Start()
387 // It doesn't support restart after stop at this moment to support restarting, need more testing
388 if( READY != mState )
395 SetupSystemInformation();
397 // Start the callback manager
398 mCallbackManager->Start();
400 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
402 unsigned int dpiHor, dpiVer;
405 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
407 // set the DPI value for font rendering
408 FontClient fontClient = FontClient::Get();
409 fontClient.SetDpi( dpiHor, dpiVer );
411 // Initialize the thread controller
412 mThreadController->Initialize();
414 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
416 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
417 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
418 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
420 std::string systemCachePath = GetSystemCachePath();
421 if( ! systemCachePath.empty() )
423 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
426 printf("Error creating directory!n");
430 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
431 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
432 if( configFile.is_open() )
434 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
439 ProcessCoreEvents(); // Ensure any startup messages are processed.
441 // Initialize the image loader plugin
442 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
444 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
450 // Dali::Internal::Adaptor::Adaptor::Pause
451 void Adaptor::Pause()
453 // Only pause the adaptor if we're actually running.
454 if( RUNNING == mState )
456 // Inform observers that we are about to be paused.
457 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
462 // Pause all windows event handlers when adaptor paused
463 for( auto window : mWindows )
468 mThreadController->Pause();
471 // Ensure any messages queued during pause callbacks are processed by doing another update.
474 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
478 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
482 // Dali::Internal::Adaptor::Adaptor::Resume
483 void Adaptor::Resume()
485 // Only resume the adaptor if we are in the suspended state.
486 if( PAUSED == mState )
490 // Reset the event handlers when adaptor resumed
491 for( auto window : mWindows )
496 // Inform observers that we have resumed.
497 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
502 // Trigger processing of events queued up while paused
503 mCore->ProcessEvents();
505 // Do at end to ensure our first update/render after resumption includes the processed messages as well
506 mThreadController->Resume();
508 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
512 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
518 if( RUNNING == mState ||
520 PAUSED_WHILE_HIDDEN == mState )
522 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
527 mThreadController->Stop();
529 // Delete the TTS player
530 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
534 mTtsPlayers[i].Reset();
538 // Destroy the image loader plugin
539 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
541 delete mNotificationTrigger;
542 mNotificationTrigger = NULL;
544 mCallbackManager->Stop();
548 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
552 void Adaptor::ContextLost()
554 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
557 void Adaptor::ContextRegained()
559 // Inform core, so that texture resources can be reloaded
560 mCore->RecoverFromContextLoss();
562 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
565 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
567 Integration::Point convertedPoint( point );
568 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
571 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
573 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
574 mWindows.front()->FeedWheelEvent( event );
577 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
579 Integration::KeyEvent convertedEvent( keyEvent );
580 mWindows.front()->FeedKeyEvent( convertedEvent );
583 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
585 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
586 for( auto windowPtr : mWindows )
588 if( windowPtr == windowImpl ) // the window is not deleted
590 mResizedSignal.Emit( mAdaptor );
592 windowImpl->SetSurface( &newSurface );
594 // Flush the event queue to give the update-render thread chance
595 // to start processing messages for new camera setup etc as soon as possible
598 // This method blocks until the render thread has completed the replace.
599 mThreadController->ReplaceSurface( &newSurface );
605 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
607 // Flush the event queue to give the update-render thread chance
608 // to start processing messages for new camera setup etc as soon as possible
611 // This method blocks until the render thread has finished rendering the current surface.
612 mThreadController->DeleteSurface( &surface );
615 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
617 return *mWindows.front()->GetSurface();
620 void Adaptor::ReleaseSurfaceLock()
622 mWindows.front()->GetSurface()->ReleaseLock();
625 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
627 if( !mTtsPlayers[mode] )
629 // Create the TTS player when it needed, because it can reduce launching time.
630 mTtsPlayers[mode] = TtsPlayer::New(mode);
633 return mTtsPlayers[mode];
636 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
638 bool idleAdded(false);
640 // Only add an idle if the Adaptor is actually running
641 if( RUNNING == mState || READY == mState || forceAdd )
643 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
649 void Adaptor::RemoveIdle( CallbackBase* callback )
651 mCallbackManager->RemoveIdleCallback( callback );
654 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
656 mThreadController->SetPreRenderCallback( callback );
659 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
661 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
662 windowImpl.SetAdaptor( Get() );
664 // Add the new Window to the container - the order is not important
665 mWindows.push_back( &windowImpl );
667 mWindowCreatedSignal.Emit( childWindow );
672 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
674 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
675 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
677 if( *iter == &windowImpl )
679 mWindows.erase( iter );
687 bool Adaptor::RemoveWindow( std::string childWindowName )
689 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
691 if( ( *iter )->GetName() == childWindowName )
693 mWindows.erase( iter );
701 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
703 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
705 if( ( *iter )->GetId() == childWindow->GetId() )
707 mWindows.erase( iter );
715 Dali::Adaptor& Adaptor::Get()
717 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
718 return gThreadLocalAdaptor->mAdaptor;
721 bool Adaptor::IsAvailable()
723 return gThreadLocalAdaptor != NULL;
726 void Adaptor::SceneCreated()
728 mCore->SceneCreated();
731 Dali::Integration::Core& Adaptor::GetCore()
736 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
738 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
741 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
743 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
744 return *mDisplayConnection;
747 GraphicsInterface& Adaptor::GetGraphicsInterface()
749 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
753 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
755 return *mPlatformAbstraction;
758 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
760 return *mNotificationTrigger;
763 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
765 return mTriggerEventFactory;
768 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
770 return mSocketFactory;
773 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
775 if( !mWindows.empty() )
777 return mWindows.front()->GetSurface();
783 TraceInterface& Adaptor::GetKernelTraceInterface()
785 return mKernelTracer;
788 TraceInterface& Adaptor::GetSystemTraceInterface()
790 return mSystemTracer;
793 PerformanceInterface* Adaptor::GetPerformanceInterface()
795 return mPerformanceInterface;
798 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
800 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
801 return *mPlatformAbstraction;
804 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
806 if( mTtsPlayers[mode] )
808 mTtsPlayers[mode].Reset();
812 Any Adaptor::GetNativeWindowHandle()
814 return mWindows.front()->GetNativeHandle();
817 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
819 Any nativeWindowHandle;
821 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
823 for( auto sceneHolder : mWindows )
825 if ( scene == sceneHolder->GetScene() )
827 nativeWindowHandle = sceneHolder->GetNativeHandle();
832 return nativeWindowHandle;
835 Any Adaptor::GetGraphicsDisplay()
841 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
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" );
959 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
963 void Adaptor::OnWindowHidden()
965 if( RUNNING == mState || READY == mState )
967 bool allWindowsHidden = true;
969 for( auto window : mWindows )
971 if ( window->IsVisible() )
973 allWindowsHidden = false;
978 // Only pause the adaptor when all the windows are hidden
979 if( allWindowsHidden )
981 if( mState == RUNNING )
985 // Adaptor cannot be resumed until any window is shown
986 mState = PAUSED_WHILE_HIDDEN;
988 else // mState is READY
990 // Pause the adaptor after the state gets RUNNING
991 mState = PAUSED_WHILE_INITIALIZING;
996 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1001 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1005 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1006 void Adaptor::OnDamaged( const DamageArea& area )
1008 // This is needed for the case where Dali window is partially obscured
1009 RequestUpdate( false );
1012 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1014 mResizedSignal.Emit( mAdaptor );
1017 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1019 // Flush the event queue to give the update-render thread chance
1020 // to start processing messages for new camera setup etc as soon as possible
1021 ProcessCoreEvents();
1023 mThreadController->ResizeSurface();
1026 void Adaptor::NotifySceneCreated()
1028 GetCore().SceneCreated();
1030 // Flush the event queue to give the update-render thread chance
1031 // to start processing messages for new camera setup etc as soon as possible
1032 ProcessCoreEvents();
1034 // Start thread controller after the scene has been created
1035 mThreadController->Start();
1037 // Process after surface is created (registering to remote surface provider if required)
1038 SurfaceInitialized();
1040 if( mState != PAUSED_WHILE_INITIALIZING )
1044 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1052 mState = PAUSED_WHILE_HIDDEN;
1054 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1058 void Adaptor::NotifyLanguageChanged()
1060 mLanguageChangedSignal.Emit( mAdaptor );
1063 void Adaptor::RenderOnce()
1065 RequestUpdateOnce();
1068 const LogFactoryInterface& Adaptor::GetLogFactory()
1070 return *mEnvironmentOptions;
1073 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1075 GetCore().RegisterProcessor(processor);
1078 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1080 GetCore().UnregisterProcessor(processor);
1083 bool Adaptor::IsMultipleWindowSupported() const
1085 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
1086 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
1087 bool ret = eglImpl.IsSurfacelessContextSupported();
1091 void Adaptor::RequestUpdateOnce()
1093 if( mThreadController )
1095 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1099 bool Adaptor::ProcessCoreEventsFromIdle()
1101 ProcessCoreEvents();
1103 // the idle handle automatically un-installs itself
1104 mNotificationOnIdleInstalled = false;
1109 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1111 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1113 for( auto window : mWindows )
1115 if ( scene == window->GetScene() )
1124 Dali::WindowContainer Adaptor::GetWindows() const
1126 Dali::WindowContainer windows;
1128 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1130 // Downcast to Dali::Window
1131 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1134 windows.push_back( window );
1141 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1143 Dali::SceneHolderList sceneHolderList;
1145 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1147 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1150 return sceneHolderList;
1153 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1155 mLanguageChangedSignal(),
1156 mWindowCreatedSignal(),
1157 mAdaptor( adaptor ),
1160 mThreadController( nullptr ),
1161 mGraphics( nullptr ),
1162 mDisplayConnection( nullptr ),
1164 mPlatformAbstraction( nullptr ),
1165 mCallbackManager( nullptr ),
1166 mNotificationOnIdleInstalled( false ),
1167 mNotificationTrigger( nullptr ),
1168 mDaliFeedbackPlugin(),
1169 mFeedbackController( nullptr ),
1172 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1173 mPerformanceInterface( nullptr ),
1176 mTriggerEventFactory(),
1177 mObjectProfiler( nullptr ),
1179 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1180 mUseRemoteSurface( false )
1182 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1183 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1185 gThreadLocalAdaptor = this;
1188 void Adaptor::SetRootLayoutDirection( std::string locale )
1190 Dali::Stage stage = Dali::Stage::GetCurrent();
1192 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1193 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1196 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1198 bool idleAdded( false );
1200 // Only add an idle if the Adaptor is actually running
1201 if( RUNNING == mState || READY == mState || forceAdd )
1203 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1209 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1211 mCallbackManager->RemoveIdleEntererCallback( callback );
1214 } // namespace Adaptor
1216 } // namespace Internal