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();
89 Window& windowImpl = Dali::GetImplementation(window);
90 Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
91 windowImpl.SetAdaptor(*adaptor);
95 void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration )
97 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
98 Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
99 mEnvironmentOptions->SetLogFunction( logFunction );
100 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
102 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
105 GetDataStoragePath( path );
106 mPlatformAbstraction->SetDataStoragePath( path );
108 ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
109 if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
111 dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
113 // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
114 // files automatically.
116 if( mEnvironmentOptions->PerformanceServerRequired() )
118 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
121 mCallbackManager = CallbackManager::New();
123 PositionSize size = mSurface->GetPositionSize();
125 mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
127 if( mEnvironmentOptions->GetGlesCallTime() > 0 )
129 mGLES = new GlProxyImplementation( *mEnvironmentOptions );
133 mGLES = new GlImplementation();
136 mEglFactory = new EglFactory( mEnvironmentOptions->GetMultiSamplingLevel() );
138 EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
140 mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager, dataRetentionPolicy );
142 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
143 if( 0u < timeInterval )
145 mObjectProfiler = new ObjectProfiler( timeInterval );
148 mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
150 mVSyncMonitor = new VSyncMonitor;
152 mThreadController = new ThreadController( *this, *mEnvironmentOptions );
154 // Should be called after Core creation
155 if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
157 Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
159 if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
161 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
163 if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
165 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
167 if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
169 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
171 if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
173 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
175 if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
177 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
179 if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
181 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
183 if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
185 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
188 // Set max texture size
189 if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
191 Dali::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
197 // Ensure stop status
200 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
201 gThreadLocalAdaptor = NULL;
203 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
205 (*iter)->OnDestroy();
208 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
209 delete mVSyncMonitor;
210 delete mEventHandler;
211 delete mObjectProfiler;
216 delete mGestureManager;
217 delete mPlatformAbstraction;
218 delete mCallbackManager;
219 delete mPerformanceInterface;
221 // uninstall it on this thread (main actor thread)
222 Dali::Integration::Log::UninstallLogFunction();
224 // Delete environment options if we own it
225 if( mEnvironmentOptionsOwned )
227 delete mEnvironmentOptions;
231 void Adaptor::Start()
233 // it doesn't support restart after stop at this moment
234 // to support restarting, need more testing
235 if( READY != mState )
240 // Start the callback manager
241 mCallbackManager->Start();
243 // create event handler
244 mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
246 if( mDeferredRotationObserver != NULL )
248 mEventHandler->SetRotationObserver(mDeferredRotationObserver);
249 mDeferredRotationObserver = NULL;
252 unsigned int dpiHor, dpiVer;
254 Dali::DisplayConnection::GetDpi(dpiHor, dpiVer);
256 // tell core about the DPI value
257 mCore->SetDpi(dpiHor, dpiVer);
259 // set the DPI value for font rendering
260 FontClient fontClient = FontClient::Get();
261 fontClient.SetDpi( dpiHor, dpiVer );
263 // Tell the core the size of the surface just before we start the render-thread
264 PositionSize size = mSurface->GetPositionSize();
265 mCore->SurfaceResized( size.width, size.height );
267 // Initialize the thread controller
268 mThreadController->Initialize();
272 ProcessCoreEvents(); // Ensure any startup messages are processed.
274 for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
280 // Dali::Internal::Adaptor::Adaptor::Pause
281 void Adaptor::Pause()
283 // Only pause the adaptor if we're actually running.
284 if( RUNNING == mState )
286 // Inform observers that we are about to be paused.
287 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
292 // Reset the event handler when adaptor paused
295 mEventHandler->Pause();
298 mThreadController->Pause();
304 // Dali::Internal::Adaptor::Adaptor::Resume
305 void Adaptor::Resume()
307 // Only resume the adaptor if we are in the suspended state.
308 if( PAUSED == mState )
312 // Reset the event handler when adaptor resumed
315 mEventHandler->Resume();
318 // Inform observers that we have resumed.
319 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
324 // Resume core so it processes any requests as well
327 // Do at end to ensure our first update/render after resumption includes the processed messages as well
328 mThreadController->Resume();
334 if( RUNNING == mState ||
336 PAUSED_WHILE_HIDDEN == mState )
338 for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
343 mThreadController->Stop();
346 // Delete the TTS player
347 for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
351 mTtsPlayers[i].Reset();
355 delete mEventHandler;
356 mEventHandler = NULL;
358 delete mNotificationTrigger;
359 mNotificationTrigger = NULL;
361 mCallbackManager->Stop();
367 void Adaptor::ContextLost()
369 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
372 void Adaptor::ContextRegained()
374 // Inform core, so that texture resources can be reloaded
375 mCore->RecoverFromContextLoss();
377 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
380 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
382 mEventHandler->FeedTouchPoint( point, timeStamp );
385 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
387 mEventHandler->FeedWheelEvent( wheelEvent );
390 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
392 mEventHandler->FeedKeyEvent( keyEvent );
395 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
397 mNativeWindow = nativeWindow;
400 // flush the event queue to give update and render threads chance
401 // to start processing messages for new camera setup etc as soon as possible
404 // this method blocks until the render thread has completed the replace.
405 mThreadController->ReplaceSurface(mSurface);
408 RenderSurface& Adaptor::GetSurface() const
413 void Adaptor::ReleaseSurfaceLock()
415 mSurface->ReleaseLock();
418 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
420 if(!mTtsPlayers[mode])
422 // Create the TTS player when it needed, because it can reduce launching time.
423 mTtsPlayers[mode] = TtsPlayer::New(mode);
426 return mTtsPlayers[mode];
429 bool Adaptor::AddIdle( CallbackBase* callback )
431 bool idleAdded(false);
433 // Only add an idle if the Adaptor is actually running
434 if( RUNNING == mState )
436 idleAdded = mCallbackManager->AddIdleCallback( callback );
442 void Adaptor::RemoveIdle( CallbackBase* callback )
444 mCallbackManager->RemoveIdleCallback( callback );
447 Dali::Adaptor& Adaptor::Get()
449 DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
450 return gThreadLocalAdaptor->mAdaptor;
453 bool Adaptor::IsAvailable()
455 return gThreadLocalAdaptor != NULL;
458 void Adaptor::SceneCreated()
460 mCore->SceneCreated();
463 Dali::Integration::Core& Adaptor::GetCore()
468 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
470 mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
473 void Adaptor::SetUseHardwareVSync( bool useHardware )
475 mVSyncMonitor->SetUseHardwareVSync( useHardware );
478 EglFactory& Adaptor::GetEGLFactory() const
480 DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
484 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
489 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
491 DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
495 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
497 return *mPlatformAbstraction;
500 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
505 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
507 return *mNotificationTrigger;
510 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
512 return mTriggerEventFactory;
515 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
517 return mSocketFactory;
520 RenderSurface* Adaptor::GetRenderSurfaceInterface()
525 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
527 return mVSyncMonitor;
530 TraceInterface& Adaptor::GetKernelTraceInterface()
532 return mKernelTracer;
535 TraceInterface& Adaptor::GetSystemTraceInterface()
537 return mSystemTracer;
540 PerformanceInterface* Adaptor::GetPerformanceInterface()
542 return mPerformanceInterface;
545 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
547 DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
548 return *mPlatformAbstraction;
551 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
553 mDragAndDropDetector = detector;
557 mEventHandler->SetDragAndDropDetector( detector );
561 void Adaptor::SetRotationObserver( RotationObserver* observer )
565 mEventHandler->SetRotationObserver( observer );
567 else if( mState == READY )
569 // Set once event handler exists
570 mDeferredRotationObserver = observer;
574 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
576 if(mTtsPlayers[mode])
578 mTtsPlayers[mode].Reset();
582 void Adaptor::SetMinimumPinchDistance(float distance)
584 if( mGestureManager )
586 mGestureManager->SetMinimumPinchDistance(distance);
590 Any Adaptor::GetNativeWindowHandle()
592 return mNativeWindow;
595 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
597 mUseRemoteSurface = useRemoteSurface;
600 void Adaptor::AddObserver( LifeCycleObserver& observer )
602 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
604 if ( match == mObservers.end() )
606 mObservers.push_back( &observer );
610 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
612 ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
614 if ( match != mObservers.end() )
616 mObservers.erase( match );
620 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
624 mCore->QueueEvent(event);
628 void Adaptor::ProcessCoreEvents()
632 if( mPerformanceInterface )
634 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
637 mCore->ProcessEvents();
639 if( mPerformanceInterface )
641 mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
646 void Adaptor::RequestUpdate()
648 // When Dali applications are partially visible behind the lock-screen,
649 // the indicator must be updated (therefore allow updates in the PAUSED state)
650 if ( PAUSED == mState ||
653 mThreadController->RequestUpdate();
657 void Adaptor::RequestProcessEventsOnIdle()
659 // Only request a notification if the Adaptor is actually running
660 // and we haven't installed the idle notification
661 if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState ) )
663 mNotificationOnIdleInstalled = AddIdle( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ) );
667 void Adaptor::OnWindowShown()
669 if ( PAUSED_WHILE_HIDDEN == mState )
671 // Adaptor can now be resumed
676 // Force a render task
681 void Adaptor::OnWindowHidden()
683 if ( STOPPED != mState )
687 // Adaptor cannot be resumed until the window is shown
688 mState = PAUSED_WHILE_HIDDEN;
692 // Dali::Internal::Adaptor::Adaptor::OnDamaged
693 void Adaptor::OnDamaged( const DamageArea& area )
695 // This is needed for the case where Dali window is partially obscured
699 void Adaptor::SurfaceSizeChanged( Dali::Adaptor::SurfaceSize surfaceSize )
701 // let the core know the surface size has changed
702 mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
704 mResizedSignal.Emit( mAdaptor );
707 void Adaptor::NotifySceneCreated()
709 GetCore().SceneCreated();
711 // Start thread controller after the scene has been created
712 mThreadController->Start();
714 // process after surface is created (registering to remote surface provider if required)
715 SurfaceInitialized();
718 void Adaptor::NotifyLanguageChanged()
720 mLanguageChangedSignal.Emit( mAdaptor );
723 void Adaptor::RequestUpdateOnce()
725 if( PAUSED_WHILE_HIDDEN != mState )
727 if( mThreadController )
729 mThreadController->RequestUpdateOnce();
734 void Adaptor::IndicatorSizeChanged(int height)
736 // let the core know the indicator height is changed
737 mCore->SetTopMargin(height);
740 void Adaptor::ProcessCoreEventsFromIdle()
744 // the idle handle automatically un-installs itself
745 mNotificationOnIdleInstalled = false;
748 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
750 mLanguageChangedSignal(),
754 mThreadController( NULL ),
755 mVSyncMonitor( NULL ),
759 mNativeWindow( nativeWindow ),
761 mPlatformAbstraction( NULL ),
762 mEventHandler( NULL ),
763 mCallbackManager( NULL ),
764 mNotificationOnIdleInstalled( false ),
765 mNotificationTrigger( NULL ),
766 mGestureManager( NULL ),
767 mDaliFeedbackPlugin(),
768 mFeedbackController( NULL ),
771 mDragAndDropDetector(),
772 mDeferredRotationObserver( NULL ),
773 mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
774 mPerformanceInterface( NULL ),
777 mTriggerEventFactory(),
778 mObjectProfiler( NULL ),
780 mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
781 mUseRemoteSurface( false )
783 DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
784 gThreadLocalAdaptor = this;
789 void Adaptor::SetViewMode( ViewMode viewMode )
791 mSurface->SetViewMode( viewMode );
792 mCore->SetViewMode( viewMode );
795 ViewMode Adaptor::GetViewMode() const
797 return mCore->GetViewMode();
800 void Adaptor::SetStereoBase( float stereoBase )
802 mCore->SetStereoBase( stereoBase );
805 float Adaptor::GetStereoBase() const
807 return mCore->GetStereoBase();
810 } // namespace Adaptor
812 } // namespace Internal