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>
57 using Dali::TextAbstraction::FontClient;
70 __thread Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
71 } // unnamed namespace
73 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
75 Dali::Adaptor* adaptor = new Dali::Adaptor;
76 Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
77 adaptor->mImpl = impl;
79 impl->Initialize(configuration);
84 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
86 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());
190 // Ensure stop status
193 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
194 gThreadLocalAdaptor = NULL;
196 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
198 (*iter)->OnDestroy();
201 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
202 delete mVSyncMonitor;
203 delete mEventHandler;
204 delete mObjectProfiler;
209 delete mGestureManager;
210 delete mPlatformAbstraction;
211 delete mCallbackManager;
212 delete mPerformanceInterface;
214 // uninstall it on this thread (main actor thread)
215 Dali::Integration::Log::UninstallLogFunction();
217 // Delete environment options if we own it
218 if( mEnvironmentOptionsOwned )
220 delete mEnvironmentOptions;
224 void Adaptor::Start()
226 // it doesn't support restart after stop at this moment
227 // to support restarting, need more testing
228 if( READY != mState )
233 // Start the callback manager
234 mCallbackManager->Start();
236 // create event handler
237 mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
239 if( mDeferredRotationObserver != NULL )
241 mEventHandler->SetRotationObserver(mDeferredRotationObserver);
242 mDeferredRotationObserver = NULL;
245 unsigned int dpiHor, dpiVer;
247 Dali::DisplayConnection::GetDpi(dpiHor, dpiVer);
249 // tell core about the DPI value
250 mCore->SetDpi(dpiHor, dpiVer);
252 // set the DPI value for font rendering
253 FontClient fontClient = FontClient::Get();
254 fontClient.SetDpi( dpiHor, dpiVer );
256 // Tell the core the size of the surface just before we start the render-thread
257 PositionSize size = mSurface->GetPositionSize();
258 mCore->SurfaceResized( size.width, size.height );
260 // Initialize the thread controller
261 mThreadController->Initialize();
265 ProcessCoreEvents(); // Ensure any startup messages are processed.
267 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
273 // Dali::Internal::Adaptor::Adaptor::Pause
274 void Adaptor::Pause()
276 // Only pause the adaptor if we're actually running.
277 if( RUNNING == mState )
279 // Inform observers that we are about to be paused.
280 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
285 // Reset the event handler when adaptor paused
288 mEventHandler->Pause();
291 mThreadController->Pause();
297 // Dali::Internal::Adaptor::Adaptor::Resume
298 void Adaptor::Resume()
300 // Only resume the adaptor if we are in the suspended state.
301 if( PAUSED == mState )
305 // Reset the event handler when adaptor resumed
308 mEventHandler->Resume();
311 // Inform observers that we have resumed.
312 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
317 // Resume core so it processes any requests as well
320 // Do at end to ensure our first update/render after resumption includes the processed messages as well
321 mThreadController->Resume();
327 if( RUNNING == mState ||
329 PAUSED_WHILE_HIDDEN == mState )
331 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
336 mThreadController->Stop();
339 // Delete the TTS player
340 for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
344 mTtsPlayers[i].Reset();
348 delete mEventHandler;
349 mEventHandler = NULL;
351 delete mNotificationTrigger;
352 mNotificationTrigger = NULL;
354 mCallbackManager->Stop();
360 void Adaptor::ContextLost()
362 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
365 void Adaptor::ContextRegained()
367 // Inform core, so that texture resources can be reloaded
368 mCore->RecoverFromContextLoss();
370 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
373 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
375 mEventHandler->FeedTouchPoint( point, timeStamp );
378 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
380 mEventHandler->FeedWheelEvent( wheelEvent );
383 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
385 mEventHandler->FeedKeyEvent( keyEvent );
388 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
390 mNativeWindow = nativeWindow;
393 // flush the event queue to give update and render threads chance
394 // to start processing messages for new camera setup etc as soon as possible
397 // this method blocks until the render thread has completed the replace.
398 mThreadController->ReplaceSurface(mSurface);
401 RenderSurface& Adaptor::GetSurface() const
406 void Adaptor::ReleaseSurfaceLock()
408 mSurface->ReleaseLock();
411 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
413 if(!mTtsPlayers[mode])
415 // Create the TTS player when it needed, because it can reduce launching time.
416 mTtsPlayers[mode] = TtsPlayer::New(mode);
419 return mTtsPlayers[mode];
422 bool Adaptor::AddIdle( CallbackBase* callback )
424 bool idleAdded(false);
426 // Only add an idle if the Adaptor is actually running
427 if( RUNNING == mState )
429 idleAdded = mCallbackManager->AddIdleCallback( callback );
435 void Adaptor::RemoveIdle( CallbackBase* callback )
437 mCallbackManager->RemoveIdleCallback( callback );
440 Dali::Adaptor& Adaptor::Get()
442 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
443 return gThreadLocalAdaptor->mAdaptor;
446 bool Adaptor::IsAvailable()
448 return gThreadLocalAdaptor != NULL;
451 void Adaptor::SceneCreated()
453 mCore->SceneCreated();
456 Dali::Integration::Core& Adaptor::GetCore()
461 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
463 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
466 void Adaptor::SetUseHardwareVSync( bool useHardware )
468 mVSyncMonitor->SetUseHardwareVSync( useHardware );
471 EglFactory& Adaptor::GetEGLFactory() const
473 DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
477 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
482 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
484 DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
488 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
490 return *mPlatformAbstraction;
493 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
498 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
500 return *mNotificationTrigger;
503 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
505 return mTriggerEventFactory;
508 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
510 return mSocketFactory;
513 RenderSurface* Adaptor::GetRenderSurfaceInterface()
518 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
520 return mVSyncMonitor;
523 TraceInterface& Adaptor::GetKernelTraceInterface()
525 return mKernelTracer;
528 TraceInterface& Adaptor::GetSystemTraceInterface()
530 return mSystemTracer;
533 PerformanceInterface* Adaptor::GetPerformanceInterface()
535 return mPerformanceInterface;
538 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
540 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
541 return *mPlatformAbstraction;
544 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
546 mDragAndDropDetector = detector;
550 mEventHandler->SetDragAndDropDetector( detector );
554 void Adaptor::SetRotationObserver( RotationObserver* observer )
558 mEventHandler->SetRotationObserver( observer );
560 else if( mState == READY )
562 // Set once event handler exists
563 mDeferredRotationObserver = observer;
567 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
569 if(mTtsPlayers[mode])
571 mTtsPlayers[mode].Reset();
575 void Adaptor::SetMinimumPinchDistance(float distance)
577 if( mGestureManager )
579 mGestureManager->SetMinimumPinchDistance(distance);
583 Any Adaptor::GetNativeWindowHandle()
585 return mNativeWindow;
588 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
590 mUseRemoteSurface = useRemoteSurface;
593 void Adaptor::AddObserver( LifeCycleObserver& observer )
595 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
597 if ( match == mObservers.end() )
599 mObservers.push_back( &observer );
603 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
605 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
607 if ( match != mObservers.end() )
609 mObservers.erase( match );
613 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
617 mCore->QueueEvent(event);
621 void Adaptor::ProcessCoreEvents()
625 if( mPerformanceInterface )
627 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
630 mCore->ProcessEvents();
632 if( mPerformanceInterface )
634 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
639 void Adaptor::RequestUpdate()
641 // When Dali applications are partially visible behind the lock-screen,
642 // the indicator must be updated (therefore allow updates in the PAUSED state)
643 if ( PAUSED == mState ||
646 mThreadController->RequestUpdate();
650 void Adaptor::RequestProcessEventsOnIdle()
652 // Only request a notification if the Adaptor is actually running
653 // and we haven't installed the idle notification
654 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState ) )
656 mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ) );
660 void Adaptor::OnWindowShown()
662 if ( PAUSED_WHILE_HIDDEN == mState )
664 // Adaptor can now be resumed
669 // Force a render task
674 void Adaptor::OnWindowHidden()
676 if ( STOPPED != mState )
680 // Adaptor cannot be resumed until the window is shown
681 mState = PAUSED_WHILE_HIDDEN;
685 // Dali::Internal::Adaptor::Adaptor::OnDamaged
686 void Adaptor::OnDamaged( const DamageArea& area )
688 // This is needed for the case where Dali window is partially obscured
692 void Adaptor::SurfaceSizeChanged( Dali::Adaptor::SurfaceSize surfaceSize )
694 // let the core know the surface size has changed
695 mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
697 mResizedSignal.Emit( mAdaptor );
700 void Adaptor::NotifySceneCreated()
702 GetCore().SceneCreated();
704 // Start thread controller after the scene has been created
705 mThreadController->Start();
707 // process after surface is created (registering to remote surface provider if required)
708 SurfaceInitialized();
711 void Adaptor::NotifyLanguageChanged()
713 mLanguageChangedSignal.Emit( mAdaptor );
716 void Adaptor::RequestUpdateOnce()
718 if( PAUSED_WHILE_HIDDEN != mState )
720 if( mThreadController )
722 mThreadController->RequestUpdateOnce();
727 void Adaptor::IndicatorSizeChanged(int height)
729 // let the core know the indicator height is changed
730 mCore->SetTopMargin(height);
733 void Adaptor::ProcessCoreEventsFromIdle()
737 // the idle handle automatically un-installs itself
738 mNotificationOnIdleInstalled = false;
741 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
743 mLanguageChangedSignal(),
747 mThreadController( NULL ),
748 mVSyncMonitor( NULL ),
752 mNativeWindow( nativeWindow ),
754 mPlatformAbstraction( NULL ),
755 mEventHandler( NULL ),
756 mCallbackManager( NULL ),
757 mNotificationOnIdleInstalled( false ),
758 mNotificationTrigger( NULL ),
759 mGestureManager( NULL ),
760 mDaliFeedbackPlugin(),
761 mFeedbackController( NULL ),
764 mDragAndDropDetector(),
765 mDeferredRotationObserver( NULL ),
766 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
767 mPerformanceInterface( NULL ),
770 mTriggerEventFactory(),
771 mObjectProfiler( NULL ),
773 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
774 mUseRemoteSurface( false )
776 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
777 gThreadLocalAdaptor = this;
782 void Adaptor::SetViewMode( ViewMode viewMode )
784 mSurface->SetViewMode( viewMode );
785 mCore->SetViewMode( viewMode );
788 ViewMode Adaptor::GetViewMode() const
790 return mCore->GetViewMode();
793 void Adaptor::SetStereoBase( float stereoBase )
795 mCore->SetStereoBase( stereoBase );
798 float Adaptor::GetStereoBase() const
800 return mCore->GetStereoBase();
803 } // namespace Adaptor
805 } // namespace Internal