143173d6ac0be5853618d4cbdcb5881346205981
[platform/core/uifw/dali-adaptor.git] / adaptors / tizen / internal / common / adaptor-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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
7 //
8 //     http://floralicense.org/license/
9 //
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.
15 //
16
17 // CLASS HEADER
18 #include "adaptor-impl.h"
19
20 // EXTERNAL INCLUDES
21 #include <boost/thread/tss.hpp>
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/profiling.h>
26 #include <dali/integration-api/events/touch-event-integ.h>
27
28 // INTERNAL INCLUDES
29 #include <base/update-render-controller.h>
30 #include <base/environment-variables.h>
31 #include <base/performance-logging/performance-interface-factory.h>
32 #include <base/lifecycle-observer.h>
33
34 #include <internal/common/callback-manager.h>
35 #include <internal/common/trigger-event.h>
36 #include <internal/common/render-surface-impl.h>
37 #include <internal/common/tts-player-impl.h>
38 #include <internal/common/accessibility-manager-impl.h>
39 #include <internal/common/timer-impl.h>
40 #include <internal/common/events/gesture-manager.h>
41 #include <internal/common/events/event-handler.h>
42 #include <internal/common/feedback/feedback-controller.h>
43 #include <internal/common/feedback/feedback-plugin-proxy.h>
44 #include <internal/common/gl/gl-implementation.h>
45 #include <internal/common/gl/egl-sync-implementation.h>
46 #include <internal/common/gl/egl-image-extensions.h>
47 #include <internal/common/gl/egl-factory.h>
48 #include <internal/common/imf-manager-impl.h>
49 #include <internal/common/clipboard-impl.h>
50 #include <internal/common/vsync-monitor.h>
51
52 #include <slp-logging.h>
53
54
55
56 namespace Dali
57 {
58
59 namespace Internal
60 {
61
62 namespace Adaptor
63 {
64
65 namespace
66 {
67 boost::thread_specific_ptr<Adaptor> gThreadLocalAdaptor;
68
69 unsigned int GetIntegerEnvironmentVariable( const char* variable, unsigned int defaultValue )
70 {
71   const char* variableParameter = std::getenv(variable);
72
73   // if the parameter exists convert it to an integer, else return the default value
74   unsigned int intValue = variableParameter ? atoi(variableParameter) : defaultValue;
75   return intValue;
76
77 }
78 } // unnamed namespace
79
80 Dali::Adaptor* Adaptor::New( RenderSurface *surface, const DeviceLayout& baseLayout )
81 {
82   DALI_ASSERT_ALWAYS( surface->GetType() != Dali::RenderSurface::NO_SURFACE && "No surface for adaptor" );
83
84   Dali::Adaptor* adaptor = new Dali::Adaptor;
85   Adaptor* impl = new Adaptor( *adaptor, surface, baseLayout );
86   adaptor->mImpl = impl;
87
88   impl->Initialize();
89
90   return adaptor;
91 }
92
93 void Adaptor::ParseLogOptions()
94 {
95   // get logging options
96   unsigned int logFrameRateFrequency = GetIntegerEnvironmentVariable( DALI_ENV_FPS_TRACKING, 0 );
97   unsigned int logupdateStatusFrequency = GetIntegerEnvironmentVariable( DALI_ENV_UPDATE_STATUS_INTERVAL, 0 );
98   unsigned int logPerformanceLevel = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE, 0 );
99   unsigned int logPanGesture = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PAN_GESTURE, 0 );
100
101   Dali::Integration::Log::LogFunction  logFunction(Dali::SlpPlatform::LogMessage);
102
103   mLogOptions.SetOptions( logFunction, logFrameRateFrequency, logupdateStatusFrequency, logPerformanceLevel, logPanGesture );
104
105   // all threads here (event, update, and render) will send their logs to SLP Platform's LogMessage handler.
106   // Dali::Integration::Log::LogFunction logFunction(Dali::SlpPlatform::LogMessage);
107
108   mLogOptions.InstallLogFunction();
109 }
110
111 void Adaptor::Initialize()
112 {
113   ParseLogOptions();
114
115   mPlatformAbstraction = new SlpPlatform::SlpPlatformAbstraction;
116
117   if( mLogOptions.GetPerformanceLoggingLevel() > 0 )
118   {
119     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, mLogOptions );
120   }
121
122   mCallbackManager = CallbackManager::New();
123
124   PositionSize size = mSurface->GetPositionSize();
125
126   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager);
127
128   mGLES = new GlImplementation;
129
130   mEglFactory = new EglFactory();
131
132   EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
133
134   mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager );
135
136   mNotificationTrigger = new TriggerEvent( boost::bind(&Adaptor::ProcessCoreEvents, this) );
137
138   mVSyncMonitor = new VSyncMonitor;
139
140   mUpdateRenderController = new UpdateRenderController( *this, mLogOptions );
141
142   mDaliFeedbackPlugin = new FeedbackPluginProxy( FeedbackPluginProxy::DEFAULT_OBJECT_NAME );
143
144   // Should be called after Core creation
145   if( mLogOptions.GetPanGestureLoggingLevel() )
146   {
147     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
148   }
149 }
150
151 Adaptor::~Adaptor()
152 {
153   // Ensure stop status
154   Stop();
155
156   // Release first as we do not want any access to Adaptor as it is being destroyed.
157   gThreadLocalAdaptor.release();
158
159   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
160   {
161     (*iter)->OnDestroy();
162   }
163
164   if (mUpdateRenderController)
165   {
166     delete mUpdateRenderController;
167     mUpdateRenderController = NULL;
168   }
169
170   if( mVSyncMonitor )
171   {
172     delete mVSyncMonitor;
173     mVSyncMonitor = NULL;
174   }
175
176   if (mEventHandler)
177   {
178     delete mEventHandler;
179     mEventHandler = NULL;
180   }
181
182   if (mCore)
183   {
184     delete mCore;
185     mCore = NULL;
186   }
187
188   // Delete EGL factory after Core, otherwise we may have a crash from GL resource destructors
189   if ( mEglFactory )
190   {
191     delete mEglFactory;
192     mEglFactory = NULL;
193   }
194
195   // Delete feedback controller before feedback plugin & style monitor dependencies
196   delete mFeedbackController;
197
198   if (mDaliFeedbackPlugin)
199   {
200     delete mDaliFeedbackPlugin;
201     mDaliFeedbackPlugin = NULL;
202   }
203
204   if (mGLES)
205   {
206     delete mGLES;
207     mGLES = NULL;
208   }
209
210   if (mGestureManager)
211   {
212     delete mGestureManager;
213     mGestureManager = NULL;
214   }
215
216   if (mPlatformAbstraction)
217   {
218     delete mPlatformAbstraction;
219     mPlatformAbstraction = NULL;
220   }
221
222   if (mCallbackManager)
223   {
224     delete mCallbackManager;
225     mCallbackManager = NULL;
226   }
227
228   if( mPerformanceInterface )
229   {
230     delete mPerformanceInterface;
231     mPerformanceInterface = NULL;
232   }
233
234   // uninstall it on this thread (main actor thread)
235   Dali::Integration::Log::UninstallLogFunction();
236 }
237
238 void Adaptor::Start()
239 {
240   // it doesn't support restart after stop at this moment
241   // to support restarting, need more testing
242   if( READY != mState )
243   {
244     return;
245   }
246
247   // Start the callback manager
248   mCallbackManager->Start();
249
250   // create event handler
251   mEventHandler = new EventHandler( mSurface, *this, *mGestureManager, *this, mDragAndDropDetector );
252
253   if( mDeferredRotationObserver != NULL )
254   {
255     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
256     mDeferredRotationObserver = NULL;
257   }
258
259   // guarantee map the surface before starting render-thread.
260   mSurface->Map();
261
262   // NOTE: dpi must be set before starting the render thread
263   // use default or command line settings if not run on device
264 #ifdef __arm__
265   // set the DPI value for font rendering
266   unsigned int dpiHor, dpiVer;
267   dpiHor = dpiVer = 0;
268   mSurface->GetDpi(dpiHor, dpiVer);
269
270   // tell core about the value
271   mCore->SetDpi(dpiHor, dpiVer);
272 #else
273   mCore->SetDpi(mHDpi, mVDpi);
274 #endif
275
276   // Tell the core the size of the surface just before we start the render-thread
277   PositionSize size = mSurface->GetPositionSize();
278   mCore->SurfaceResized( size.width, size.height );
279
280   // Start the update & render threads
281   mUpdateRenderController->Start();
282
283   mState = RUNNING;
284
285   ProcessCoreEvents(); // Ensure any startup messages are processed.
286
287   if ( !mFeedbackController )
288   {
289     // Start sound & haptic feedback
290     mFeedbackController = new FeedbackController( *mDaliFeedbackPlugin );
291   }
292
293   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
294   {
295     (*iter)->OnStart();
296   }
297 }
298
299 // Dali::Internal::Adaptor::Adaptor::Pause
300 void Adaptor::Pause()
301 {
302   // Only pause the adaptor if we're actually running.
303   if( RUNNING == mState )
304   {
305     // Inform observers that we are about to be paused.
306     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
307     {
308       (*iter)->OnPause();
309     }
310
311     // Reset the event handler when adaptor paused
312     if( mEventHandler )
313     {
314       mEventHandler->Reset();
315     }
316
317     mUpdateRenderController->Pause();
318     mCore->Suspend();
319     mState = PAUSED;
320   }
321 }
322
323 // Dali::Internal::Adaptor::Adaptor::Resume
324 void Adaptor::Resume()
325 {
326   // Only resume the adaptor if we are in the suspended state.
327   if( PAUSED == mState )
328   {
329     mCore->Resume();
330     mUpdateRenderController->Resume();
331     mState = RUNNING;
332
333     // Reset the event handler when adaptor resumed
334     if( mEventHandler )
335     {
336       mEventHandler->Reset();
337     }
338
339     // Inform observers that we have resumed.
340     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
341     {
342       (*iter)->OnResume();
343     }
344
345     ProcessCoreEvents(); // Ensure any outstanding messages are processed
346   }
347 }
348
349 void Adaptor::Stop()
350 {
351   if( RUNNING == mState ||
352       PAUSED  == mState ||
353       PAUSED_WHILE_HIDDEN == mState )
354   {
355     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
356     {
357       (*iter)->OnStop();
358     }
359
360     mUpdateRenderController->Stop();
361     mCore->Suspend();
362
363     // Delete the TTS player
364     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
365     {
366       if(mTtsPlayers[i])
367       {
368         mTtsPlayers[i].Reset();
369       }
370     }
371
372     delete mEventHandler;
373     mEventHandler = NULL;
374
375     delete mNotificationTrigger;
376     mNotificationTrigger = NULL;
377
378     mCallbackManager->Stop();
379
380     mState = STOPPED;
381   }
382 }
383
384 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
385 {
386   mEventHandler->FeedTouchPoint( point, timeStamp );
387 }
388
389 void Adaptor::FeedWheelEvent( MouseWheelEvent& wheelEvent )
390 {
391   mEventHandler->FeedWheelEvent( wheelEvent );
392 }
393
394 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
395 {
396   mEventHandler->FeedKeyEvent( keyEvent );
397 }
398
399 bool Adaptor::MoveResize( const PositionSize& positionSize )
400 {
401   PositionSize old = mSurface->GetPositionSize();
402
403   // just resize the surface. The driver should automatically resize the egl Surface (untested)
404   // EGL Spec says : EGL window surfaces need to be resized when their corresponding native window
405   // is resized. Implementations typically use hooks into the OS and native window
406   // system to perform this resizing on demand, transparently to the client.
407   mSurface->MoveResize( positionSize );
408
409   if(old.width != positionSize.width || old.height != positionSize.height)
410   {
411     SurfaceSizeChanged(positionSize);
412   }
413
414   return true;
415 }
416
417 void Adaptor::SurfaceResized( const PositionSize& positionSize )
418 {
419   PositionSize old = mSurface->GetPositionSize();
420
421   // Called by an application, when it has resized a window outside of Dali.
422   // The EGL driver automatically detects X Window resize calls, and resizes
423   // the EGL surface for us.
424   mSurface->MoveResize( positionSize );
425
426   if(old.width != positionSize.width || old.height != positionSize.height)
427   {
428     SurfaceSizeChanged(positionSize);
429   }
430 }
431
432 void Adaptor::ReplaceSurface( Dali::RenderSurface& surface )
433 {
434   // adaptor implementation needs the implementation of
435   RenderSurface* internalSurface = dynamic_cast<Internal::Adaptor::RenderSurface*>( &surface );
436   DALI_ASSERT_ALWAYS( internalSurface && "Incorrect surface" );
437
438   mSurface = internalSurface;
439
440   SurfaceSizeChanged( internalSurface->GetPositionSize() );
441
442   // flush the event queue to give update and render threads chance
443   // to start processing messages for new camera setup etc as soon as possible
444   ProcessCoreEvents();
445
446   // this method is synchronous
447   mUpdateRenderController->ReplaceSurface(internalSurface);
448 }
449
450 void Adaptor::RenderSync()
451 {
452   mUpdateRenderController->RenderSync();
453 }
454
455 Dali::RenderSurface& Adaptor::GetSurface() const
456 {
457   return *mSurface;
458 }
459
460 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
461 {
462   if(!mTtsPlayers[mode])
463   {
464     // Create the TTS player when it needed, because it can reduce launching time.
465     mTtsPlayers[mode] = TtsPlayer::New(mode);
466   }
467
468   return mTtsPlayers[mode];
469 }
470
471 bool Adaptor::AddIdle(boost::function<void(void)> callBack)
472 {
473   bool idleAdded(false);
474
475   // Only add an idle if the Adaptor is actually running
476   if( RUNNING == mState )
477   {
478     idleAdded = mCallbackManager->AddCallback(callBack, CallbackManager::IDLE_PRIORITY);
479   }
480
481   return idleAdded;
482 }
483
484 bool Adaptor::CallFromMainLoop(boost::function<void(void)> callBack)
485 {
486   bool callAdded(false);
487
488   // Only allow the callback if the Adaptor is actually running
489   if ( RUNNING == mState )
490   {
491     callAdded = mCallbackManager->AddCallback(callBack, CallbackManager::DEFAULT_PRIORITY);
492   }
493
494   return callAdded;
495 }
496
497 Dali::Adaptor& Adaptor::Get()
498 {
499   DALI_ASSERT_ALWAYS( gThreadLocalAdaptor.get() != NULL && "Adaptor not instantiated" );
500   return gThreadLocalAdaptor->mAdaptor;
501 }
502
503 bool Adaptor::IsAvailable()
504 {
505   return gThreadLocalAdaptor.get() != NULL;
506 }
507
508 Dali::Integration::Core& Adaptor::GetCore()
509 {
510   return *mCore;
511 }
512
513 void Adaptor::DisableVSync()
514 {
515   mUpdateRenderController->DisableVSync();
516 }
517
518 void Adaptor::SetDpi(size_t hDpi, size_t vDpi)
519 {
520   mHDpi = hDpi;
521   mVDpi = vDpi;
522 }
523
524 EglFactory& Adaptor::GetEGLFactory() const
525 {
526   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
527   return *mEglFactory;
528 }
529
530 EglFactoryInterface& Adaptor::GetEGLFactoryInterface() const
531 {
532   return *mEglFactory;
533 }
534
535 Integration::GlAbstraction& Adaptor::GetGlAbstraction() const
536 {
537   DALI_ASSERT_DEBUG( mGLES && "GLImplementation not created" );
538   return *mGLES;
539 }
540
541 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
542 {
543   return *mPlatformAbstraction;
544 }
545
546 Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
547 {
548   return *mGLES;
549 }
550
551 TriggerEventInterface& Adaptor::GetTriggerEventInterface()
552 {
553   return *mNotificationTrigger;
554 }
555 RenderSurface* Adaptor::GetRenderSurfaceInterface()
556 {
557   return mSurface;
558 }
559 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
560 {
561   return mVSyncMonitor;
562 }
563
564 KernelTraceInterface& Adaptor::GetKernelTraceInterface()
565 {
566   return mKernelTracer;
567 }
568
569 PerformanceInterface* Adaptor::GetPerformanceInterface()
570 {
571   return mPerformanceInterface;
572 }
573
574 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
575 {
576   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
577   return *mPlatformAbstraction;
578 }
579
580 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
581 {
582   mDragAndDropDetector = detector;
583
584   if ( mEventHandler )
585   {
586     mEventHandler->SetDragAndDropDetector( detector );
587   }
588 }
589
590 void Adaptor::SetRotationObserver( RotationObserver* observer )
591 {
592   if( mEventHandler )
593   {
594     mEventHandler->SetRotationObserver( observer );
595   }
596   else if( mState == READY )
597   {
598     // Set once event handler exists
599     mDeferredRotationObserver = observer;
600   }
601 }
602
603 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
604 {
605   if(mTtsPlayers[mode])
606   {
607     mTtsPlayers[mode].Reset();
608   }
609 }
610
611 void Adaptor::AddObserver( LifeCycleObserver& observer )
612 {
613   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
614
615   if ( match == mObservers.end() )
616   {
617     mObservers.push_back( &observer );
618   }
619 }
620
621 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
622 {
623   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
624
625   if ( match != mObservers.end() )
626   {
627     mObservers.erase( match );
628   }
629 }
630
631 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
632 {
633   if( mCore )
634   {
635     mCore->QueueEvent(event);
636   }
637 }
638
639 void Adaptor::ProcessCoreEvents()
640 {
641   if( mCore )
642   {
643     if( mPerformanceInterface )
644     {
645       mPerformanceInterface->AddMarker( PerformanceMarker::PROCESS_EVENTS_START );
646     }
647
648     mCore->ProcessEvents();
649
650     if( mPerformanceInterface )
651     {
652       mPerformanceInterface->AddMarker( PerformanceMarker::PROCESS_EVENTS_END );
653     }
654
655   }
656 }
657
658 void Adaptor::RequestUpdate()
659 {
660   // When Dali applications are partially visible behind the lock-screen,
661   // the indicator must be updated (therefore allow updates in the PAUSED state)
662   if ( PAUSED  == mState ||
663        RUNNING == mState )
664   {
665     mUpdateRenderController->RequestUpdate();
666   }
667 }
668
669 void Adaptor::RequestProcessEventsOnIdle()
670 {
671   // Only request a notification if the Adaptor is actually running
672   if ( RUNNING == mState )
673   {
674     boost::unique_lock<boost::mutex> lock( mIdleInstaller );
675
676     // check if the idle handle is already installed
677     if( mNotificationOnIdleInstalled )
678     {
679       return;
680     }
681     mNotificationOnIdleInstalled = AddIdle( boost::bind( &Adaptor::ProcessCoreEventsFromIdle, this ) );
682   }
683 }
684
685 void Adaptor::OnWindowShown()
686 {
687   if ( PAUSED_WHILE_HIDDEN == mState )
688   {
689     // Adaptor can now be resumed
690     mState = PAUSED;
691
692     Resume();
693
694     // Force a render task
695     RequestUpdateOnce();
696   }
697 }
698
699 void Adaptor::OnWindowHidden()
700 {
701   if ( STOPPED != mState )
702   {
703     Pause();
704
705     // Adaptor cannot be resumed until the window is shown
706     mState = PAUSED_WHILE_HIDDEN;
707   }
708 }
709
710 // Dali::Internal::Adaptor::Adaptor::OnDamaged
711 void Adaptor::OnDamaged( const DamageArea& area )
712 {
713   // This is needed for the case where Dali window is partially obscured
714   RequestUpdate();
715 }
716
717 void Adaptor::SurfaceSizeChanged(const PositionSize& positionSize)
718 {
719   // let the core know the surface size has changed
720   mCore->SurfaceResized(positionSize.width, positionSize.height);
721
722   mResizedSignalV2.Emit( mAdaptor );
723 }
724
725 void Adaptor::NotifyLanguageChanged()
726 {
727   mLanguageChangedSignalV2.Emit( mAdaptor );
728 }
729
730 void Adaptor::RequestUpdateOnce()
731 {
732   if( PAUSED_WHILE_HIDDEN != mState )
733   {
734     if( mUpdateRenderController )
735     {
736       mUpdateRenderController->RequestUpdateOnce();
737     }
738   }
739 }
740
741 void Adaptor::ProcessCoreEventsFromIdle()
742 {
743   ProcessCoreEvents();
744
745   // the idle handle automatically un-installs itself
746   mNotificationOnIdleInstalled = false;
747 }
748
749 void Adaptor::RegisterSingleton(const std::type_info& info, BaseHandle singleton)
750 {
751   if(singleton)
752   {
753     mSingletonContainer.insert(SingletonPair(info.name(), singleton));
754   }
755 }
756
757 BaseHandle Adaptor::GetSingleton(const std::type_info& info) const
758 {
759   BaseHandle object = Dali::BaseHandle();
760
761   SingletonConstIter iter = mSingletonContainer.find(info.name());
762   if(iter != mSingletonContainer.end())
763   {
764     object = (*iter).second;
765   }
766
767   return object;
768 }
769
770 Adaptor::Adaptor(Dali::Adaptor& adaptor, RenderSurface* surface, const DeviceLayout& baseLayout)
771 : mAdaptor(adaptor),
772   mState(READY),
773   mCore(NULL),
774   mUpdateRenderController(NULL),
775   mVSyncMonitor(NULL),
776   mGLES( NULL ),
777   mEglFactory( NULL ),
778   mSurface( surface ),
779   mPlatformAbstraction( NULL ),
780   mEventHandler( NULL ),
781   mCallbackManager( NULL ),
782   mNotificationOnIdleInstalled( false ),
783   mNotificationTrigger(NULL),
784   mGestureManager(NULL),
785   mHDpi( 0 ),
786   mVDpi( 0 ),
787   mDaliFeedbackPlugin(NULL),
788   mFeedbackController(NULL),
789   mObservers(),
790   mDragAndDropDetector(),
791   mDeferredRotationObserver(NULL),
792   mBaseLayout(baseLayout),
793   mLogOptions(),
794   mPerformanceInterface(NULL)
795 {
796   DALI_ASSERT_ALWAYS( gThreadLocalAdaptor.get() == NULL && "Cannot create more than one Adaptor per thread" );
797   gThreadLocalAdaptor.reset(this);
798 }
799
800 } // namespace Adaptor
801
802 } // namespace Internal
803
804 } // namespace Dali