Add logs - Window, Adaptor and CombinedUpdateRenderController
[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   // Start thread controller after the scene has been created
958   mThreadController->Start();
959
960   // Process after surface is created (registering to remote surface provider if required)
961   SurfaceInitialized();
962
963   mState = RUNNING;
964
965   DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated\n" );
966 }
967
968 void Adaptor::NotifyLanguageChanged()
969 {
970   mLanguageChangedSignal.Emit( mAdaptor );
971 }
972
973 void Adaptor::RenderOnce()
974 {
975   RequestUpdateOnce();
976 }
977
978 const LogFactoryInterface& Adaptor::GetLogFactory()
979 {
980   return *mEnvironmentOptions;
981 }
982
983 void Adaptor::RegisterProcessor( Integration::Processor& processor )
984 {
985   GetCore().RegisterProcessor(processor);
986 }
987
988 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
989 {
990   GetCore().UnregisterProcessor(processor);
991 }
992
993 void Adaptor::RequestUpdateOnce()
994 {
995   if( mThreadController )
996   {
997     mThreadController->RequestUpdateOnce();
998   }
999 }
1000
1001 bool Adaptor::ProcessCoreEventsFromIdle()
1002 {
1003   ProcessCoreEvents();
1004
1005   // the idle handle automatically un-installs itself
1006   mNotificationOnIdleInstalled = false;
1007
1008   return false;
1009 }
1010
1011 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1012 : mResizedSignal(),
1013   mLanguageChangedSignal(),
1014   mAdaptor( adaptor ),
1015   mState( READY ),
1016   mCore( nullptr ),
1017   mThreadController( nullptr ),
1018   mVSyncMonitor( nullptr ),
1019   mGraphics( nullptr ),
1020   mDisplayConnection( nullptr ),
1021   mWindowFrame(),
1022   mPlatformAbstraction( nullptr ),
1023   mEventHandler( nullptr ),
1024   mCallbackManager( nullptr ),
1025   mNotificationOnIdleInstalled( false ),
1026   mNotificationTrigger( nullptr ),
1027   mGestureManager( nullptr ),
1028   mDaliFeedbackPlugin(),
1029   mFeedbackController( nullptr ),
1030   mTtsPlayers(),
1031   mObservers(),
1032   mDragAndDropDetector(),
1033   mDeferredRotationObserver( nullptr ),
1034   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1035   mPerformanceInterface( nullptr ),
1036   mKernelTracer(),
1037   mSystemTracer(),
1038   mTriggerEventFactory(),
1039   mObjectProfiler( nullptr ),
1040   mSocketFactory(),
1041   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1042   mUseRemoteSurface( false )
1043 {
1044   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1045
1046   WindowPane defaultWindow;
1047   defaultWindow.nativeWindow = nativeWindow;
1048   defaultWindow.surface = surface;
1049   defaultWindow.id = 0;
1050
1051   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1052   iter = mWindowFrame.insert( iter, defaultWindow );
1053
1054   gThreadLocalAdaptor = this;
1055 }
1056
1057 void Adaptor::SetRootLayoutDirection( std::string locale )
1058 {
1059   Dali::Stage stage = Dali::Stage::GetCurrent();
1060
1061   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1062                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1063 }
1064
1065 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1066 {
1067   bool idleAdded( false );
1068
1069   // Only add an idle if the Adaptor is actually running
1070   if( RUNNING == mState || READY == mState || forceAdd )
1071   {
1072     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1073   }
1074
1075   return idleAdded;
1076 }
1077
1078 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1079 {
1080   mCallbackManager->RemoveIdleEntererCallback( callback );
1081 }
1082
1083 } // namespace Adaptor
1084
1085 } // namespace Internal
1086
1087 } // namespace Dali