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