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