Revert "[Tizen] Revert "Support multiple window rendering""
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
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
18 // CLASS HEADER
19 #include <dali/internal/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
21
22 // EXTERNAL INCLUDES
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/touch-event-integ.h>
33 #include <dali/integration-api/processor-interface.h>
34
35 // INTERNAL INCLUDES
36 #include <dali/public-api/dali-adaptor-common.h>
37 #include <dali/internal/system/common/thread-controller.h>
38 #include <dali/internal/system/common/performance-interface-factory.h>
39 #include <dali/internal/adaptor/common/lifecycle-observer.h>
40
41 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
42 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
43
44 #include <dali/devel-api/text-abstraction/font-client.h>
45
46 #include <dali/internal/system/common/callback-manager.h>
47 #include <dali/internal/accessibility/common/tts-player-impl.h>
48 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
49 #include <dali/internal/input/common/gesture-manager.h>
50 #include <dali/internal/window-system/common/event-handler.h>
51 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
52 #include <dali/internal/graphics/gles/gl-implementation.h>
53 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
54 #include <dali/internal/graphics/common/egl-image-extensions.h>
55 #include <dali/internal/clipboard/common/clipboard-impl.h>
56 #include <dali/internal/graphics/common/vsync-monitor.h>
57 #include <dali/internal/system/common/object-profiler.h>
58 #include <dali/internal/window-system/common/display-connection.h>
59 #include <dali/internal/window-system/common/window-impl.h>
60 #include <dali/internal/window-system/common/window-render-surface.h>
61
62 #include <dali/internal/system/common/logging.h>
63
64 #include <dali/internal/system/common/locale-utils.h>
65 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
66 #include <dali/internal/imaging/common/image-loader.h>
67
68
69 using Dali::TextAbstraction::FontClient;
70
71 namespace Dali
72 {
73
74 namespace Internal
75 {
76
77 namespace Adaptor
78 {
79
80 namespace
81 {
82 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
83 } // unnamed namespace
84
85
86 Dali::Adaptor* Adaptor::New( Any nativeWindow, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
87 {
88   Dali::Adaptor* adaptor = new Dali::Adaptor;
89   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
90   adaptor->mImpl = impl;
91
92   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
93   auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
94
95   impl->Initialize( graphicsFactory, configuration );
96   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
97
98   return adaptor;
99 }
100
101 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
102 {
103   Any winId = window.GetNativeHandle();
104
105   Window& windowImpl = Dali::GetImplementation( window );
106   Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
107   windowImpl.SetAdaptor( *adaptor );
108   return adaptor;
109 }
110
111 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Any nativeWindow, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
112 {
113   Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
114   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions ); // Impl adaptor
115   adaptor->mImpl = impl;
116
117   impl->Initialize( graphicsFactory, configuration );
118
119   return adaptor;
120 } // Called second
121
122 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
123 {
124   Any winId = window.GetNativeHandle();
125
126   Window& windowImpl = Dali::GetImplementation( window );
127   Dali::Adaptor* adaptor = New( graphicsFactory, winId, windowImpl.GetSurface(), configuration, environmentOptions );
128   windowImpl.SetAdaptor( *adaptor );
129   return adaptor;
130 } // Called first
131
132 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
133 {
134   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
135   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
136   mEnvironmentOptions->SetLogFunction( logFunction );
137   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
138
139   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
140
141   std::string path;
142   GetDataStoragePath( path );
143   mPlatformAbstraction->SetDataStoragePath( path );
144
145   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
146   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
147   {
148     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
149   }
150
151   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
152
153   if( mEnvironmentOptions->PerformanceServerRequired() )
154   {
155     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
156   }
157
158   mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
159   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
160
161   mCallbackManager = CallbackManager::New();
162
163   WindowPane defaultWindow = mWindowFrame.front();
164
165   DALI_ASSERT_DEBUG( defaultWindow.surface && "Surface not initialized" );
166
167   PositionSize size = defaultWindow.surface->GetPositionSize();
168
169   defaultWindow.surface->SetAdaptor(*this);
170
171   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
172
173   mGraphics = &( graphicsFactory.Create() );
174   mGraphics->Initialize( mEnvironmentOptions );
175
176   auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
177
178   // This will only be created once
179   eglGraphics->Create();
180
181   GlImplementation& mGLES = eglGraphics->GetGlesInterface();
182   EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
183
184   mCore = Integration::Core::New( *this,
185                                   *mPlatformAbstraction,
186                                   mGLES,
187                                   eglSyncImpl,
188                                   *mGestureManager,
189                                   dataRetentionPolicy ,
190                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
191                                   mGraphics->GetDepthBufferRequired(),
192                                   mGraphics->GetStencilBufferRequired() );
193
194   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
195   if( 0u < timeInterval )
196   {
197     mObjectProfiler = new ObjectProfiler( timeInterval );
198   }
199
200   mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
201
202   mVSyncMonitor = new VSyncMonitor;
203
204   mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow.surface->GetSurfaceType() );
205
206   mThreadController = new ThreadController( *this, *mEnvironmentOptions );
207
208   // Should be called after Core creation
209   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
210   {
211     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
212   }
213   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
214   {
215     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
216   }
217   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
218   {
219     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
220   }
221   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
222   {
223     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
224   }
225   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
226   {
227     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
228   }
229   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
230   {
231     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
232   }
233   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
234   {
235     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
236   }
237   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
238   {
239     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
240   }
241   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
242   {
243     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
244   }
245   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
246   {
247     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
248   }
249   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
250   {
251     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
252   }
253   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
254   {
255     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
256   }
257   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
258   {
259     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
260   }
261   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
262   {
263     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
264   }
265   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
266   {
267     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
268   }
269   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
270   {
271     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
272   }
273
274   // Set max texture size
275   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
276   {
277     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
278   }
279 }
280
281 Adaptor::~Adaptor()
282 {
283   // Ensure stop status
284   Stop();
285
286   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
287   gThreadLocalAdaptor = NULL;
288
289   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
290   {
291     (*iter)->OnDestroy();
292   }
293
294   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
295   delete mVSyncMonitor;
296   delete mEventHandler;
297   delete mObjectProfiler;
298
299   delete mCore;
300
301   delete mGestureManager;
302   delete mDisplayConnection;
303   delete mPlatformAbstraction;
304   delete mCallbackManager;
305   delete mPerformanceInterface;
306
307   mGraphics->Destroy();
308
309   // uninstall it on this thread (main actor thread)
310   Dali::Integration::Log::UninstallLogFunction();
311
312   // Delete environment options if we own it
313   if( mEnvironmentOptionsOwned )
314   {
315     delete mEnvironmentOptions;
316   }
317 }
318
319 void Adaptor::Start()
320 {
321   // It doesn't support restart after stop at this moment to support restarting, need more testing
322   if( READY != mState )
323   {
324     return;
325   }
326
327   mCore->Initialize();
328
329   SetupSystemInformation();
330
331   // Start the callback manager
332   mCallbackManager->Start();
333
334   WindowPane defaultWindow = mWindowFrame.front();
335
336   // Create event handler
337   mEventHandler = new EventHandler( defaultWindow.surface, *this, *mGestureManager, *this, mDragAndDropDetector );
338
339   if( mDeferredRotationObserver != NULL )
340   {
341     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
342     mDeferredRotationObserver = NULL;
343   }
344
345   unsigned int dpiHor, dpiVer;
346   dpiHor = dpiVer = 0;
347
348   defaultWindow.surface->GetDpi( dpiHor, dpiVer );
349
350   // set the DPI value for font rendering
351   FontClient fontClient = FontClient::Get();
352   fontClient.SetDpi( dpiHor, dpiVer );
353
354   // Tell the core the size of the surface just before we start the render-thread
355   mCore->SurfaceResized( defaultWindow.surface );
356
357   // Initialize the thread controller
358   mThreadController->Initialize();
359
360   ProcessCoreEvents(); // Ensure any startup messages are processed.
361
362   // Initialize the image loader plugin
363   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
364
365   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
366   {
367     (*iter)->OnStart();
368   }
369 }
370
371 // Dali::Internal::Adaptor::Adaptor::Pause
372 void Adaptor::Pause()
373 {
374   // Only pause the adaptor if we're actually running.
375   if( RUNNING == mState )
376   {
377     // Inform observers that we are about to be paused.
378     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
379     {
380       (*iter)->OnPause();
381     }
382
383     // Reset the event handler when adaptor paused
384     if( mEventHandler )
385     {
386       mEventHandler->Pause();
387     }
388
389     mThreadController->Pause();
390     mState = PAUSED;
391
392     // Ensure any messages queued during pause callbacks are processed by doing another update.
393     RequestUpdateOnce();
394   }
395 }
396
397 // Dali::Internal::Adaptor::Adaptor::Resume
398 void Adaptor::Resume()
399 {
400   // Only resume the adaptor if we are in the suspended state.
401   if( PAUSED == mState )
402   {
403     mState = RUNNING;
404
405     // Reset the event handler when adaptor resumed
406     if( mEventHandler )
407     {
408       mEventHandler->Resume();
409     }
410
411     // Inform observers that we have resumed.
412     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
413     {
414       (*iter)->OnResume();
415     }
416
417     // Trigger processing of events queued up while paused
418     mCore->ProcessEvents();
419
420     // Do at end to ensure our first update/render after resumption includes the processed messages as well
421     mThreadController->Resume();
422   }
423 }
424
425 void Adaptor::Stop()
426 {
427   if( RUNNING == mState ||
428       PAUSED  == mState ||
429       PAUSED_WHILE_HIDDEN == mState )
430   {
431     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
432     {
433       (*iter)->OnStop();
434     }
435
436     mThreadController->Stop();
437
438     // Clear out all the handles to Windows
439     mWindowFrame.clear();
440
441     // Delete the TTS player
442     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
443     {
444       if(mTtsPlayers[i])
445       {
446         mTtsPlayers[i].Reset();
447       }
448     }
449
450     // Destroy the image loader plugin
451     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
452
453     delete mEventHandler;
454     mEventHandler = NULL;
455
456     delete mNotificationTrigger;
457     mNotificationTrigger = NULL;
458
459     mCallbackManager->Stop();
460
461     mState = STOPPED;
462   }
463 }
464
465 void Adaptor::ContextLost()
466 {
467   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
468 }
469
470 void Adaptor::ContextRegained()
471 {
472   // Inform core, so that texture resources can be reloaded
473   mCore->RecoverFromContextLoss();
474
475   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
476 }
477
478 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
479 {
480   mEventHandler->FeedTouchPoint( point, timeStamp );
481 }
482
483 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
484 {
485   mEventHandler->FeedWheelEvent( wheelEvent );
486 }
487
488 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
489 {
490   mEventHandler->FeedKeyEvent( keyEvent );
491 }
492
493 void Adaptor::ReplaceSurface( Any nativeWindow, Dali::RenderSurfaceInterface& newSurface )
494 {
495   // Let the core know the surface size has changed
496   mCore->SurfaceResized( &newSurface );
497
498   mResizedSignal.Emit( mAdaptor );
499
500   WindowPane newDefaultWindow;
501   newDefaultWindow.nativeWindow = nativeWindow;
502   newDefaultWindow.surface = &newSurface;
503   newDefaultWindow.surface->SetAdaptor(*this);
504
505   WindowPane oldDefaultWindow = mWindowFrame.front();
506
507   // Update WindowFrame
508   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
509   iter = mWindowFrame.insert( iter, newDefaultWindow );
510
511   // Flush the event queue to give the update-render thread chance
512   // to start processing messages for new camera setup etc as soon as possible
513   ProcessCoreEvents();
514
515   // This method blocks until the render thread has completed the replace.
516   mThreadController->ReplaceSurface( newDefaultWindow.surface );
517
518   // Must delete the old Window only after the render thread has completed the replace
519   oldDefaultWindow.surface->DestroySurface();
520   oldDefaultWindow.surface = nullptr;
521 }
522
523 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
524 {
525   WindowPane defaultWindow = mWindowFrame.front();
526   return *(defaultWindow.surface);
527 }
528
529 void Adaptor::ReleaseSurfaceLock()
530 {
531   WindowPane defaultWindow = mWindowFrame.front();
532   defaultWindow.surface->ReleaseLock();
533 }
534
535 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
536 {
537   if(!mTtsPlayers[mode])
538   {
539     // Create the TTS player when it needed, because it can reduce launching time.
540     mTtsPlayers[mode] = TtsPlayer::New(mode);
541   }
542
543   return mTtsPlayers[mode];
544 }
545
546 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
547 {
548   bool idleAdded(false);
549
550   // Only add an idle if the Adaptor is actually running
551   if( RUNNING == mState || READY == mState || forceAdd )
552   {
553     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
554   }
555
556   return idleAdded;
557 }
558
559 void Adaptor::RemoveIdle( CallbackBase* callback )
560 {
561   mCallbackManager->RemoveIdleCallback( callback );
562 }
563
564 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
565 {
566   mThreadController->SetPreRenderCallback( callback );
567 }
568
569 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
570 {
571   Window& windowImpl = Dali::GetImplementation( *childWindow );
572   windowImpl.SetAdaptor( Get() );
573
574   // This is any Window that is not the main (default) one
575   WindowPane additionalWindow;
576   additionalWindow.instance = childWindow;
577   additionalWindow.window_name = childWindowName;
578   additionalWindow.class_name = childWindowClassName;
579   additionalWindow.window_mode = childWindowMode;
580   additionalWindow.surface = windowImpl.GetSurface();
581   additionalWindow.id = windowImpl.GetId();
582
583   // Add the new Window to the Frame - the order is not important
584   mWindowFrame.push_back( additionalWindow );
585
586   return true;
587 }
588
589 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
590 {
591   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
592   {
593     if( iter->instance == childWindow )
594     {
595       mWindowFrame.erase( iter );
596       return true;
597     }
598   }
599
600   return false;
601 }
602
603 bool Adaptor::RemoveWindow( std::string childWindowName )
604 {
605   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
606   {
607     if( iter->window_name == childWindowName )
608     {
609       mWindowFrame.erase( iter );
610       return true;
611     }
612   }
613
614   return false;
615 }
616
617 bool Adaptor::RemoveWindow( Window* childWindow )
618 {
619   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
620   {
621     if( iter->id == childWindow->GetId() )
622     {
623       mWindowFrame.erase( iter );
624       return true;
625     }
626   }
627
628   return false;
629 }
630
631 Dali::Adaptor& Adaptor::Get()
632 {
633   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
634   return gThreadLocalAdaptor->mAdaptor;
635 }
636
637 bool Adaptor::IsAvailable()
638 {
639   return gThreadLocalAdaptor != NULL;
640 }
641
642 void Adaptor::SceneCreated()
643 {
644   mCore->SceneCreated();
645 }
646
647 Dali::Integration::Core& Adaptor::GetCore()
648 {
649   return *mCore;
650 }
651
652 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
653 {
654   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
655 }
656
657 void Adaptor::SetUseHardwareVSync( bool useHardware )
658 {
659   mVSyncMonitor->SetUseHardwareVSync( useHardware );
660 }
661
662 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
663 {
664   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
665   return *mDisplayConnection;
666 }
667
668 GraphicsInterface& Adaptor::GetGraphicsInterface()
669 {
670   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
671   return *mGraphics;
672 }
673
674 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
675 {
676   return *mPlatformAbstraction;
677 }
678
679 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
680 {
681   return *mNotificationTrigger;
682 }
683
684 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
685 {
686   return mTriggerEventFactory;
687 }
688
689 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
690 {
691   return mSocketFactory;
692 }
693
694 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
695 {
696   if( !mWindowFrame.empty())
697   {
698     WindowPane defaultWindow = mWindowFrame.front();
699     return defaultWindow.surface;
700   }
701   else
702   {
703     return nullptr;
704   }
705 }
706
707 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
708 {
709   return mVSyncMonitor;
710 }
711
712 TraceInterface& Adaptor::GetKernelTraceInterface()
713 {
714   return mKernelTracer;
715 }
716
717 TraceInterface& Adaptor::GetSystemTraceInterface()
718 {
719   return mSystemTracer;
720 }
721
722 PerformanceInterface* Adaptor::GetPerformanceInterface()
723 {
724   return mPerformanceInterface;
725 }
726
727 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
728 {
729   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
730   return *mPlatformAbstraction;
731 }
732
733 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
734 {
735   mDragAndDropDetector = detector;
736
737   if ( mEventHandler )
738   {
739     mEventHandler->SetDragAndDropDetector( detector );
740   }
741 }
742
743 void Adaptor::SetRotationObserver( RotationObserver* observer )
744 {
745   if( mEventHandler )
746   {
747     mEventHandler->SetRotationObserver( observer );
748   }
749   else if( mState == READY )
750   {
751     // Set once event handler exists
752     mDeferredRotationObserver = observer;
753   }
754 }
755
756 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
757 {
758   if(mTtsPlayers[mode])
759   {
760     mTtsPlayers[mode].Reset();
761   }
762 }
763
764 void Adaptor::SetMinimumPinchDistance(float distance)
765 {
766   if( mGestureManager )
767   {
768     mGestureManager->SetMinimumPinchDistance(distance);
769   }
770 }
771
772 Any Adaptor::GetNativeWindowHandle()
773 {
774   WindowPane defaultWindow = mWindowFrame.front();
775   return defaultWindow.nativeWindow;
776 }
777
778 Any Adaptor::GetGraphicsDisplay()
779 {
780   Any display;
781
782   if (mGraphics)
783   {
784     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
785
786     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
787     display = eglImpl.GetDisplay();
788   }
789
790   return display;
791 }
792
793 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
794 {
795   mUseRemoteSurface = useRemoteSurface;
796 }
797
798 void Adaptor::AddObserver( LifeCycleObserver& observer )
799 {
800   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
801
802   if ( match == mObservers.end() )
803   {
804     mObservers.push_back( &observer );
805   }
806 }
807
808 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
809 {
810   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
811
812   if ( match != mObservers.end() )
813   {
814     mObservers.erase( match );
815   }
816 }
817
818 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
819 {
820   if( mCore )
821   {
822     mCore->QueueEvent(event);
823   }
824 }
825
826 void Adaptor::ProcessCoreEvents()
827 {
828   if( mCore )
829   {
830     if( mPerformanceInterface )
831     {
832       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
833     }
834
835     mCore->ProcessEvents();
836
837     if( mPerformanceInterface )
838     {
839       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
840     }
841   }
842 }
843
844 void Adaptor::RequestUpdate( bool forceUpdate )
845 {
846   switch( mState )
847   {
848     case RUNNING:
849     {
850       mThreadController->RequestUpdate();
851       break;
852     }
853     case PAUSED:
854     case PAUSED_WHILE_HIDDEN:
855     {
856       // When Dali applications are partially visible behind the lock-screen,
857       // the indicator must be updated (therefore allow updates in the PAUSED state)
858       if( forceUpdate )
859       {
860         mThreadController->RequestUpdateOnce();
861       }
862       break;
863     }
864     default:
865     {
866       // Do nothing
867       break;
868     }
869   }
870 }
871
872 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
873 {
874   // Only request a notification if the Adaptor is actually running
875   // and we haven't installed the idle notification
876   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
877   {
878     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
879   }
880 }
881
882 void Adaptor::OnWindowShown()
883 {
884   if ( PAUSED_WHILE_HIDDEN == mState )
885   {
886     // Adaptor can now be resumed
887     mState = PAUSED;
888
889     Resume();
890
891     // Force a render task
892     RequestUpdateOnce();
893   }
894 }
895
896 void Adaptor::OnWindowHidden()
897 {
898   if ( RUNNING == mState )
899   {
900     Pause();
901
902     // Adaptor cannot be resumed until the window is shown
903     mState = PAUSED_WHILE_HIDDEN;
904   }
905 }
906
907 // Dali::Internal::Adaptor::Adaptor::OnDamaged
908 void Adaptor::OnDamaged( const DamageArea& area )
909 {
910   // This is needed for the case where Dali window is partially obscured
911   RequestUpdate( false );
912 }
913
914 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
915 {
916   // Let the core know the surface size has changed
917   mCore->SurfaceResized( surface );
918
919   mResizedSignal.Emit( mAdaptor );
920 }
921
922 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
923 {
924   // Flush the event queue to give the update-render thread chance
925   // to start processing messages for new camera setup etc as soon as possible
926   ProcessCoreEvents();
927
928   mThreadController->ResizeSurface();
929 }
930
931 void Adaptor::NotifySceneCreated()
932 {
933   GetCore().SceneCreated();
934
935   // Start thread controller after the scene has been created
936   mThreadController->Start();
937
938   // Process after surface is created (registering to remote surface provider if required)
939   SurfaceInitialized();
940
941   mState = RUNNING;
942 }
943
944 void Adaptor::NotifyLanguageChanged()
945 {
946   mLanguageChangedSignal.Emit( mAdaptor );
947 }
948
949 void Adaptor::RenderOnce()
950 {
951   RequestUpdateOnce();
952 }
953
954 const LogFactoryInterface& Adaptor::GetLogFactory()
955 {
956   return *mEnvironmentOptions;
957 }
958
959 void Adaptor::RegisterProcessor( Integration::Processor& processor )
960 {
961   GetCore().RegisterProcessor(processor);
962 }
963
964 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
965 {
966   GetCore().UnregisterProcessor(processor);
967 }
968
969 void Adaptor::RequestUpdateOnce()
970 {
971   if( mThreadController )
972   {
973     mThreadController->RequestUpdateOnce();
974   }
975 }
976
977 bool Adaptor::ProcessCoreEventsFromIdle()
978 {
979   ProcessCoreEvents();
980
981   // the idle handle automatically un-installs itself
982   mNotificationOnIdleInstalled = false;
983
984   return false;
985 }
986
987 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
988 : mResizedSignal(),
989   mLanguageChangedSignal(),
990   mAdaptor( adaptor ),
991   mState( READY ),
992   mCore( nullptr ),
993   mThreadController( nullptr ),
994   mVSyncMonitor( nullptr ),
995   mGraphics( nullptr ),
996   mDisplayConnection( nullptr ),
997   mWindowFrame(),
998   mPlatformAbstraction( nullptr ),
999   mEventHandler( nullptr ),
1000   mCallbackManager( nullptr ),
1001   mNotificationOnIdleInstalled( false ),
1002   mNotificationTrigger( nullptr ),
1003   mGestureManager( nullptr ),
1004   mDaliFeedbackPlugin(),
1005   mFeedbackController( nullptr ),
1006   mTtsPlayers(),
1007   mObservers(),
1008   mDragAndDropDetector(),
1009   mDeferredRotationObserver( nullptr ),
1010   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1011   mPerformanceInterface( nullptr ),
1012   mKernelTracer(),
1013   mSystemTracer(),
1014   mTriggerEventFactory(),
1015   mObjectProfiler( nullptr ),
1016   mSocketFactory(),
1017   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1018   mUseRemoteSurface( false )
1019 {
1020   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1021
1022   WindowPane defaultWindow;
1023   defaultWindow.nativeWindow = nativeWindow;
1024   defaultWindow.surface = surface;
1025   defaultWindow.id = 0;
1026
1027   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1028   iter = mWindowFrame.insert( iter, defaultWindow );
1029
1030   gThreadLocalAdaptor = this;
1031 }
1032
1033 void Adaptor::SetRootLayoutDirection( std::string locale )
1034 {
1035   Dali::Stage stage = Dali::Stage::GetCurrent();
1036
1037   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1038                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1039 }
1040
1041 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1042 {
1043   bool idleAdded( false );
1044
1045   // Only add an idle if the Adaptor is actually running
1046   if( RUNNING == mState || READY == mState || forceAdd )
1047   {
1048     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1049   }
1050
1051   return idleAdded;
1052 }
1053
1054 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1055 {
1056   mCallbackManager->RemoveIdleEntererCallback( callback );
1057 }
1058
1059 } // namespace Adaptor
1060
1061 } // namespace Internal
1062
1063 } // namespace Dali