2 * Copyright (c) 2017 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 "adaptor-impl.h"
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/core.h>
25 #include <dali/integration-api/context-notifier.h>
26 #include <dali/integration-api/profiling.h>
27 #include <dali/integration-api/input-options.h>
28 #include <dali/integration-api/events/touch-event-integ.h>
31 #include <base/thread-controller.h>
32 #include <base/performance-logging/performance-interface-factory.h>
33 #include <base/lifecycle-observer.h>
35 #include <dali/devel-api/text-abstraction/font-client.h>
37 #include <callback-manager.h>
38 #include <render-surface.h>
39 #include <tts-player-impl.h>
40 #include <accessibility-adaptor-impl.h>
41 #include <events/gesture-manager.h>
42 #include <events/event-handler.h>
43 #include <gl/gl-proxy-implementation.h>
44 #include <gl/gl-implementation.h>
45 #include <gl/egl-sync-implementation.h>
46 #include <gl/egl-image-extensions.h>
47 #include <gl/egl-factory.h>
48 #include <imf-manager-impl.h>
49 #include <clipboard-impl.h>
50 #include <vsync-monitor.h>
51 #include <object-profiler.h>
52 #include <base/display-connection.h>
53 #include <window-impl.h>
55 #include <tizen-logging.h>
56 #include <image-loading.h>
58 using Dali::TextAbstraction::FontClient;
71 __thread Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
72 } // unnamed namespace
74 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
76 Dali::Adaptor* adaptor = new Dali::Adaptor;
77 Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
78 adaptor->mImpl = impl;
80 impl->Initialize(configuration);
85 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
87 Any winId = window.GetNativeHandle();
88 Window& windowImpl = Dali::GetImplementation(window);
89 Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
90 windowImpl.SetAdaptor(*adaptor);
94 void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration )
96 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
97 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
98 mEnvironmentOptions->SetLogFunction( logFunction );
99 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
101 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
104 GetDataStoragePath( path );
105 mPlatformAbstraction->SetDataStoragePath( path );
107 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
108 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
110 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
112 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
113 // files automatically.
115 if( mEnvironmentOptions->PerformanceServerRequired() )
117 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
120 mCallbackManager = CallbackManager::New();
122 PositionSize size = mSurface->GetPositionSize();
124 mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
126 if( mEnvironmentOptions->GetGlesCallTime() > 0 )
128 mGLES = new GlProxyImplementation( *mEnvironmentOptions );
132 mGLES = new GlImplementation();
135 mEglFactory = new EglFactory( mEnvironmentOptions->GetMultiSamplingLevel() );
137 EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
139 mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager, dataRetentionPolicy );
141 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
142 if( 0u < timeInterval )
144 mObjectProfiler = new ObjectProfiler( timeInterval );
147 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
149 mVSyncMonitor = new VSyncMonitor;
151 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
153 // Should be called after Core creation
154 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
156 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
158 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
160 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
162 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
164 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
166 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
168 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
170 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
172 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
174 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
176 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
178 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
180 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
182 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
184 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
187 // Set max texture size
188 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
190 Dali::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
196 // Ensure stop status
199 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
200 gThreadLocalAdaptor = NULL;
202 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
204 (*iter)->OnDestroy();
207 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
208 delete mVSyncMonitor;
209 delete mEventHandler;
210 delete mObjectProfiler;
215 delete mGestureManager;
216 delete mPlatformAbstraction;
217 delete mCallbackManager;
218 delete mPerformanceInterface;
220 // uninstall it on this thread (main actor thread)
221 Dali::Integration::Log::UninstallLogFunction();
223 // Delete environment options if we own it
224 if( mEnvironmentOptionsOwned )
226 delete mEnvironmentOptions;
230 void Adaptor::Start()
232 // it doesn't support restart after stop at this moment
233 // to support restarting, need more testing
234 if( READY != mState )
239 // Start the callback manager
240 mCallbackManager->Start();
242 // create event handler
243 mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
245 if( mDeferredRotationObserver != NULL )
247 mEventHandler->SetRotationObserver(mDeferredRotationObserver);
248 mDeferredRotationObserver = NULL;
251 unsigned int dpiHor, dpiVer;
253 Dali::DisplayConnection::GetDpi(dpiHor, dpiVer);
255 // tell core about the DPI value
256 mCore->SetDpi(dpiHor, dpiVer);
258 // set the DPI value for font rendering
259 FontClient fontClient = FontClient::Get();
260 fontClient.SetDpi( dpiHor, dpiVer );
262 // Tell the core the size of the surface just before we start the render-thread
263 PositionSize size = mSurface->GetPositionSize();
264 mCore->SurfaceResized( size.width, size.height );
266 // Initialize the thread controller
267 mThreadController->Initialize();
271 ProcessCoreEvents(); // Ensure any startup messages are processed.
273 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
279 // Dali::Internal::Adaptor::Adaptor::Pause
280 void Adaptor::Pause()
282 // Only pause the adaptor if we're actually running.
283 if( RUNNING == mState )
285 // Inform observers that we are about to be paused.
286 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
291 // Reset the event handler when adaptor paused
294 mEventHandler->Pause();
297 mThreadController->Pause();
303 // Dali::Internal::Adaptor::Adaptor::Resume
304 void Adaptor::Resume()
306 // Only resume the adaptor if we are in the suspended state.
307 if( PAUSED == mState )
311 // Reset the event handler when adaptor resumed
314 mEventHandler->Resume();
317 // Inform observers that we have resumed.
318 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
323 // Resume core so it processes any requests as well
326 // Do at end to ensure our first update/render after resumption includes the processed messages as well
327 mThreadController->Resume();
333 if( RUNNING == mState ||
335 PAUSED_WHILE_HIDDEN == mState )
337 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
342 mThreadController->Stop();
345 // Delete the TTS player
346 for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
350 mTtsPlayers[i].Reset();
354 delete mEventHandler;
355 mEventHandler = NULL;
357 delete mNotificationTrigger;
358 mNotificationTrigger = NULL;
360 mCallbackManager->Stop();
366 void Adaptor::ContextLost()
368 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
371 void Adaptor::ContextRegained()
373 // Inform core, so that texture resources can be reloaded
374 mCore->RecoverFromContextLoss();
376 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
379 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
381 mEventHandler->FeedTouchPoint( point, timeStamp );
384 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
386 mEventHandler->FeedWheelEvent( wheelEvent );
389 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
391 mEventHandler->FeedKeyEvent( keyEvent );
394 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
396 mNativeWindow = nativeWindow;
399 // flush the event queue to give update and render threads chance
400 // to start processing messages for new camera setup etc as soon as possible
403 // this method blocks until the render thread has completed the replace.
404 mThreadController->ReplaceSurface(mSurface);
407 RenderSurface& Adaptor::GetSurface() const
412 void Adaptor::ReleaseSurfaceLock()
414 mSurface->ReleaseLock();
417 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
419 if(!mTtsPlayers[mode])
421 // Create the TTS player when it needed, because it can reduce launching time.
422 mTtsPlayers[mode] = TtsPlayer::New(mode);
425 return mTtsPlayers[mode];
428 bool Adaptor::AddIdle( CallbackBase* callback )
430 bool idleAdded(false);
432 // Only add an idle if the Adaptor is actually running
433 if( RUNNING == mState )
435 idleAdded = mCallbackManager->AddIdleCallback( callback );
441 void Adaptor::RemoveIdle( CallbackBase* callback )
443 mCallbackManager->RemoveIdleCallback( callback );
446 Dali::Adaptor& Adaptor::Get()
448 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
449 return gThreadLocalAdaptor->mAdaptor;
452 bool Adaptor::IsAvailable()
454 return gThreadLocalAdaptor != NULL;
457 void Adaptor::SceneCreated()
459 mCore->SceneCreated();
462 Dali::Integration::Core& Adaptor::GetCore()
467 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
469 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
472 void Adaptor::SetUseHardwareVSync( bool useHardware )
474 mVSyncMonitor->SetUseHardwareVSync( useHardware );
477 EglFactory& Adaptor::GetEGLFactory() const
479 DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
483 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
488 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
490 DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
494 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
496 return *mPlatformAbstraction;
499 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
504 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
506 return *mNotificationTrigger;
509 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
511 return mTriggerEventFactory;
514 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
516 return mSocketFactory;
519 RenderSurface* Adaptor::GetRenderSurfaceInterface()
524 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
526 return mVSyncMonitor;
529 TraceInterface& Adaptor::GetKernelTraceInterface()
531 return mKernelTracer;
534 TraceInterface& Adaptor::GetSystemTraceInterface()
536 return mSystemTracer;
539 PerformanceInterface* Adaptor::GetPerformanceInterface()
541 return mPerformanceInterface;
544 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
546 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
547 return *mPlatformAbstraction;
550 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
552 mDragAndDropDetector = detector;
556 mEventHandler->SetDragAndDropDetector( detector );
560 void Adaptor::SetRotationObserver( RotationObserver* observer )
564 mEventHandler->SetRotationObserver( observer );
566 else if( mState == READY )
568 // Set once event handler exists
569 mDeferredRotationObserver = observer;
573 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
575 if(mTtsPlayers[mode])
577 mTtsPlayers[mode].Reset();
581 void Adaptor::SetMinimumPinchDistance(float distance)
583 if( mGestureManager )
585 mGestureManager->SetMinimumPinchDistance(distance);
589 Any Adaptor::GetNativeWindowHandle()
591 return mNativeWindow;
594 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
596 mUseRemoteSurface = useRemoteSurface;
599 void Adaptor::AddObserver( LifeCycleObserver& observer )
601 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
603 if ( match == mObservers.end() )
605 mObservers.push_back( &observer );
609 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
611 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
613 if ( match != mObservers.end() )
615 mObservers.erase( match );
619 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
623 mCore->QueueEvent(event);
627 void Adaptor::ProcessCoreEvents()
631 if( mPerformanceInterface )
633 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
636 mCore->ProcessEvents();
638 if( mPerformanceInterface )
640 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
645 void Adaptor::RequestUpdate()
647 // When Dali applications are partially visible behind the lock-screen,
648 // the indicator must be updated (therefore allow updates in the PAUSED state)
649 if ( PAUSED == mState ||
652 mThreadController->RequestUpdate();
656 void Adaptor::RequestProcessEventsOnIdle()
658 // Only request a notification if the Adaptor is actually running
659 // and we haven't installed the idle notification
660 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState ) )
662 mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ) );
666 void Adaptor::OnWindowShown()
668 if ( PAUSED_WHILE_HIDDEN == mState )
670 // Adaptor can now be resumed
675 // Force a render task
680 void Adaptor::OnWindowHidden()
682 if ( STOPPED != mState )
686 // Adaptor cannot be resumed until the window is shown
687 mState = PAUSED_WHILE_HIDDEN;
691 // Dali::Internal::Adaptor::Adaptor::OnDamaged
692 void Adaptor::OnDamaged( const DamageArea& area )
694 // This is needed for the case where Dali window is partially obscured
698 void Adaptor::SurfaceSizeChanged( Dali::Adaptor::SurfaceSize surfaceSize )
700 // let the core know the surface size has changed
701 mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
703 mResizedSignal.Emit( mAdaptor );
706 void Adaptor::NotifySceneCreated()
708 GetCore().SceneCreated();
710 // Start thread controller after the scene has been created
711 mThreadController->Start();
713 // process after surface is created (registering to remote surface provider if required)
714 SurfaceInitialized();
717 void Adaptor::NotifyLanguageChanged()
719 mLanguageChangedSignal.Emit( mAdaptor );
722 void Adaptor::RequestUpdateOnce()
724 if( PAUSED_WHILE_HIDDEN != mState )
726 if( mThreadController )
728 mThreadController->RequestUpdateOnce();
733 void Adaptor::IndicatorSizeChanged(int height)
735 // let the core know the indicator height is changed
736 mCore->SetTopMargin(height);
739 void Adaptor::ProcessCoreEventsFromIdle()
743 // the idle handle automatically un-installs itself
744 mNotificationOnIdleInstalled = false;
747 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
749 mLanguageChangedSignal(),
753 mThreadController( NULL ),
754 mVSyncMonitor( NULL ),
758 mNativeWindow( nativeWindow ),
760 mPlatformAbstraction( NULL ),
761 mEventHandler( NULL ),
762 mCallbackManager( NULL ),
763 mNotificationOnIdleInstalled( false ),
764 mNotificationTrigger( NULL ),
765 mGestureManager( NULL ),
766 mDaliFeedbackPlugin(),
767 mFeedbackController( NULL ),
770 mDragAndDropDetector(),
771 mDeferredRotationObserver( NULL ),
772 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
773 mPerformanceInterface( NULL ),
776 mTriggerEventFactory(),
777 mObjectProfiler( NULL ),
779 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
780 mUseRemoteSurface( false )
782 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
783 gThreadLocalAdaptor = this;
788 void Adaptor::SetViewMode( ViewMode viewMode )
790 mSurface->SetViewMode( viewMode );
791 mCore->SetViewMode( viewMode );
794 ViewMode Adaptor::GetViewMode() const
796 return mCore->GetViewMode();
799 void Adaptor::SetStereoBase( float stereoBase )
801 mCore->SetStereoBase( stereoBase );
804 float Adaptor::GetStereoBase() const
806 return mCore->GetStereoBase();
809 } // namespace Adaptor
811 } // namespace Internal