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     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
396   }
397   else
398   {
399     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
400   }
401 }
402
403 // Dali::Internal::Adaptor::Adaptor::Resume
404 void Adaptor::Resume()
405 {
406   // Only resume the adaptor if we are in the suspended state.
407   if( PAUSED == mState )
408   {
409     mState = RUNNING;
410
411     // Reset the event handler when adaptor resumed
412     if( mEventHandler )
413     {
414       mEventHandler->Resume();
415     }
416
417     // Inform observers that we have resumed.
418     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
419     {
420       (*iter)->OnResume();
421     }
422
423     // Trigger processing of events queued up while paused
424     mCore->ProcessEvents();
425
426     // Do at end to ensure our first update/render after resumption includes the processed messages as well
427     mThreadController->Resume();
428
429     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
430   }
431   else
432   {
433     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
434   }
435 }
436
437 void Adaptor::Stop()
438 {
439   if( RUNNING == mState ||
440       PAUSED  == mState ||
441       PAUSED_WHILE_HIDDEN == mState )
442   {
443     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
444     {
445       (*iter)->OnStop();
446     }
447
448     mThreadController->Stop();
449
450     // Clear out all the handles to Windows
451     mWindowFrame.clear();
452
453     // Delete the TTS player
454     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
455     {
456       if(mTtsPlayers[i])
457       {
458         mTtsPlayers[i].Reset();
459       }
460     }
461
462     // Destroy the image loader plugin
463     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
464
465     delete mEventHandler;
466     mEventHandler = NULL;
467
468     delete mNotificationTrigger;
469     mNotificationTrigger = NULL;
470
471     mCallbackManager->Stop();
472
473     mState = STOPPED;
474
475     DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
476   }
477 }
478
479 void Adaptor::ContextLost()
480 {
481   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
482 }
483
484 void Adaptor::ContextRegained()
485 {
486   // Inform core, so that texture resources can be reloaded
487   mCore->RecoverFromContextLoss();
488
489   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
490 }
491
492 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
493 {
494   mEventHandler->FeedTouchPoint( point, timeStamp );
495 }
496
497 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
498 {
499   mEventHandler->FeedWheelEvent( wheelEvent );
500 }
501
502 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
503 {
504   mEventHandler->FeedKeyEvent( keyEvent );
505 }
506
507 void Adaptor::ReplaceSurface( Any nativeWindow, Dali::RenderSurfaceInterface& newSurface )
508 {
509   // Let the core know the surface size has changed
510   mCore->SurfaceResized( &newSurface );
511
512   mResizedSignal.Emit( mAdaptor );
513
514   WindowPane newDefaultWindow;
515   newDefaultWindow.nativeWindow = nativeWindow;
516   newDefaultWindow.surface = &newSurface;
517   newDefaultWindow.surface->SetAdaptor(*this);
518
519   WindowPane oldDefaultWindow = mWindowFrame.front();
520
521   // Update WindowFrame
522   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
523   iter = mWindowFrame.insert( iter, newDefaultWindow );
524
525   // Flush the event queue to give the update-render thread chance
526   // to start processing messages for new camera setup etc as soon as possible
527   ProcessCoreEvents();
528
529   // This method blocks until the render thread has completed the replace.
530   mThreadController->ReplaceSurface( newDefaultWindow.surface );
531
532   // Must delete the old Window only after the render thread has completed the replace
533   oldDefaultWindow.surface->DestroySurface();
534   oldDefaultWindow.surface = nullptr;
535 }
536
537 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
538 {
539   WindowPane defaultWindow = mWindowFrame.front();
540   return *(defaultWindow.surface);
541 }
542
543 void Adaptor::ReleaseSurfaceLock()
544 {
545   WindowPane defaultWindow = mWindowFrame.front();
546   defaultWindow.surface->ReleaseLock();
547 }
548
549 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
550 {
551   if(!mTtsPlayers[mode])
552   {
553     // Create the TTS player when it needed, because it can reduce launching time.
554     mTtsPlayers[mode] = TtsPlayer::New(mode);
555   }
556
557   return mTtsPlayers[mode];
558 }
559
560 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
561 {
562   bool idleAdded(false);
563
564   // Only add an idle if the Adaptor is actually running
565   if( RUNNING == mState || READY == mState || forceAdd )
566   {
567     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
568   }
569
570   return idleAdded;
571 }
572
573 void Adaptor::RemoveIdle( CallbackBase* callback )
574 {
575   mCallbackManager->RemoveIdleCallback( callback );
576 }
577
578 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
579 {
580   mThreadController->SetPreRenderCallback( callback );
581 }
582
583 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
584 {
585   Window& windowImpl = Dali::GetImplementation( *childWindow );
586   windowImpl.SetAdaptor( Get() );
587
588   // This is any Window that is not the main (default) one
589   WindowPane additionalWindow;
590   additionalWindow.instance = childWindow;
591   additionalWindow.window_name = childWindowName;
592   additionalWindow.class_name = childWindowClassName;
593   additionalWindow.window_mode = childWindowMode;
594   additionalWindow.surface = windowImpl.GetSurface();
595   additionalWindow.id = windowImpl.GetId();
596
597   // Add the new Window to the Frame - the order is not important
598   mWindowFrame.push_back( additionalWindow );
599
600   return true;
601 }
602
603 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
604 {
605   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
606   {
607     if( iter->instance == childWindow )
608     {
609       mWindowFrame.erase( iter );
610       return true;
611     }
612   }
613
614   return false;
615 }
616
617 bool Adaptor::RemoveWindow( std::string childWindowName )
618 {
619   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
620   {
621     if( iter->window_name == childWindowName )
622     {
623       mWindowFrame.erase( iter );
624       return true;
625     }
626   }
627
628   return false;
629 }
630
631 bool Adaptor::RemoveWindow( Window* childWindow )
632 {
633   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
634   {
635     if( iter->id == childWindow->GetId() )
636     {
637       mWindowFrame.erase( iter );
638       return true;
639     }
640   }
641
642   return false;
643 }
644
645 Dali::Adaptor& Adaptor::Get()
646 {
647   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
648   return gThreadLocalAdaptor->mAdaptor;
649 }
650
651 bool Adaptor::IsAvailable()
652 {
653   return gThreadLocalAdaptor != NULL;
654 }
655
656 void Adaptor::SceneCreated()
657 {
658   mCore->SceneCreated();
659 }
660
661 Dali::Integration::Core& Adaptor::GetCore()
662 {
663   return *mCore;
664 }
665
666 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
667 {
668   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
669 }
670
671 void Adaptor::SetUseHardwareVSync( bool useHardware )
672 {
673   mVSyncMonitor->SetUseHardwareVSync( useHardware );
674 }
675
676 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
677 {
678   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
679   return *mDisplayConnection;
680 }
681
682 GraphicsInterface& Adaptor::GetGraphicsInterface()
683 {
684   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
685   return *mGraphics;
686 }
687
688 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
689 {
690   return *mPlatformAbstraction;
691 }
692
693 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
694 {
695   return *mNotificationTrigger;
696 }
697
698 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
699 {
700   return mTriggerEventFactory;
701 }
702
703 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
704 {
705   return mSocketFactory;
706 }
707
708 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
709 {
710   if( !mWindowFrame.empty())
711   {
712     WindowPane defaultWindow = mWindowFrame.front();
713     return defaultWindow.surface;
714   }
715   else
716   {
717     return nullptr;
718   }
719 }
720
721 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
722 {
723   return mVSyncMonitor;
724 }
725
726 TraceInterface& Adaptor::GetKernelTraceInterface()
727 {
728   return mKernelTracer;
729 }
730
731 TraceInterface& Adaptor::GetSystemTraceInterface()
732 {
733   return mSystemTracer;
734 }
735
736 PerformanceInterface* Adaptor::GetPerformanceInterface()
737 {
738   return mPerformanceInterface;
739 }
740
741 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
742 {
743   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
744   return *mPlatformAbstraction;
745 }
746
747 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
748 {
749   mDragAndDropDetector = detector;
750
751   if ( mEventHandler )
752   {
753     mEventHandler->SetDragAndDropDetector( detector );
754   }
755 }
756
757 void Adaptor::SetRotationObserver( RotationObserver* observer )
758 {
759   if( mEventHandler )
760   {
761     mEventHandler->SetRotationObserver( observer );
762   }
763   else if( mState == READY )
764   {
765     // Set once event handler exists
766     mDeferredRotationObserver = observer;
767   }
768 }
769
770 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
771 {
772   if(mTtsPlayers[mode])
773   {
774     mTtsPlayers[mode].Reset();
775   }
776 }
777
778 void Adaptor::SetMinimumPinchDistance(float distance)
779 {
780   if( mGestureManager )
781   {
782     mGestureManager->SetMinimumPinchDistance(distance);
783   }
784 }
785
786 Any Adaptor::GetNativeWindowHandle()
787 {
788   WindowPane defaultWindow = mWindowFrame.front();
789   return defaultWindow.nativeWindow;
790 }
791
792 Any Adaptor::GetGraphicsDisplay()
793 {
794   Any display;
795
796   if (mGraphics)
797   {
798     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
799
800     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
801     display = eglImpl.GetDisplay();
802   }
803
804   return display;
805 }
806
807 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
808 {
809   mUseRemoteSurface = useRemoteSurface;
810 }
811
812 void Adaptor::AddObserver( LifeCycleObserver& observer )
813 {
814   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
815
816   if ( match == mObservers.end() )
817   {
818     mObservers.push_back( &observer );
819   }
820 }
821
822 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
823 {
824   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
825
826   if ( match != mObservers.end() )
827   {
828     mObservers.erase( match );
829   }
830 }
831
832 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
833 {
834   if( mCore )
835   {
836     mCore->QueueEvent(event);
837   }
838 }
839
840 void Adaptor::ProcessCoreEvents()
841 {
842   if( mCore )
843   {
844     if( mPerformanceInterface )
845     {
846       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
847     }
848
849     mCore->ProcessEvents();
850
851     if( mPerformanceInterface )
852     {
853       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
854     }
855   }
856 }
857
858 void Adaptor::RequestUpdate( bool forceUpdate )
859 {
860   switch( mState )
861   {
862     case RUNNING:
863     {
864       mThreadController->RequestUpdate();
865       break;
866     }
867     case PAUSED:
868     case PAUSED_WHILE_HIDDEN:
869     {
870       // When Dali applications are partially visible behind the lock-screen,
871       // the indicator must be updated (therefore allow updates in the PAUSED state)
872       if( forceUpdate )
873       {
874         mThreadController->RequestUpdateOnce();
875       }
876       break;
877     }
878     default:
879     {
880       // Do nothing
881       break;
882     }
883   }
884 }
885
886 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
887 {
888   // Only request a notification if the Adaptor is actually running
889   // and we haven't installed the idle notification
890   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
891   {
892     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
893   }
894 }
895
896 void Adaptor::OnWindowShown()
897 {
898   if ( PAUSED_WHILE_HIDDEN == mState )
899   {
900     // Adaptor can now be resumed
901     mState = PAUSED;
902
903     Resume();
904
905     // Force a render task
906     RequestUpdateOnce();
907   }
908   else
909   {
910     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Not shown [%d]\n", mState );
911   }
912 }
913
914 void Adaptor::OnWindowHidden()
915 {
916   if ( RUNNING == mState )
917   {
918     Pause();
919
920     // Adaptor cannot be resumed until the window is shown
921     mState = PAUSED_WHILE_HIDDEN;
922   }
923   else
924   {
925     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Not hidden [%d]\n", mState );
926   }
927 }
928
929 // Dali::Internal::Adaptor::Adaptor::OnDamaged
930 void Adaptor::OnDamaged( const DamageArea& area )
931 {
932   // This is needed for the case where Dali window is partially obscured
933   RequestUpdate( false );
934 }
935
936 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
937 {
938   // Let the core know the surface size has changed
939   mCore->SurfaceResized( surface );
940
941   mResizedSignal.Emit( mAdaptor );
942 }
943
944 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
945 {
946   // Flush the event queue to give the update-render thread chance
947   // to start processing messages for new camera setup etc as soon as possible
948   ProcessCoreEvents();
949
950   mThreadController->ResizeSurface();
951 }
952
953 void Adaptor::NotifySceneCreated()
954 {
955   GetCore().SceneCreated();
956
957   // Flush the event queue to give the update-render thread chance
958   // to start processing messages for new camera setup etc as soon as possible
959   ProcessCoreEvents();
960
961   // Start thread controller after the scene has been created
962   mThreadController->Start();
963
964   // Process after surface is created (registering to remote surface provider if required)
965   SurfaceInitialized();
966
967   mState = RUNNING;
968
969   DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated\n" );
970 }
971
972 void Adaptor::NotifyLanguageChanged()
973 {
974   mLanguageChangedSignal.Emit( mAdaptor );
975 }
976
977 void Adaptor::RenderOnce()
978 {
979   RequestUpdateOnce();
980 }
981
982 const LogFactoryInterface& Adaptor::GetLogFactory()
983 {
984   return *mEnvironmentOptions;
985 }
986
987 void Adaptor::RegisterProcessor( Integration::Processor& processor )
988 {
989   GetCore().RegisterProcessor(processor);
990 }
991
992 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
993 {
994   GetCore().UnregisterProcessor(processor);
995 }
996
997 void Adaptor::RequestUpdateOnce()
998 {
999   if( mThreadController )
1000   {
1001     mThreadController->RequestUpdateOnce();
1002   }
1003 }
1004
1005 bool Adaptor::ProcessCoreEventsFromIdle()
1006 {
1007   ProcessCoreEvents();
1008
1009   // the idle handle automatically un-installs itself
1010   mNotificationOnIdleInstalled = false;
1011
1012   return false;
1013 }
1014
1015 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1016 : mResizedSignal(),
1017   mLanguageChangedSignal(),
1018   mAdaptor( adaptor ),
1019   mState( READY ),
1020   mCore( nullptr ),
1021   mThreadController( nullptr ),
1022   mVSyncMonitor( nullptr ),
1023   mGraphics( nullptr ),
1024   mDisplayConnection( nullptr ),
1025   mWindowFrame(),
1026   mPlatformAbstraction( nullptr ),
1027   mEventHandler( nullptr ),
1028   mCallbackManager( nullptr ),
1029   mNotificationOnIdleInstalled( false ),
1030   mNotificationTrigger( nullptr ),
1031   mGestureManager( nullptr ),
1032   mDaliFeedbackPlugin(),
1033   mFeedbackController( nullptr ),
1034   mTtsPlayers(),
1035   mObservers(),
1036   mDragAndDropDetector(),
1037   mDeferredRotationObserver( nullptr ),
1038   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1039   mPerformanceInterface( nullptr ),
1040   mKernelTracer(),
1041   mSystemTracer(),
1042   mTriggerEventFactory(),
1043   mObjectProfiler( nullptr ),
1044   mSocketFactory(),
1045   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1046   mUseRemoteSurface( false )
1047 {
1048   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1049
1050   WindowPane defaultWindow;
1051   defaultWindow.nativeWindow = nativeWindow;
1052   defaultWindow.surface = surface;
1053   defaultWindow.id = 0;
1054
1055   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1056   iter = mWindowFrame.insert( iter, defaultWindow );
1057
1058   gThreadLocalAdaptor = this;
1059 }
1060
1061 void Adaptor::SetRootLayoutDirection( std::string locale )
1062 {
1063   Dali::Stage stage = Dali::Stage::GetCurrent();
1064
1065   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1066                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1067 }
1068
1069 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1070 {
1071   bool idleAdded( false );
1072
1073   // Only add an idle if the Adaptor is actually running
1074   if( RUNNING == mState || READY == mState || forceAdd )
1075   {
1076     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1077   }
1078
1079   return idleAdded;
1080 }
1081
1082 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1083 {
1084   mCallbackManager->RemoveIdleEntererCallback( callback );
1085 }
1086
1087 } // namespace Adaptor
1088
1089 } // namespace Internal
1090
1091 } // namespace Dali