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() );
287 // Set max texture size
288 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
290 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
293 std::string systemCachePath = GetSystemCachePath();
294 if ( ! systemCachePath.empty() )
296 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::READ | Dali::FileStream::TEXT );
297 std::fstream& stream = dynamic_cast<std::fstream&>( fileStream.GetStream() );
298 if( stream.is_open() )
301 while( std::getline( stream, line ) )
303 line.erase( line.find_last_not_of( " \t\r\n" ) + 1 );
304 line.erase( 0, line.find_first_not_of( " \t\r\n" ) );
305 if( '#' == *( line.cbegin() ) || line == "" )
310 std::istringstream stream( line );
311 std::string environmentVariableName, environmentVariableValue;
312 std::getline(stream, environmentVariableName, ' ');
313 if( environmentVariableName == "DALI_ENV_MAX_TEXTURE_SIZE" && mEnvironmentOptions->GetMaxTextureSize() == 0 )
315 std::getline(stream, environmentVariableValue);
316 setenv( environmentVariableName.c_str() , environmentVariableValue.c_str(), 1 );
317 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( std::atoi( environmentVariableValue.c_str() ) );
323 DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
330 // Ensure stop status
333 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
334 gThreadLocalAdaptor = NULL;
336 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
338 (*iter)->OnDestroy();
341 // Clear out all the handles to Windows
344 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
345 delete mObjectProfiler;
349 delete mDisplayConnection;
350 delete mPlatformAbstraction;
351 delete mCallbackManager;
352 delete mPerformanceInterface;
354 mGraphics->Destroy();
356 // uninstall it on this thread (main actor thread)
357 Dali::Integration::Log::UninstallLogFunction();
359 // Delete environment options if we own it
360 if( mEnvironmentOptionsOwned )
362 delete mEnvironmentOptions;
366 void Adaptor::Start()
368 // It doesn't support restart after stop at this moment to support restarting, need more testing
369 if( READY != mState )
376 SetupSystemInformation();
378 // Start the callback manager
379 mCallbackManager->Start();
381 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
383 unsigned int dpiHor, dpiVer;
386 defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
388 // set the DPI value for font rendering
389 FontClient fontClient = FontClient::Get();
390 fontClient.SetDpi( dpiHor, dpiVer );
392 // Initialize the thread controller
393 mThreadController->Initialize();
395 if( !Dali::TizenPlatform::ImageLoader::MaxTextureSizeUpdated() )
397 auto eglGraphics = static_cast<EglGraphics *>( mGraphics );
398 GlImplementation& mGLES = eglGraphics->GetGlesInterface();
399 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mGLES.GetMaxTextureSize() );
401 std::string systemCachePath = GetSystemCachePath();
402 if( ! systemCachePath.empty() )
404 const int dir_err = system( std::string( "mkdir " + systemCachePath ).c_str() );
407 printf("Error creating directory!n");
411 Dali::FileStream fileStream( systemCachePath + "gpu-environment.conf", Dali::FileStream::WRITE | Dali::FileStream::TEXT );
412 std::fstream& configFile = dynamic_cast<std::fstream&>( fileStream.GetStream() );
413 if( configFile.is_open() )
415 configFile << "DALI_ENV_MAX_TEXTURE_SIZE " << mGLES.GetMaxTextureSize() << std::endl;
420 ProcessCoreEvents(); // Ensure any startup messages are processed.
422 // Initialize the image loader plugin
423 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
425 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
431 // Dali::Internal::Adaptor::Adaptor::Pause
432 void Adaptor::Pause()
434 // Only pause the adaptor if we're actually running.
435 if( RUNNING == mState )
437 // Inform observers that we are about to be paused.
438 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
443 // Pause all windows event handlers when adaptor paused
444 for( auto window : mWindows )
449 mThreadController->Pause();
452 // Ensure any messages queued during pause callbacks are processed by doing another update.
455 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
459 DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
463 // Dali::Internal::Adaptor::Adaptor::Resume
464 void Adaptor::Resume()
466 // Only resume the adaptor if we are in the suspended state.
467 if( PAUSED == mState )
471 // Reset the event handlers when adaptor resumed
472 for( auto window : mWindows )
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 )
508 mThreadController->Stop();
510 // Delete the TTS player
511 for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
515 mTtsPlayers[i].Reset();
519 // Destroy the image loader plugin
520 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
522 delete mNotificationTrigger;
523 mNotificationTrigger = NULL;
525 mCallbackManager->Stop();
529 DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
533 void Adaptor::ContextLost()
535 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
538 void Adaptor::ContextRegained()
540 // Inform core, so that texture resources can be reloaded
541 mCore->RecoverFromContextLoss();
543 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
546 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
548 Integration::Point convertedPoint( point );
549 mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
552 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
554 Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
555 mWindows.front()->FeedWheelEvent( event );
558 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
560 Integration::KeyEvent convertedEvent( keyEvent );
561 mWindows.front()->FeedKeyEvent( convertedEvent );
564 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
566 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
567 for( auto windowPtr : mWindows )
569 if( windowPtr == windowImpl ) // the window is not deleted
571 mResizedSignal.Emit( mAdaptor );
573 windowImpl->SetSurface( &newSurface );
575 // Flush the event queue to give the update-render thread chance
576 // to start processing messages for new camera setup etc as soon as possible
579 // This method blocks until the render thread has completed the replace.
580 mThreadController->ReplaceSurface( &newSurface );
586 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
588 // Flush the event queue to give the update-render thread chance
589 // to start processing messages for new camera setup etc as soon as possible
592 // This method blocks until the render thread has finished rendering the current surface.
593 mThreadController->DeleteSurface( &surface );
596 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
598 return *mWindows.front()->GetSurface();
601 void Adaptor::ReleaseSurfaceLock()
603 mWindows.front()->GetSurface()->ReleaseLock();
606 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
608 if( !mTtsPlayers[mode] )
610 // Create the TTS player when it needed, because it can reduce launching time.
611 mTtsPlayers[mode] = TtsPlayer::New(mode);
614 return mTtsPlayers[mode];
617 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
619 bool idleAdded(false);
621 // Only add an idle if the Adaptor is actually running
622 if( RUNNING == mState || READY == mState || forceAdd )
624 idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
630 void Adaptor::RemoveIdle( CallbackBase* callback )
632 mCallbackManager->RemoveIdleCallback( callback );
635 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
637 mThreadController->SetPreRenderCallback( callback );
640 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode )
642 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
643 windowImpl.SetAdaptor( Get() );
645 // Add the new Window to the container - the order is not important
646 mWindows.push_back( &windowImpl );
648 mWindowCreatedSignal.Emit( childWindow );
653 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
655 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
656 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
658 if( *iter == &windowImpl )
660 mWindows.erase( iter );
668 bool Adaptor::RemoveWindow( std::string childWindowName )
670 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
672 if( ( *iter )->GetName() == childWindowName )
674 mWindows.erase( iter );
682 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
684 for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
686 if( ( *iter )->GetId() == childWindow->GetId() )
688 mWindows.erase( iter );
696 Dali::Adaptor& Adaptor::Get()
698 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
699 return gThreadLocalAdaptor->mAdaptor;
702 bool Adaptor::IsAvailable()
704 return gThreadLocalAdaptor != NULL;
707 void Adaptor::SceneCreated()
709 mCore->SceneCreated();
712 Dali::Integration::Core& Adaptor::GetCore()
717 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
719 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
722 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
724 DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
725 return *mDisplayConnection;
728 GraphicsInterface& Adaptor::GetGraphicsInterface()
730 DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
734 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
736 return *mPlatformAbstraction;
739 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
741 return *mNotificationTrigger;
744 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
746 return mTriggerEventFactory;
749 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
751 return mSocketFactory;
754 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
756 if( !mWindows.empty() )
758 return mWindows.front()->GetSurface();
764 TraceInterface& Adaptor::GetKernelTraceInterface()
766 return mKernelTracer;
769 TraceInterface& Adaptor::GetSystemTraceInterface()
771 return mSystemTracer;
774 PerformanceInterface* Adaptor::GetPerformanceInterface()
776 return mPerformanceInterface;
779 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
781 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
782 return *mPlatformAbstraction;
785 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
787 if( mTtsPlayers[mode] )
789 mTtsPlayers[mode].Reset();
793 Any Adaptor::GetNativeWindowHandle()
795 return mWindows.front()->GetNativeHandle();
798 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
800 Any nativeWindowHandle;
802 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
804 for( auto sceneHolder : mWindows )
806 if ( scene == sceneHolder->GetScene() )
808 nativeWindowHandle = sceneHolder->GetNativeHandle();
813 return nativeWindowHandle;
816 Any Adaptor::GetGraphicsDisplay()
822 auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
824 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
825 display = eglImpl.GetDisplay();
831 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
833 mUseRemoteSurface = useRemoteSurface;
836 void Adaptor::AddObserver( LifeCycleObserver& observer )
838 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
840 if ( match == mObservers.end() )
842 mObservers.push_back( &observer );
846 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
848 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
850 if ( match != mObservers.end() )
852 mObservers.erase( match );
856 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
860 mCore->QueueEvent(event);
864 void Adaptor::ProcessCoreEvents()
868 if( mPerformanceInterface )
870 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
873 mCore->ProcessEvents();
875 if( mPerformanceInterface )
877 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
882 void Adaptor::RequestUpdate( bool forceUpdate )
888 mThreadController->RequestUpdate();
892 case PAUSED_WHILE_HIDDEN:
896 // Update (and resource upload) without rendering
897 mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
909 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
911 // Only request a notification if the Adaptor is actually running
912 // and we haven't installed the idle notification
913 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
915 mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
919 void Adaptor::OnWindowShown()
921 if( PAUSED_WHILE_HIDDEN == mState )
923 // Adaptor can now be resumed
928 // Force a render task
931 else if( RUNNING == mState )
933 // Force a render task
936 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
940 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
944 void Adaptor::OnWindowHidden()
946 if( RUNNING == mState || READY == mState )
948 bool allWindowsHidden = true;
950 for( auto window : mWindows )
952 if ( window->IsVisible() )
954 allWindowsHidden = false;
959 // Only pause the adaptor when all the windows are hidden
960 if( allWindowsHidden )
962 if( mState == RUNNING )
966 // Adaptor cannot be resumed until any window is shown
967 mState = PAUSED_WHILE_HIDDEN;
969 else // mState is READY
971 // Pause the adaptor after the state gets RUNNING
972 mState = PAUSED_WHILE_INITIALIZING;
977 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
982 DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
986 // Dali::Internal::Adaptor::Adaptor::OnDamaged
987 void Adaptor::OnDamaged( const DamageArea& area )
989 // This is needed for the case where Dali window is partially obscured
990 RequestUpdate( false );
993 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
995 mResizedSignal.Emit( mAdaptor );
998 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1000 // Flush the event queue to give the update-render thread chance
1001 // to start processing messages for new camera setup etc as soon as possible
1002 ProcessCoreEvents();
1004 mThreadController->ResizeSurface();
1007 void Adaptor::NotifySceneCreated()
1009 GetCore().SceneCreated();
1011 // Flush the event queue to give the update-render thread chance
1012 // to start processing messages for new camera setup etc as soon as possible
1013 ProcessCoreEvents();
1015 // Start thread controller after the scene has been created
1016 mThreadController->Start();
1018 // Process after surface is created (registering to remote surface provider if required)
1019 SurfaceInitialized();
1021 if( mState != PAUSED_WHILE_INITIALIZING )
1025 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1033 mState = PAUSED_WHILE_HIDDEN;
1035 DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1039 void Adaptor::NotifyLanguageChanged()
1041 mLanguageChangedSignal.Emit( mAdaptor );
1044 void Adaptor::RenderOnce()
1046 RequestUpdateOnce();
1049 const LogFactoryInterface& Adaptor::GetLogFactory()
1051 return *mEnvironmentOptions;
1054 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1056 GetCore().RegisterProcessor(processor);
1059 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1061 GetCore().UnregisterProcessor(processor);
1064 void Adaptor::RequestUpdateOnce()
1066 if( mThreadController )
1068 mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1072 bool Adaptor::ProcessCoreEventsFromIdle()
1074 ProcessCoreEvents();
1076 // the idle handle automatically un-installs itself
1077 mNotificationOnIdleInstalled = false;
1082 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1084 Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1086 for( auto window : mWindows )
1088 if ( scene == window->GetScene() )
1097 Dali::WindowContainer Adaptor::GetWindows() const
1099 Dali::WindowContainer windows;
1101 for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1103 // Downcast to Dali::Window
1104 Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1107 windows.push_back( window );
1114 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1116 Dali::SceneHolderList sceneHolderList;
1118 for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1120 sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1123 return sceneHolderList;
1126 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1128 mLanguageChangedSignal(),
1129 mWindowCreatedSignal(),
1130 mAdaptor( adaptor ),
1133 mThreadController( nullptr ),
1134 mGraphics( nullptr ),
1135 mDisplayConnection( nullptr ),
1137 mPlatformAbstraction( nullptr ),
1138 mCallbackManager( nullptr ),
1139 mNotificationOnIdleInstalled( false ),
1140 mNotificationTrigger( nullptr ),
1141 mDaliFeedbackPlugin(),
1142 mFeedbackController( nullptr ),
1145 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1146 mPerformanceInterface( nullptr ),
1149 mTriggerEventFactory(),
1150 mObjectProfiler( nullptr ),
1152 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1153 mUseRemoteSurface( false )
1155 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1156 mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1158 gThreadLocalAdaptor = this;
1161 void Adaptor::SetRootLayoutDirection( std::string locale )
1163 Dali::Stage stage = Dali::Stage::GetCurrent();
1165 stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1166 static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1169 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1171 bool idleAdded( false );
1173 // Only add an idle if the Adaptor is actually running
1174 if( RUNNING == mState || READY == mState || forceAdd )
1176 idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1182 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1184 mCallbackManager->RemoveIdleEntererCallback( callback );
1187 } // namespace Adaptor
1189 } // namespace Internal