Merge "Blend Equation Advanced Supporting" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2020 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/addons/common/addon-manager-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
23
24 // EXTERNAL INCLUDES
25 #include <errno.h>
26 #include <sys/stat.h>
27 #include <dali/public-api/actors/layer.h>
28 #include <dali/public-api/object/any.h>
29 #include <dali/public-api/object/object-registry.h>
30 #include <dali/public-api/events/wheel-event.h>
31 #include <dali/devel-api/actors/actor-devel.h>
32 #include <dali/devel-api/common/stage.h>
33 #include <dali/integration-api/debug.h>
34 #include <dali/integration-api/core.h>
35 #include <dali/integration-api/context-notifier.h>
36 #include <dali/integration-api/profiling.h>
37 #include <dali/integration-api/input-options.h>
38 #include <dali/integration-api/events/key-event-integ.h>
39 #include <dali/integration-api/events/touch-event-integ.h>
40 #include <dali/integration-api/events/wheel-event-integ.h>
41 #include <dali/integration-api/processor-interface.h>
42 #include <dali/integration-api/addon-manager.h>
43
44 // INTERNAL INCLUDES
45 #include <dali/public-api/dali-adaptor-common.h>
46 #include <dali/internal/system/common/thread-controller.h>
47 #include <dali/internal/system/common/performance-interface-factory.h>
48 #include <dali/internal/adaptor/common/lifecycle-observer.h>
49 #include <dali/internal/adaptor/common/thread-controller-interface.h>
50
51 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
52 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
53
54 #include <dali/devel-api/text-abstraction/font-client.h>
55
56 #include <dali/internal/system/common/callback-manager.h>
57 #include <dali/internal/accessibility/common/tts-player-impl.h>
58 #include <dali/internal/window-system/common/event-handler.h>
59 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
60 #include <dali/internal/graphics/gles/gl-implementation.h>
61 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
62 #include <dali/internal/graphics/common/egl-image-extensions.h>
63 #include <dali/internal/clipboard/common/clipboard-impl.h>
64 #include <dali/internal/system/common/object-profiler.h>
65 #include <dali/internal/window-system/common/display-connection.h>
66 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
67 #include <dali/internal/window-system/common/window-impl.h>
68 #include <dali/internal/window-system/common/window-render-surface.h>
69
70 #include <dali/devel-api/adaptor-framework/accessibility-impl.h>
71 #include <dali/internal/system/common/logging.h>
72
73 #include <dali/internal/system/common/locale-utils.h>
74 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
75 #include <dali/internal/imaging/common/image-loader.h>
76
77 #include <dali/internal/system/common/configuration-manager.h>
78 #include <dali/internal/system/common/environment-variables.h>
79
80 using Dali::TextAbstraction::FontClient;
81
82 extern std::string GetSystemCachePath();
83
84 namespace Dali
85 {
86
87 namespace Internal
88 {
89
90 namespace Adaptor
91 {
92
93 namespace
94 {
95
96 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
97
98 } // unnamed namespace
99
100 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
101 {
102   Dali::Adaptor* adaptor = new Dali::Adaptor;
103   Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode );
104   adaptor->mImpl = impl;
105
106   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
107   auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
108
109   impl->Initialize( graphicsFactory );
110   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
111
112   return adaptor;
113 }
114
115 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
116 {
117   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
118   Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
119   windowImpl.SetAdaptor( *adaptor );
120   return adaptor;
121 }
122
123 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
124 {
125   Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
126   Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions, threadMode ); // Impl adaptor
127   adaptor->mImpl = impl;
128
129   impl->Initialize( graphicsFactory );
130
131   return adaptor;
132 } // Called second
133
134 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions )
135 {
136   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
137   Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL );
138   windowImpl.SetAdaptor( *adaptor );
139   return adaptor;
140 } // Called first
141
142 void Adaptor::Initialize( GraphicsFactory& graphicsFactory )
143 {
144   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
145   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
146   mEnvironmentOptions->SetLogFunction( logFunction );
147   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
148
149   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
150
151   std::string path;
152   GetDataStoragePath( path );
153   mPlatformAbstraction->SetDataStoragePath( path );
154
155   if( mEnvironmentOptions->PerformanceServerRequired() )
156   {
157     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
158   }
159
160   mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
161   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
162
163   mCallbackManager = CallbackManager::New();
164
165   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
166
167   DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
168
169   mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
170   mGraphics->Initialize( mEnvironmentOptions );
171
172   GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
173   auto eglGraphics = static_cast<EglGraphics *>( graphics );
174
175   // This will only be created once
176   eglGraphics->Create();
177
178   GlImplementation& mGLES = eglGraphics->GetGlesInterface();
179   EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
180   EglContextHelperImplementation& eglContextHelperImpl = eglGraphics->GetContextHelperImplementation();
181
182   // Create the AddOnManager
183   mAddOnManager.reset( Dali::Internal::AddOnManagerFactory::CreateAddOnManager() );
184
185   mCore = Integration::Core::New( *this,
186                                   *mPlatformAbstraction,
187                                   mGLES,
188                                   eglSyncImpl,
189                                   eglContextHelperImpl,
190                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
191                                   mGraphics->GetDepthBufferRequired(),
192                                   mGraphics->GetStencilBufferRequired(),
193                                   mGraphics->GetPartialUpdateRequired() );
194
195
196   defaultWindow->SetAdaptor( Get() );
197
198   Dali::Integration::SceneHolder defaultSceneHolder( defaultWindow );
199
200   mWindowCreatedSignal.Emit( defaultSceneHolder );
201
202   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
203   if( 0u < timeInterval )
204   {
205     mObjectProfiler = new ObjectProfiler( mCore->GetObjectRegistry(), timeInterval );
206   }
207
208   mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
209
210   mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
211
212   mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
213
214   // Should be called after Core creation
215   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
216   {
217     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
218   }
219   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
220   {
221     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
222   }
223   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
224   {
225     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
226   }
227   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
228   {
229     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
230   }
231   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
232   {
233     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
234   }
235   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
236   {
237     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
238   }
239   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
240   {
241     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
242   }
243   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
244   {
245     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
246   }
247   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
248   {
249     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
250   }
251   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
252   {
253     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
254   }
255   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
256   {
257     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
258   }
259   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
260   {
261     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
262   }
263   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
264   {
265     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
266   }
267   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
268   {
269     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
270   }
271   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
272   {
273     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
274   }
275   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
276   {
277     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
278   }
279   if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
280   {
281     Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
282   }
283   if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
284   {
285     Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
286   }
287   if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
288   {
289     Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
290   }
291   if( mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0 )
292   {
293     Integration::SetPinchGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumPinchTouchEvents() );
294   }
295   if( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0 )
296   {
297     Integration::SetPinchGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() );
298   }
299   if( mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0 )
300   {
301     Integration::SetRotationGestureMinimumTouchEvents( mEnvironmentOptions->GetMinimumRotationTouchEvents() );
302   }
303   if( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0 )
304   {
305     Integration::SetRotationGestureMinimumTouchEventsAfterStart( mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() );
306   }
307   if( mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0 )
308   {
309     Integration::SetLongPressMinimumHoldingTime( mEnvironmentOptions->GetLongPressMinimumHoldingTime() );
310   }
311
312   std::string systemCachePath = GetSystemCachePath();
313   if( ! systemCachePath.empty() )
314   {
315     const int dir_err = mkdir( systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
316     if ( 0 != dir_err && errno != EEXIST )
317     {
318       DALI_LOG_ERROR( "Error creating system cache directory: %s!\n", systemCachePath.c_str() );
319       exit( 1 );
320     }
321   }
322
323   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>( systemCachePath, eglGraphics, mThreadController );
324
325   auto appName = GetApplicationPackageName();
326   auto bridge = Accessibility::Bridge::GetCurrentBridge();
327   bridge->SetApplicationName( appName );
328   bridge->Initialize();
329   Dali::Stage::GetCurrent().KeyEventSignal().Connect( &accessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent );
330 }
331
332 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent( const Dali::KeyEvent& event )
333 {
334   Accessibility::KeyEventType type;
335   if( event.GetState() == Dali::KeyEvent::DOWN )
336   {
337     type = Accessibility::KeyEventType::KEY_PRESSED;
338   }
339   else if( event.GetState() == Dali::KeyEvent::UP )
340   {
341     type = Accessibility::KeyEventType::KEY_RELEASED;
342   }
343   else
344   {
345     return;
346   }
347   Dali::Accessibility::Bridge::GetCurrentBridge()->Emit( type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty() );
348 }
349
350 Adaptor::~Adaptor()
351 {
352   Accessibility::Bridge::GetCurrentBridge()->Terminate();
353
354   // Ensure stop status
355   Stop();
356
357   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
358   gThreadLocalAdaptor = NULL;
359
360   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
361   {
362     (*iter)->OnDestroy();
363   }
364
365   // Clear out all the handles to Windows
366   mWindows.clear();
367
368   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
369   delete mObjectProfiler;
370
371   delete mCore;
372
373   delete mDisplayConnection;
374   delete mPlatformAbstraction;
375   delete mCallbackManager;
376   delete mPerformanceInterface;
377
378   mGraphics->Destroy();
379
380   // uninstall it on this thread (main actor thread)
381   Dali::Integration::Log::UninstallLogFunction();
382
383   // Delete environment options if we own it
384   if( mEnvironmentOptionsOwned )
385   {
386     delete mEnvironmentOptions;
387   }
388 }
389
390 void Adaptor::Start()
391 {
392   // It doesn't support restart after stop at this moment to support restarting, need more testing
393   if( READY != mState )
394   {
395     return;
396   }
397
398   mCore->Initialize();
399
400   SetupSystemInformation();
401
402   // Start the callback manager
403   mCallbackManager->Start();
404
405   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
406
407   unsigned int dpiHor, dpiVer;
408   dpiHor = dpiVer = 0;
409
410   defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
411
412   // set the DPI value for font rendering
413   FontClient fontClient = FontClient::Get();
414   fontClient.SetDpi( dpiHor, dpiVer );
415
416   // Initialize the thread controller
417   mThreadController->Initialize();
418
419   // Set max texture size
420   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
421   {
422     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
423   }
424   else
425   {
426     unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
427     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( maxTextureSize );
428   }
429
430   // Set cached isAdvancedBlendEquationSupported
431   GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
432   auto eglGraphics = static_cast<EglGraphics *>( graphics );
433   GlImplementation& mGLES = eglGraphics->GetGlesInterface();
434   mGLES.SetIsAdvancedBlendEquationSupported( mConfigurationManager->IsAdvancedBlendEquationSupported() );
435   mGLES.SetShadingLanguageVersion( mConfigurationManager->GetShadingLanguageVersion() );
436
437   ProcessCoreEvents(); // Ensure any startup messages are processed.
438
439   // Initialize the image loader plugin
440   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
441
442   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
443   {
444     (*iter)->OnStart();
445   }
446
447   if (mAddOnManager)
448   {
449     mAddOnManager->Start();
450   }
451 }
452
453 // Dali::Internal::Adaptor::Adaptor::Pause
454 void Adaptor::Pause()
455 {
456   // Only pause the adaptor if we're actually running.
457   if( RUNNING == mState )
458   {
459     // Inform observers that we are about to be paused.
460     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
461     {
462       (*iter)->OnPause();
463     }
464
465     // Extensions
466     if (mAddOnManager)
467     {
468       mAddOnManager->Pause();
469     }
470
471     // Pause all windows event handlers when adaptor paused
472     for( auto window : mWindows )
473     {
474       window->Pause();
475     }
476
477     mThreadController->Pause();
478     mState = PAUSED;
479
480     // Ensure any messages queued during pause callbacks are processed by doing another update.
481     RequestUpdateOnce();
482
483     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
484   }
485   else
486   {
487     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
488   }
489 }
490
491 // Dali::Internal::Adaptor::Adaptor::Resume
492 void Adaptor::Resume()
493 {
494   // Only resume the adaptor if we are in the suspended state.
495   if( PAUSED == mState )
496   {
497     mState = RUNNING;
498
499     // Reset the event handlers when adaptor resumed
500     for( auto window : mWindows )
501     {
502       window->Resume();
503     }
504
505     // Resume AddOnManager
506     if (mAddOnManager)
507     {
508       mAddOnManager->Resume();
509     }
510
511     // Inform observers that we have resumed.
512     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
513     {
514       (*iter)->OnResume();
515     }
516
517     // Trigger processing of events queued up while paused
518     mCore->ProcessEvents();
519
520     // Do at end to ensure our first update/render after resumption includes the processed messages as well
521     mThreadController->Resume();
522
523     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
524   }
525   else
526   {
527     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
528   }
529 }
530
531 void Adaptor::Stop()
532 {
533   if( RUNNING == mState ||
534       PAUSED  == mState ||
535       PAUSED_WHILE_HIDDEN == mState )
536   {
537     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
538     {
539       (*iter)->OnStop();
540     }
541
542     if (mAddOnManager)
543     {
544       mAddOnManager->Stop();
545     }
546
547     mThreadController->Stop();
548
549     // Delete the TTS player
550     for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
551     {
552       if( mTtsPlayers[i] )
553       {
554         mTtsPlayers[i].Reset();
555       }
556     }
557
558     // Destroy the image loader plugin
559     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
560
561     delete mNotificationTrigger;
562     mNotificationTrigger = NULL;
563
564     mCallbackManager->Stop();
565
566     mState = STOPPED;
567
568     DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
569   }
570 }
571
572 void Adaptor::ContextLost()
573 {
574   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
575 }
576
577 void Adaptor::ContextRegained()
578 {
579   // Inform core, so that texture resources can be reloaded
580   mCore->RecoverFromContextLoss();
581
582   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
583 }
584
585 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
586 {
587   Integration::Point convertedPoint( point );
588   mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
589 }
590
591 void Adaptor::FeedWheelEvent( Dali::WheelEvent& wheelEvent )
592 {
593   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >( wheelEvent.GetType() ), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime() );
594   mWindows.front()->FeedWheelEvent( event );
595 }
596
597 void Adaptor::FeedKeyEvent( Dali::KeyEvent& keyEvent )
598 {
599   Integration::KeyEvent convertedEvent( keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast< Integration::KeyEvent::State >( keyEvent.GetState() ), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass() );
600   mWindows.front()->FeedKeyEvent( convertedEvent );
601 }
602
603 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
604 {
605   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
606   for( auto windowPtr : mWindows )
607   {
608     if( windowPtr == windowImpl ) // the window is not deleted
609     {
610       mResizedSignal.Emit( mAdaptor );
611
612       windowImpl->SetSurface( &newSurface );
613
614       // Flush the event queue to give the update-render thread chance
615       // to start processing messages for new camera setup etc as soon as possible
616       ProcessCoreEvents();
617
618       // This method blocks until the render thread has completed the replace.
619       mThreadController->ReplaceSurface( &newSurface );
620       break;
621     }
622   }
623 }
624
625 void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface )
626 {
627   // Flush the event queue to give the update-render thread chance
628   // to start processing messages for new camera setup etc as soon as possible
629   ProcessCoreEvents();
630
631   // This method blocks until the render thread has finished rendering the current surface.
632   mThreadController->DeleteSurface( &surface );
633 }
634
635 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
636 {
637   return *mWindows.front()->GetSurface();
638 }
639
640 void Adaptor::ReleaseSurfaceLock()
641 {
642   mWindows.front()->GetSurface()->ReleaseLock();
643 }
644
645 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
646 {
647   if( !mTtsPlayers[mode] )
648   {
649     // Create the TTS player when it needed, because it can reduce launching time.
650     mTtsPlayers[mode] = TtsPlayer::New(mode);
651   }
652
653   return mTtsPlayers[mode];
654 }
655
656 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
657 {
658   bool idleAdded(false);
659
660   // Only add an idle if the Adaptor is actually running
661   if( RUNNING == mState || READY == mState || forceAdd )
662   {
663     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
664   }
665
666   return idleAdded;
667 }
668
669 void Adaptor::RemoveIdle( CallbackBase* callback )
670 {
671   mCallbackManager->RemoveIdleCallback( callback );
672 }
673
674 void Adaptor::ProcessIdle()
675 {
676   bool idleProcessed = mCallbackManager->ProcessIdle();
677   mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
678 }
679
680 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
681 {
682   mThreadController->SetPreRenderCallback( callback );
683 }
684
685 bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow )
686 {
687   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( childWindow );
688   windowImpl.SetAdaptor( Get() );
689
690   // ChildWindow is set to the layout direction of the default window.
691   windowImpl.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
692
693   // Add the new Window to the container - the order is not important
694   mWindows.push_back( &windowImpl );
695
696   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
697
698   mThreadController->AddSurface( surface );
699
700   mWindowCreatedSignal.Emit( childWindow );
701
702   return true;
703 }
704
705 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
706 {
707   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
708   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
709   {
710     if( *iter == &windowImpl )
711     {
712       mWindows.erase( iter );
713       return true;
714     }
715   }
716
717   return false;
718 }
719
720 bool Adaptor::RemoveWindow( std::string childWindowName )
721 {
722   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
723   {
724     if( ( *iter )->GetName() == childWindowName )
725     {
726       mWindows.erase( iter );
727       return true;
728     }
729   }
730
731   return false;
732 }
733
734 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
735 {
736   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
737   {
738     if( ( *iter )->GetId() == childWindow->GetId() )
739     {
740       mWindows.erase( iter );
741       return true;
742     }
743   }
744
745   return false;
746 }
747
748 Dali::Adaptor& Adaptor::Get()
749 {
750   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
751   return gThreadLocalAdaptor->mAdaptor;
752 }
753
754 bool Adaptor::IsAvailable()
755 {
756   return gThreadLocalAdaptor != NULL;
757 }
758
759 void Adaptor::SceneCreated()
760 {
761   mCore->SceneCreated();
762 }
763
764 Dali::Integration::Core& Adaptor::GetCore()
765 {
766   return *mCore;
767 }
768
769 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
770 {
771   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
772 }
773
774 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
775 {
776   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
777   return *mDisplayConnection;
778 }
779
780 GraphicsInterface& Adaptor::GetGraphicsInterface()
781 {
782   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
783   return *( mGraphics.get() );
784 }
785
786 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
787 {
788   return *mPlatformAbstraction;
789 }
790
791 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
792 {
793   return *mNotificationTrigger;
794 }
795
796 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
797 {
798   return mSocketFactory;
799 }
800
801 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
802 {
803   if( !mWindows.empty() )
804   {
805     return mWindows.front()->GetSurface();
806   }
807
808   return nullptr;
809 }
810
811 TraceInterface& Adaptor::GetKernelTraceInterface()
812 {
813   return mKernelTracer;
814 }
815
816 TraceInterface& Adaptor::GetSystemTraceInterface()
817 {
818   return mSystemTracer;
819 }
820
821 PerformanceInterface* Adaptor::GetPerformanceInterface()
822 {
823   return mPerformanceInterface;
824 }
825
826 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
827 {
828   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
829   return *mPlatformAbstraction;
830 }
831
832 void Adaptor::GetWindowContainerInterface( WindowContainer& windows )
833 {
834   windows = mWindows;
835 }
836
837 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
838 {
839   if( mTtsPlayers[mode] )
840   {
841     mTtsPlayers[mode].Reset();
842   }
843 }
844
845 Any Adaptor::GetNativeWindowHandle()
846 {
847   return mWindows.front()->GetNativeHandle();
848 }
849
850 Any Adaptor::GetNativeWindowHandle( Dali::Actor actor )
851 {
852   Any nativeWindowHandle;
853
854   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
855
856   for( auto sceneHolder : mWindows )
857   {
858     if ( scene == sceneHolder->GetScene() )
859     {
860       nativeWindowHandle = sceneHolder->GetNativeHandle();
861       break;
862     }
863   }
864
865   return nativeWindowHandle;
866 }
867
868 Any Adaptor::GetGraphicsDisplay()
869 {
870   Any display;
871
872   if (mGraphics)
873   {
874     GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
875     auto eglGraphics = static_cast<EglGraphics *>( graphics );
876
877     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
878     display = eglImpl.GetDisplay();
879   }
880
881   return display;
882 }
883
884 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
885 {
886   mUseRemoteSurface = useRemoteSurface;
887 }
888
889 void Adaptor::AddObserver( LifeCycleObserver& observer )
890 {
891   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
892
893   if ( match == mObservers.end() )
894   {
895     mObservers.push_back( &observer );
896   }
897 }
898
899 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
900 {
901   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
902
903   if ( match != mObservers.end() )
904   {
905     mObservers.erase( match );
906   }
907 }
908
909 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
910 {
911   if( mCore )
912   {
913     mCore->QueueEvent(event);
914   }
915 }
916
917 void Adaptor::ProcessCoreEvents()
918 {
919   if( mCore )
920   {
921     if( mPerformanceInterface )
922     {
923       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
924     }
925
926     mCore->ProcessEvents();
927
928     if( mPerformanceInterface )
929     {
930       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
931     }
932   }
933 }
934
935 void Adaptor::RequestUpdate( bool forceUpdate )
936 {
937   switch( mState )
938   {
939     case RUNNING:
940     {
941       mThreadController->RequestUpdate();
942       break;
943     }
944     case PAUSED:
945     case PAUSED_WHILE_HIDDEN:
946     {
947       if( forceUpdate )
948       {
949         // Update (and resource upload) without rendering
950         mThreadController->RequestUpdateOnce( UpdateMode::SKIP_RENDER );
951       }
952       break;
953     }
954     default:
955     {
956       // Do nothing
957       break;
958     }
959   }
960 }
961
962 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
963 {
964   // Only request a notification if the Adaptor is actually running
965   // and we haven't installed the idle notification
966   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
967   {
968     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
969   }
970 }
971
972 void Adaptor::OnWindowShown()
973 {
974   Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
975
976   if( PAUSED_WHILE_HIDDEN == mState )
977   {
978     // Adaptor can now be resumed
979     mState = PAUSED;
980
981     Resume();
982
983     // Force a render task
984     RequestUpdateOnce();
985   }
986   else if( RUNNING == mState )
987   {
988     // Force a render task
989     RequestUpdateOnce();
990
991     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Update requested.\n" );
992   }
993   else if( PAUSED_WHILE_INITIALIZING == mState )
994   {
995     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
996     mState = READY;
997   }
998   else
999   {
1000     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
1001   }
1002 }
1003
1004 void Adaptor::OnWindowHidden()
1005 {
1006   Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
1007
1008   if( RUNNING == mState || READY == mState )
1009   {
1010     bool allWindowsHidden = true;
1011
1012     for( auto window : mWindows )
1013     {
1014       if ( window->IsVisible() )
1015       {
1016         allWindowsHidden = false;
1017         break;
1018       }
1019     }
1020
1021     // Only pause the adaptor when all the windows are hidden
1022     if( allWindowsHidden )
1023     {
1024       if( mState == RUNNING )
1025       {
1026         Pause();
1027
1028         // Adaptor cannot be resumed until any window is shown
1029         mState = PAUSED_WHILE_HIDDEN;
1030       }
1031       else  // mState is READY
1032       {
1033         // Pause the adaptor after the state gets RUNNING
1034         mState = PAUSED_WHILE_INITIALIZING;
1035       }
1036     }
1037     else
1038     {
1039       DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
1040     }
1041   }
1042   else
1043   {
1044     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
1045   }
1046 }
1047
1048 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1049 void Adaptor::OnDamaged( const DamageArea& area )
1050 {
1051   // This is needed for the case where Dali window is partially obscured
1052   RequestUpdate( false );
1053 }
1054
1055 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1056 {
1057   mResizedSignal.Emit( mAdaptor );
1058 }
1059
1060 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
1061 {
1062   // Nofify surface resizing before flushing event queue
1063   mThreadController->ResizeSurface();
1064
1065   // Flush the event queue to give the update-render thread chance
1066   // to start processing messages for new camera setup etc as soon as possible
1067   ProcessCoreEvents();
1068 }
1069
1070 void Adaptor::NotifySceneCreated()
1071 {
1072   GetCore().SceneCreated();
1073
1074   // Flush the event queue to give the update-render thread chance
1075   // to start processing messages for new camera setup etc as soon as possible
1076   ProcessCoreEvents();
1077
1078   // Start thread controller after the scene has been created
1079   mThreadController->Start();
1080
1081   // Process after surface is created (registering to remote surface provider if required)
1082   SurfaceInitialized();
1083
1084   if( mState != PAUSED_WHILE_INITIALIZING )
1085   {
1086     mState = RUNNING;
1087
1088     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
1089   }
1090   else
1091   {
1092     mState = RUNNING;
1093
1094     Pause();
1095
1096     mState = PAUSED_WHILE_HIDDEN;
1097
1098     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
1099   }
1100 }
1101
1102 void Adaptor::NotifyLanguageChanged()
1103 {
1104   mLanguageChangedSignal.Emit( mAdaptor );
1105 }
1106
1107 void Adaptor::RenderOnce()
1108 {
1109   if( mThreadController )
1110   {
1111     UpdateMode updateMode;
1112     if( mThreadMode == ThreadMode::NORMAL )
1113     {
1114       updateMode = UpdateMode::NORMAL;
1115     }
1116     else
1117     {
1118       updateMode = UpdateMode::FORCE_RENDER;
1119
1120       ProcessCoreEvents();
1121     }
1122     mThreadController->RequestUpdateOnce( updateMode );
1123   }
1124 }
1125
1126 const LogFactoryInterface& Adaptor::GetLogFactory()
1127 {
1128   return *mEnvironmentOptions;
1129 }
1130
1131 void Adaptor::RegisterProcessor( Integration::Processor& processor )
1132 {
1133   GetCore().RegisterProcessor(processor);
1134 }
1135
1136 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
1137 {
1138   GetCore().UnregisterProcessor(processor);
1139 }
1140
1141 bool Adaptor::IsMultipleWindowSupported() const
1142 {
1143   return mConfigurationManager->IsMultipleWindowSupported();
1144 }
1145
1146 void Adaptor::RequestUpdateOnce()
1147 {
1148   if( mThreadController )
1149   {
1150     mThreadController->RequestUpdateOnce( UpdateMode::NORMAL );
1151   }
1152 }
1153
1154 bool Adaptor::ProcessCoreEventsFromIdle()
1155 {
1156   ProcessCoreEvents();
1157
1158   // the idle handle automatically un-installs itself
1159   mNotificationOnIdleInstalled = false;
1160
1161   return false;
1162 }
1163
1164 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
1165 {
1166   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
1167
1168   for( auto window : mWindows )
1169   {
1170     if ( scene == window->GetScene() )
1171     {
1172       return window;
1173     }
1174   }
1175
1176   return nullptr;
1177 }
1178
1179 Dali::WindowContainer Adaptor::GetWindows() const
1180 {
1181   Dali::WindowContainer windows;
1182
1183   for ( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1184   {
1185     // Downcast to Dali::Window
1186     Dali::Window window( dynamic_cast<Dali::Internal::Adaptor::Window*>( *iter ) );
1187     if ( window )
1188     {
1189       windows.push_back( window );
1190     }
1191   }
1192
1193   return windows;
1194 }
1195
1196 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1197 {
1198   Dali::SceneHolderList sceneHolderList;
1199
1200   for( auto iter = mWindows.begin(); iter != mWindows.end(); ++iter )
1201   {
1202     sceneHolderList.push_back( Dali::Integration::SceneHolder( *iter ) );
1203   }
1204
1205   return sceneHolderList;
1206 }
1207
1208 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1209 {
1210   Dali::ObjectRegistry registry;
1211   if( mCore )
1212   {
1213     registry = mCore->GetObjectRegistry();
1214   }
1215   return registry;
1216 }
1217
1218 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode )
1219 : mResizedSignal(),
1220   mLanguageChangedSignal(),
1221   mWindowCreatedSignal(),
1222   mAdaptor( adaptor ),
1223   mState( READY ),
1224   mCore( nullptr ),
1225   mThreadController( nullptr ),
1226   mGraphics( nullptr ),
1227   mDisplayConnection( nullptr ),
1228   mWindows(),
1229   mConfigurationManager( nullptr ),
1230   mPlatformAbstraction( nullptr ),
1231   mCallbackManager( nullptr ),
1232   mNotificationOnIdleInstalled( false ),
1233   mNotificationTrigger( nullptr ),
1234   mDaliFeedbackPlugin(),
1235   mFeedbackController( nullptr ),
1236   mTtsPlayers(),
1237   mObservers(),
1238   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1239   mPerformanceInterface( nullptr ),
1240   mKernelTracer(),
1241   mSystemTracer(),
1242   mObjectProfiler( nullptr ),
1243   mSocketFactory(),
1244   mThreadMode( threadMode ),
1245   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1246   mUseRemoteSurface( false ),
1247   mRootLayoutDirection( Dali::LayoutDirection::LEFT_TO_RIGHT )
1248 {
1249   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1250   mWindows.insert( mWindows.begin(), &Dali::GetImplementation( window ) );
1251
1252   gThreadLocalAdaptor = this;
1253 }
1254
1255 void Adaptor::SetRootLayoutDirection( std::string locale )
1256 {
1257   mRootLayoutDirection = static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) );
1258   for ( auto& window : mWindows )
1259   {
1260     Dali::Actor root = window->GetRootLayer();
1261     root.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection );
1262   }
1263 }
1264
1265 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1266 {
1267   bool idleAdded( false );
1268
1269   // Only add an idle if the Adaptor is actually running
1270   if( RUNNING == mState || READY == mState || forceAdd )
1271   {
1272     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1273   }
1274
1275   if( !idleAdded )
1276   {
1277     // Delete callback
1278     delete callback;
1279   }
1280
1281   return idleAdded;
1282 }
1283
1284 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1285 {
1286   mCallbackManager->RemoveIdleEntererCallback( callback );
1287 }
1288
1289 } // namespace Adaptor
1290
1291 } // namespace Internal
1292
1293 } // namespace Dali