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(),
189 mGraphics->PartialUpdateAvailable() );
191 defaultWindow->SetAdaptor( Get() );
193 Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
195 mWindowCreatedSignal.Emit( defaultSceneHolder );
197 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
198 if( 0u < timeInterval )
200 mObjectProfiler = new ObjectProfiler( timeInterval );
203 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
205 mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
207 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
209 // Should be called after Core creation
210 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
212 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
214 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
216 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
218 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
220 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
222 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
224 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
226 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
228 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
230 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
232 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
234 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
236 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
238 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
240 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
242 if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
244 Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
246 if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
248 Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
250 if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
252 Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false );
254 if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
256 Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false );
258 if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
260 Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
262 if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
264 Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
266 if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
268 Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
270 if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
272 Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
274 if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
276 Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
278 if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
280 Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
282 if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
284 Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
286 if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
288 Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
291 // Set max texture size
292 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
294 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
297 std::string systemCachePath = GetSystemCachePath();
298 if ( ! systemCachePath.empty() )
300 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
301 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
302 if( stream.is_open() )
305 while( std::getline( stream, line ) )
307 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
308 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
309 if( '#' == *( line.cbegin() ) || line == "" )
314 std::istringstream stream( line );
315 std::string environmentVariableName, environmentVariableValue;
316 std::getline(stream, environmentVariableName, ' ');
317 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
319 std::getline(stream, environmentVariableValue);
320 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
321 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
327 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
334 // Ensure stop status
337 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
338 gThreadLocalAdaptor = NULL;
340 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
342 (*iter)->OnDestroy();
345 // Clear out all the handles to Windows
348 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
349 delete mObjectProfiler;
353 delete mDisplayConnection;
354 delete mPlatformAbstraction;
355 delete mCallbackManager;
356 delete mPerformanceInterface;
358 mGraphics->Destroy();
360 // uninstall it on this thread (main actor thread)
361 Dali::Integration::Log::UninstallLogFunction();
363 // Delete environment options if we own it
364 if( mEnvironmentOptionsOwned )
366 delete mEnvironmentOptions;
370 void Adaptor::Start()
372 // It doesn't support restart after stop at this moment to support restarting, need more testing
373 if( READY != mState )
380 SetupSystemInformation();
382 // Start the callback manager
383 mCallbackManager->Start();
385 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
387 unsigned int dpiHor, dpiVer;
390 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
392 // set the DPI value for font rendering
393 FontClient fontClient = FontClient::Get();
394 fontClient.SetDpi( dpiHor, dpiVer );
396 // Initialize the thread controller
397 mThreadController->Initialize();
399 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
401 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
402 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
403 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
405 std::string systemCachePath = GetSystemCachePath();
406 if( ! systemCachePath.empty() )
408 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
411 printf("Error creating directory!n");
415 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
416 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
417 if( configFile.is_open() )
419 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
424 ProcessCoreEvents(); // Ensure any startup messages are processed.
426 // Initialize the image loader plugin
427 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
429 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
435 // Dali::Internal::Adaptor::Adaptor::Pause
436 void Adaptor::Pause()
438 // Only pause the adaptor if we're actually running.
439 if( RUNNING == mState )
441 // Inform observers that we are about to be paused.
442 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
447 // Pause all windows event handlers when adaptor paused
448 for( auto window : mWindows )
453 mThreadController->Pause();
456 // Ensure any messages queued during pause callbacks are processed by doing another update.
459 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
463 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
467 // Dali::Internal::Adaptor::Adaptor::Resume
468 void Adaptor::Resume()
470 // Only resume the adaptor if we are in the suspended state.
471 if( PAUSED == mState )
475 // Reset the event handlers when adaptor resumed
476 for( auto window : mWindows )
481 // Inform observers that we have resumed.
482 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
487 // Trigger processing of events queued up while paused
488 mCore->ProcessEvents();
490 // Do at end to ensure our first update/render after resumption includes the processed messages as well
491 mThreadController->Resume();
493 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
497 DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
503 if( RUNNING == mState ||
505 PAUSED_WHILE_HIDDEN == mState )
507 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
512 mThreadController->Stop();
514 // Delete the TTS player
515 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
519 mTtsPlayers[i].Reset();
523 // Destroy the image loader plugin
524 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
526 delete mNotificationTrigger;
527 mNotificationTrigger = NULL;
529 mCallbackManager->Stop();
533 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
537 void Adaptor::ContextLost()
539 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
542 void Adaptor::ContextRegained()
544 // Inform core, so that texture resources can be reloaded
545 mCore->RecoverFromContextLoss();
547 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
550 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
552 Integration::Point convertedPoint( point );
553 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
556 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
558 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
559 mWindows.front()->FeedWheelEvent( event );
562 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
564 Integration::KeyEvent convertedEvent( keyEvent );
565 mWindows.front()->FeedKeyEvent( convertedEvent );
568 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
570 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
571 for( auto windowPtr : mWindows )
573 if( windowPtr == windowImpl ) // the window is not deleted
575 mResizedSignal.Emit( mAdaptor );
577 windowImpl->SetSurface( &newSurface );
579 // Flush the event queue to give the update-render thread chance
580 // to start processing messages for new camera setup etc as soon as possible
583 // This method blocks until the render thread has completed the replace.
584 mThreadController->ReplaceSurface( &newSurface );
590 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
592 // Flush the event queue to give the update-render thread chance
593 // to start processing messages for new camera setup etc as soon as possible
596 // This method blocks until the render thread has finished rendering the current surface.
597 mThreadController->DeleteSurface( &surface );
600 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
602 return *mWindows.front()->GetSurface();
605 void Adaptor::ReleaseSurfaceLock()
607 mWindows.front()->GetSurface()->ReleaseLock();
610 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
612 if( !mTtsPlayers[mode] )
614 // Create the TTS player when it needed, because it can reduce launching time.
615 mTtsPlayers[mode] = TtsPlayer::New(mode);
618 return mTtsPlayers[mode];
621 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
623 bool idleAdded(false);
625 // Only add an idle if the Adaptor is actually running
626 if( RUNNING == mState || READY == mState || forceAdd )
628 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
634 void Adaptor::RemoveIdle( CallbackBase* callback )
636 mCallbackManager->RemoveIdleCallback( callback );
639 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
641 mThreadController->SetPreRenderCallback( callback );
644 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
646 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
647 windowImpl.SetAdaptor( Get() );
649 // Add the new Window to the container - the order is not important
650 mWindows.push_back( &windowImpl );
652 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
654 mThreadController->AddSurface( surface );
656 mWindowCreatedSignal.Emit( childWindow );
661 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
663 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
664 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
666 if( *iter == &windowImpl )
668 mWindows.erase( iter );
676 bool Adaptor::RemoveWindow( std::string childWindowName )
678 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
680 if( ( *iter )->GetName() == childWindowName )
682 mWindows.erase( iter );
690 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
692 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
694 if( ( *iter )->GetId() == childWindow->GetId() )
696 mWindows.erase( iter );
704 Dali::Adaptor& Adaptor::Get()
706 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
707 return gThreadLocalAdaptor->mAdaptor;
710 bool Adaptor::IsAvailable()
712 return gThreadLocalAdaptor != NULL;
715 void Adaptor::SceneCreated()
717 mCore->SceneCreated();
720 Dali::Integration::Core& Adaptor::GetCore()
725 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
727 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
730 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
732 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
733 return *mDisplayConnection;
736 GraphicsInterface& Adaptor::GetGraphicsInterface()
738 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
742 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
744 return *mPlatformAbstraction;
747 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
749 return *mNotificationTrigger;
752 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
754 return mTriggerEventFactory;
757 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
759 return mSocketFactory;
762 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
764 if( !mWindows.empty() )
766 return mWindows.front()->GetSurface();
772 TraceInterface& Adaptor::GetKernelTraceInterface()
774 return mKernelTracer;
777 TraceInterface& Adaptor::GetSystemTraceInterface()
779 return mSystemTracer;
782 PerformanceInterface* Adaptor::GetPerformanceInterface()
784 return mPerformanceInterface;
787 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
789 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
790 return *mPlatformAbstraction;
793 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
795 if( mTtsPlayers[mode] )
797 mTtsPlayers[mode].Reset();
801 Any Adaptor::GetNativeWindowHandle()
803 return mWindows.front()->GetNativeHandle();
806 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
808 Any nativeWindowHandle;
810 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
812 for( auto sceneHolder : mWindows )
814 if ( scene == sceneHolder->GetScene() )
816 nativeWindowHandle = sceneHolder->GetNativeHandle();
821 return nativeWindowHandle;
824 Any Adaptor::GetGraphicsDisplay()
830 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
832 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
833 display = eglImpl.GetDisplay();
839 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
841 mUseRemoteSurface = useRemoteSurface;
844 void Adaptor::AddObserver( LifeCycleObserver& observer )
846 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
848 if ( match == mObservers.end() )
850 mObservers.push_back( &observer );
854 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
856 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
858 if ( match != mObservers.end() )
860 mObservers.erase( match );
864 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
868 mCore->QueueEvent(event);
872 void Adaptor::ProcessCoreEvents()
876 if( mPerformanceInterface )
878 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
881 mCore->ProcessEvents();
883 if( mPerformanceInterface )
885 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
890 void Adaptor::RequestUpdate( bool forceUpdate )
896 mThreadController->RequestUpdate();
900 case PAUSED_WHILE_HIDDEN:
904 // Update (and resource upload) without rendering
905 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
917 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
919 // Only request a notification if the Adaptor is actually running
920 // and we haven't installed the idle notification
921 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
923 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
927 void Adaptor::OnWindowShown()
929 if( PAUSED_WHILE_HIDDEN == mState )
931 // Adaptor can now be resumed
936 // Force a render task
939 else if( RUNNING == mState )
941 // Force a render task
944 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
948 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
952 void Adaptor::OnWindowHidden()
954 if( RUNNING == mState || READY == mState )
956 bool allWindowsHidden = true;
958 for( auto window : mWindows )
960 if ( window->IsVisible() )
962 allWindowsHidden = false;
967 // Only pause the adaptor when all the windows are hidden
968 if( allWindowsHidden )
970 if( mState == RUNNING )
974 // Adaptor cannot be resumed until any window is shown
975 mState = PAUSED_WHILE_HIDDEN;
977 else // mState is READY
979 // Pause the adaptor after the state gets RUNNING
980 mState = PAUSED_WHILE_INITIALIZING;
985 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
990 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
994 // Dali::Internal::Adaptor::Adaptor::OnDamaged
995 void Adaptor::OnDamaged( const DamageArea& area )
997 // This is needed for the case where Dali window is partially obscured
998 RequestUpdate( false );
1001 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1003 mResizedSignal.Emit( mAdaptor );
1006 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1008 // Flush the event queue to give the update-render thread chance
1009 // to start processing messages for new camera setup etc as soon as possible
1010 ProcessCoreEvents();
1012 mThreadController->ResizeSurface();
1015 void Adaptor::NotifySceneCreated()
1017 GetCore().SceneCreated();
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 // Start thread controller after the scene has been created
1024 mThreadController->Start();
1026 // Process after surface is created (registering to remote surface provider if required)
1027 SurfaceInitialized();
1029 if( mState != PAUSED_WHILE_INITIALIZING )
1033 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1041 mState = PAUSED_WHILE_HIDDEN;
1043 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1047 void Adaptor::NotifyLanguageChanged()
1049 mLanguageChangedSignal.Emit( mAdaptor );
1052 void Adaptor::RenderOnce()
1054 RequestUpdateOnce();
1057 const LogFactoryInterface& Adaptor::GetLogFactory()
1059 return *mEnvironmentOptions;
1062 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1064 GetCore().RegisterProcessor(processor);
1067 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1069 GetCore().UnregisterProcessor(processor);
1072 bool Adaptor::IsMultipleWindowSupported() const
1074 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
1075 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
1076 bool ret = eglImpl.IsSurfacelessContextSupported();
1080 void Adaptor::RequestUpdateOnce()
1082 if( mThreadController )
1084 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1088 bool Adaptor::ProcessCoreEventsFromIdle()
1090 ProcessCoreEvents();
1092 // the idle handle automatically un-installs itself
1093 mNotificationOnIdleInstalled = false;
1098 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1100 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1102 for( auto window : mWindows )
1104 if ( scene == window->GetScene() )
1113 Dali::WindowContainer Adaptor::GetWindows() const
1115 Dali::WindowContainer windows;
1117 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1119 // Downcast to Dali::Window
1120 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1123 windows.push_back( window );
1130 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1132 Dali::SceneHolderList sceneHolderList;
1134 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1136 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1139 return sceneHolderList;
1142 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1144 mLanguageChangedSignal(),
1145 mWindowCreatedSignal(),
1146 mAdaptor( adaptor ),
1149 mThreadController( nullptr ),
1150 mGraphics( nullptr ),
1151 mDisplayConnection( nullptr ),
1153 mPlatformAbstraction( nullptr ),
1154 mCallbackManager( nullptr ),
1155 mNotificationOnIdleInstalled( false ),
1156 mNotificationTrigger( nullptr ),
1157 mDaliFeedbackPlugin(),
1158 mFeedbackController( nullptr ),
1161 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1162 mPerformanceInterface( nullptr ),
1165 mTriggerEventFactory(),
1166 mObjectProfiler( nullptr ),
1168 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1169 mUseRemoteSurface( false )
1171 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1172 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1174 gThreadLocalAdaptor = this;
1177 void Adaptor::SetRootLayoutDirection( std::string locale )
1179 Dali::Stage stage = Dali::Stage::GetCurrent();
1181 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1182 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1185 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1187 bool idleAdded( false );
1189 // Only add an idle if the Adaptor is actually running
1190 if( RUNNING == mState || READY == mState || forceAdd )
1192 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1198 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1200 mCallbackManager->RemoveIdleEntererCallback( callback );
1203 } // namespace Adaptor
1205 } // namespace Internal