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