2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/addons/common/addon-manager-impl.h>
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/devel-api/common/stage.h>
27 #include <dali/integration-api/addon-manager.h>
28 #include <dali/integration-api/context-notifier.h>
29 #include <dali/integration-api/core.h>
30 #include <dali/integration-api/debug.h>
31 #include <dali/integration-api/events/key-event-integ.h>
32 #include <dali/integration-api/events/touch-event-integ.h>
33 #include <dali/integration-api/events/wheel-event-integ.h>
34 #include <dali/integration-api/input-options.h>
35 #include <dali/integration-api/processor-interface.h>
36 #include <dali/integration-api/profiling.h>
37 #include <dali/public-api/actors/layer.h>
38 #include <dali/public-api/events/wheel-event.h>
39 #include <dali/public-api/object/any.h>
40 #include <dali/public-api/object/object-registry.h>
45 #include <dali/internal/adaptor/common/lifecycle-observer.h>
46 #include <dali/internal/adaptor/common/thread-controller-interface.h>
47 #include <dali/internal/system/common/performance-interface-factory.h>
48 #include <dali/internal/system/common/thread-controller.h>
49 #include <dali/public-api/dali-adaptor-common.h>
51 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
52 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
54 #include <dali/devel-api/text-abstraction/font-client.h>
56 #include <dali/internal/accessibility/common/tts-player-impl.h>
57 #include <dali/internal/clipboard/common/clipboard-impl.h>
58 #include <dali/internal/graphics/common/egl-image-extensions.h>
59 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
60 #include <dali/internal/graphics/gles/gl-implementation.h>
61 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
62 #include <dali/internal/system/common/callback-manager.h>
63 #include <dali/internal/system/common/object-profiler.h>
64 #include <dali/internal/window-system/common/display-connection.h>
65 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
66 #include <dali/internal/window-system/common/event-handler.h>
67 #include <dali/internal/window-system/common/window-impl.h>
68 #include <dali/internal/window-system/common/window-render-surface.h>
70 #include <dali/devel-api/adaptor-framework/accessibility-impl.h>
71 #include <dali/internal/system/common/logging.h>
73 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
74 #include <dali/internal/imaging/common/image-loader.h>
75 #include <dali/internal/system/common/locale-utils.h>
77 #include <dali/internal/system/common/configuration-manager.h>
78 #include <dali/internal/system/common/environment-variables.h>
80 using Dali::TextAbstraction::FontClient;
82 extern std::string GetSystemCachePath();
92 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
94 } // unnamed namespace
96 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
98 Dali::Adaptor* adaptor = new Dali::Adaptor;
99 Adaptor* impl = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode);
100 adaptor->mImpl = impl;
102 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder(*(impl->mEnvironmentOptions));
103 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
105 impl->Initialize(graphicsFactory);
106 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
111 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
113 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
114 Dali::Adaptor* adaptor = New(window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
115 windowImpl.SetAdaptor(*adaptor);
119 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
121 Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
122 Adaptor* impl = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode); // Impl adaptor
123 adaptor->mImpl = impl;
125 impl->Initialize(graphicsFactory);
130 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
132 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
133 Dali::Adaptor* adaptor = New(graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
134 windowImpl.SetAdaptor(*adaptor);
138 void Adaptor::Initialize(GraphicsFactory& graphicsFactory)
140 // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
141 Dali::Integration::Log::LogFunction logFunction(Dali::TizenPlatform::LogMessage);
142 mEnvironmentOptions->SetLogFunction(logFunction);
143 mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
145 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
148 GetDataStoragePath(path);
149 mPlatformAbstraction->SetDataStoragePath(path);
151 if(mEnvironmentOptions->PerformanceServerRequired())
153 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface(*this, *mEnvironmentOptions);
156 mEnvironmentOptions->CreateTraceManager(mPerformanceInterface);
157 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
159 mCallbackManager = CallbackManager::New();
161 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
163 DALI_ASSERT_DEBUG(defaultWindow->GetSurface() && "Surface not initialized");
165 mGraphics = std::unique_ptr<GraphicsInterface>(&graphicsFactory.Create());
167 // Create the AddOnManager
168 mAddOnManager.reset(Dali::Internal::AddOnManagerFactory::CreateAddOnManager());
170 mCore = Integration::Core::New(*this,
171 *mPlatformAbstraction,
172 mGraphics->GetController(),
173 (0u != mEnvironmentOptions->GetRenderToFboInterval()) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
174 mGraphics->GetDepthBufferRequired(),
175 mGraphics->GetStencilBufferRequired(),
176 mGraphics->GetPartialUpdateRequired());
178 defaultWindow->SetAdaptor(Get());
180 Dali::Integration::SceneHolder defaultSceneHolder(defaultWindow);
182 mWindowCreatedSignal.Emit(defaultSceneHolder);
184 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
185 if(0u < timeInterval)
187 mObjectProfiler = new ObjectProfiler(mCore->GetObjectRegistry(), timeInterval);
190 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &Adaptor::ProcessCoreEvents), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
192 mDisplayConnection = Dali::DisplayConnection::New(*mGraphics, defaultWindow->GetSurface()->GetSurfaceType());
194 mThreadController = new ThreadController(*this, *mEnvironmentOptions, mThreadMode);
196 // Should be called after Core creation
197 if(mEnvironmentOptions->GetPanGestureLoggingLevel())
199 Integration::EnableProfiling(Dali::Integration::PROFILING_TYPE_PAN_GESTURE);
201 if(mEnvironmentOptions->GetPanGesturePredictionMode() >= 0)
203 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
205 if(mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0)
207 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
209 if(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0)
211 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
213 if(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0)
215 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
217 if(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0)
219 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
221 if(mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0)
223 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
225 if(mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f)
227 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
229 if(mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0)
231 Integration::SetPanGestureUseActualTimes(mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false);
233 if(mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0)
235 Integration::SetPanGestureInterpolationTimeRange(mEnvironmentOptions->GetPanGestureInterpolationTimeRange());
237 if(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0)
239 Integration::SetPanGestureScalarOnlyPredictionEnabled(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false);
241 if(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0)
243 Integration::SetPanGestureTwoPointPredictionEnabled(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false);
245 if(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0)
247 Integration::SetPanGestureTwoPointInterpolatePastTime(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime());
249 if(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f)
251 Integration::SetPanGestureTwoPointVelocityBias(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias());
253 if(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f)
255 Integration::SetPanGestureTwoPointAccelerationBias(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias());
257 if(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0)
259 Integration::SetPanGestureMultitapSmoothingRange(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange());
261 if(mEnvironmentOptions->GetMinimumPanDistance() >= 0)
263 Integration::SetPanGestureMinimumDistance(mEnvironmentOptions->GetMinimumPanDistance());
265 if(mEnvironmentOptions->GetMinimumPanEvents() >= 0)
267 Integration::SetPanGestureMinimumPanEvents(mEnvironmentOptions->GetMinimumPanEvents());
269 if(mEnvironmentOptions->GetMinimumPinchDistance() >= 0)
271 Integration::SetPinchGestureMinimumDistance(mEnvironmentOptions->GetMinimumPinchDistance());
273 if(mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0)
275 Integration::SetPinchGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumPinchTouchEvents());
277 if(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0)
279 Integration::SetPinchGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart());
281 if(mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0)
283 Integration::SetRotationGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumRotationTouchEvents());
285 if(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0)
287 Integration::SetRotationGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart());
289 if(mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0)
291 Integration::SetLongPressMinimumHoldingTime(mEnvironmentOptions->GetLongPressMinimumHoldingTime());
293 if(mEnvironmentOptions->GetTapMaximumAllowedTime() > 0)
295 Integration::SetTapMaximumAllowedTime(mEnvironmentOptions->GetTapMaximumAllowedTime());
299 std::string systemCachePath = GetSystemCachePath();
300 if(!systemCachePath.empty())
302 const int dir_err = mkdir(systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
303 if(0 != dir_err && errno != EEXIST)
305 DALI_LOG_ERROR("Error creating system cache directory: %s!\n", systemCachePath.c_str());
310 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
312 auto appName = GetApplicationPackageName();
313 auto bridge = Accessibility::Bridge::GetCurrentBridge();
314 bridge->SetApplicationName(appName);
315 bridge->Initialize();
316 Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
319 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent(const Dali::KeyEvent& event)
321 Accessibility::KeyEventType type;
322 if(event.GetState() == Dali::KeyEvent::DOWN)
324 type = Accessibility::KeyEventType::KEY_PRESSED;
326 else if(event.GetState() == Dali::KeyEvent::UP)
328 type = Accessibility::KeyEventType::KEY_RELEASED;
334 Dali::Accessibility::Bridge::GetCurrentBridge()->Emit(type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty());
339 Accessibility::Bridge::GetCurrentBridge()->Terminate();
341 // Ensure stop status
344 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
345 gThreadLocalAdaptor = NULL;
347 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
349 (*iter)->OnDestroy();
352 // Clear out all the handles to Windows
355 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
356 delete mObjectProfiler;
360 delete mDisplayConnection;
361 delete mPlatformAbstraction;
362 delete mCallbackManager;
363 delete mPerformanceInterface;
365 mGraphics->Destroy();
367 // uninstall it on this thread (main actor thread)
368 Dali::Integration::Log::UninstallLogFunction();
370 // Delete environment options if we own it
371 if(mEnvironmentOptionsOwned)
373 delete mEnvironmentOptions;
377 void Adaptor::Start()
379 // It doesn't support restart after stop at this moment to support restarting, need more testing
387 SetupSystemInformation();
389 // Start the callback manager
390 mCallbackManager->Start();
392 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
394 unsigned int dpiHor, dpiVer;
397 defaultWindow->GetSurface()->GetDpi(dpiHor, dpiVer);
399 // set the DPI value for font rendering
400 FontClient fontClient = FontClient::Get();
401 fontClient.SetDpi(dpiHor, dpiVer);
403 // Initialize the thread controller
404 mThreadController->Initialize();
406 // Set max texture size
407 if(mEnvironmentOptions->GetMaxTextureSize() > 0)
409 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(mEnvironmentOptions->GetMaxTextureSize());
413 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
414 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(maxTextureSize);
417 // cache advanced blending and shader language version
418 mGraphics->CacheConfigurations(*mConfigurationManager.get());
420 ProcessCoreEvents(); // Ensure any startup messages are processed.
422 // Initialize the image loader plugin
423 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
425 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
432 mAddOnManager->Start();
436 // Dali::Internal::Adaptor::Adaptor::Pause
437 void Adaptor::Pause()
439 // Only pause the adaptor if we're actually running.
440 if(RUNNING == mState)
442 // Inform observers that we are about to be paused.
443 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
451 mAddOnManager->Pause();
454 // Pause all windows event handlers when adaptor paused
455 for(auto window : mWindows)
460 mThreadController->Pause();
463 // Ensure any messages queued during pause callbacks are processed by doing another update.
466 DALI_LOG_RELEASE_INFO("Adaptor::Pause: Paused\n");
470 DALI_LOG_RELEASE_INFO("Adaptor::Pause: Not paused [%d]\n", mState);
474 // Dali::Internal::Adaptor::Adaptor::Resume
475 void Adaptor::Resume()
477 // Only resume the adaptor if we are in the suspended state.
482 // Reset the event handlers when adaptor resumed
483 for(auto window : mWindows)
488 // Resume AddOnManager
491 mAddOnManager->Resume();
494 // Inform observers that we have resumed.
495 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
500 // Trigger processing of events queued up while paused
501 mCore->ProcessEvents();
503 // Do at end to ensure our first update/render after resumption includes the processed messages as well
504 mThreadController->Resume();
506 DALI_LOG_RELEASE_INFO("Adaptor::Resume: Resumed\n");
510 DALI_LOG_RELEASE_INFO("Adaptor::Resume: Not resumed [%d]\n", mState);
516 if(RUNNING == mState ||
518 PAUSED_WHILE_HIDDEN == mState)
520 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
527 mAddOnManager->Stop();
530 mThreadController->Stop();
532 // Delete the TTS player
533 for(int i = 0; i < Dali::TtsPlayer::MODE_NUM; i++)
537 mTtsPlayers[i].Reset();
541 // Destroy the image loader plugin
542 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
544 delete mNotificationTrigger;
545 mNotificationTrigger = NULL;
547 mCallbackManager->Stop();
551 DALI_LOG_RELEASE_INFO("Adaptor::Stop\n");
555 void Adaptor::ContextLost()
557 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
560 void Adaptor::ContextRegained()
562 // Inform core, so that texture resources can be reloaded
563 mCore->RecoverFromContextLoss();
565 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
568 void Adaptor::FeedTouchPoint(TouchPoint& point, int timeStamp)
570 Integration::Point convertedPoint(point);
571 mWindows.front()->FeedTouchPoint(convertedPoint, timeStamp);
574 void Adaptor::FeedWheelEvent(Dali::WheelEvent& wheelEvent)
576 Integration::WheelEvent event(static_cast<Integration::WheelEvent::Type>(wheelEvent.GetType()), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime());
577 mWindows.front()->FeedWheelEvent(event);
580 void Adaptor::FeedKeyEvent(Dali::KeyEvent& keyEvent)
582 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());
583 mWindows.front()->FeedKeyEvent(convertedEvent);
586 void Adaptor::ReplaceSurface(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface)
588 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation(window);
589 for(auto windowPtr : mWindows)
591 if(windowPtr == windowImpl) // the window is not deleted
593 mResizedSignal.Emit(mAdaptor);
595 windowImpl->SetSurface(&newSurface);
597 // Flush the event queue to give the update-render thread chance
598 // to start processing messages for new camera setup etc as soon as possible
601 // This method blocks until the render thread has completed the replace.
602 mThreadController->ReplaceSurface(&newSurface);
608 void Adaptor::DeleteSurface(Dali::RenderSurfaceInterface& surface)
610 // Flush the event queue to give the update-render thread chance
611 // to start processing messages for new camera setup etc as soon as possible
614 // This method blocks until the render thread has finished rendering the current surface.
615 mThreadController->DeleteSurface(&surface);
618 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
620 return *mWindows.front()->GetSurface();
623 void Adaptor::ReleaseSurfaceLock()
625 mWindows.front()->GetSurface()->ReleaseLock();
628 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
630 if(!mTtsPlayers[mode])
632 // Create the TTS player when it needed, because it can reduce launching time.
633 mTtsPlayers[mode] = TtsPlayer::New(mode);
636 return mTtsPlayers[mode];
639 bool Adaptor::AddIdle(CallbackBase* callback, bool hasReturnValue, bool forceAdd)
641 bool idleAdded(false);
643 // Only add an idle if the Adaptor is actually running
644 if(RUNNING == mState || READY == mState || forceAdd)
646 idleAdded = mCallbackManager->AddIdleCallback(callback, hasReturnValue);
652 void Adaptor::RemoveIdle(CallbackBase* callback)
654 mCallbackManager->RemoveIdleCallback(callback);
657 void Adaptor::ProcessIdle()
659 bool idleProcessed = mCallbackManager->ProcessIdle();
660 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
663 void Adaptor::SetPreRenderCallback(CallbackBase* callback)
665 mThreadController->SetPreRenderCallback(callback);
668 bool Adaptor::AddWindow(Dali::Integration::SceneHolder childWindow)
670 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(childWindow);
671 windowImpl.SetAdaptor(Get());
673 // ChildWindow is set to the layout direction of the default window.
674 windowImpl.GetRootLayer().SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
676 // Add the new Window to the container - the order is not important
677 mWindows.push_back(&windowImpl);
679 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
681 mThreadController->AddSurface(surface);
683 mWindowCreatedSignal.Emit(childWindow);
688 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
690 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
691 for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
693 if(*iter == &windowImpl)
695 mWindows.erase(iter);
703 bool Adaptor::RemoveWindow(std::string childWindowName)
705 for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
707 if((*iter)->GetName() == childWindowName)
709 mWindows.erase(iter);
717 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
719 for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
721 if((*iter)->GetId() == childWindow->GetId())
723 mWindows.erase(iter);
731 Dali::Adaptor& Adaptor::Get()
733 DALI_ASSERT_ALWAYS(IsAvailable() && "Adaptor not instantiated");
734 return gThreadLocalAdaptor->mAdaptor;
737 bool Adaptor::IsAvailable()
739 return gThreadLocalAdaptor != NULL;
742 void Adaptor::SceneCreated()
744 mCore->SceneCreated();
747 Dali::Integration::Core& Adaptor::GetCore()
752 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
754 mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
757 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
759 DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
760 return *mDisplayConnection;
763 GraphicsInterface& Adaptor::GetGraphicsInterface()
765 DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
766 return *(mGraphics.get());
769 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
771 return *mPlatformAbstraction;
774 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
776 return *mNotificationTrigger;
779 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
781 return mSocketFactory;
784 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
786 if(!mWindows.empty())
788 return mWindows.front()->GetSurface();
794 TraceInterface& Adaptor::GetKernelTraceInterface()
796 return mKernelTracer;
799 TraceInterface& Adaptor::GetSystemTraceInterface()
801 return mSystemTracer;
804 PerformanceInterface* Adaptor::GetPerformanceInterface()
806 return mPerformanceInterface;
809 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
811 DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
812 return *mPlatformAbstraction;
815 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
820 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
822 if(mTtsPlayers[mode])
824 mTtsPlayers[mode].Reset();
828 Any Adaptor::GetNativeWindowHandle()
830 return mWindows.front()->GetNativeHandle();
833 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
835 Any nativeWindowHandle;
837 Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
839 for(auto sceneHolder : mWindows)
841 if(scene == sceneHolder->GetScene())
843 nativeWindowHandle = sceneHolder->GetNativeHandle();
848 return nativeWindowHandle;
851 Any Adaptor::GetGraphicsDisplay()
857 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
858 auto eglGraphics = static_cast<EglGraphics*>(graphics);
860 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
861 display = eglImpl.GetDisplay();
867 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
869 mUseRemoteSurface = useRemoteSurface;
872 void Adaptor::AddObserver(LifeCycleObserver& observer)
874 ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
876 if(match == mObservers.end())
878 mObservers.push_back(&observer);
882 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
884 ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
886 if(match != mObservers.end())
888 mObservers.erase(match);
892 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
896 mCore->QueueEvent(event);
900 void Adaptor::ProcessCoreEvents()
904 if(mPerformanceInterface)
906 mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
909 mCore->ProcessEvents();
911 if(mPerformanceInterface)
913 mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
918 void Adaptor::RequestUpdate(bool forceUpdate)
924 mThreadController->RequestUpdate();
928 case PAUSED_WHILE_HIDDEN:
932 // Update (and resource upload) without rendering
933 mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
945 void Adaptor::RequestProcessEventsOnIdle(bool forceProcess)
947 // Only request a notification if the Adaptor is actually running
948 // and we haven't installed the idle notification
949 if((!mNotificationOnIdleInstalled) && (RUNNING == mState || READY == mState || forceProcess))
951 mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), forceProcess);
955 void Adaptor::OnWindowShown()
957 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
959 if(PAUSED_WHILE_HIDDEN == mState)
961 // Adaptor can now be resumed
966 // Force a render task
969 else if(RUNNING == mState)
971 // Force a render task
974 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
976 else if(PAUSED_WHILE_INITIALIZING == mState)
978 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
983 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
987 void Adaptor::OnWindowHidden()
989 Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
991 if(RUNNING == mState || READY == mState)
993 bool allWindowsHidden = true;
995 for(auto window : mWindows)
997 if(window->IsVisible())
999 allWindowsHidden = false;
1004 // Only pause the adaptor when all the windows are hidden
1005 if(allWindowsHidden)
1007 if(mState == RUNNING)
1011 // Adaptor cannot be resumed until any window is shown
1012 mState = PAUSED_WHILE_HIDDEN;
1014 else // mState is READY
1016 // Pause the adaptor after the state gets RUNNING
1017 mState = PAUSED_WHILE_INITIALIZING;
1022 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1027 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1031 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1032 void Adaptor::OnDamaged(const DamageArea& area)
1034 // This is needed for the case where Dali window is partially obscured
1035 RequestUpdate(false);
1038 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1040 mResizedSignal.Emit(mAdaptor);
1043 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1045 // Nofify surface resizing before flushing event queue
1046 mThreadController->ResizeSurface();
1048 // Flush the event queue to give the update-render thread chance
1049 // to start processing messages for new camera setup etc as soon as possible
1050 ProcessCoreEvents();
1053 void Adaptor::NotifySceneCreated()
1055 GetCore().SceneCreated();
1057 // Flush the event queue to give the update-render thread chance
1058 // to start processing messages for new camera setup etc as soon as possible
1059 ProcessCoreEvents();
1061 // Start thread controller after the scene has been created
1062 mThreadController->Start();
1064 // Process after surface is created (registering to remote surface provider if required)
1065 SurfaceInitialized();
1067 if(mState != PAUSED_WHILE_INITIALIZING)
1071 DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1079 mState = PAUSED_WHILE_HIDDEN;
1081 DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1085 void Adaptor::NotifyLanguageChanged()
1087 mLanguageChangedSignal.Emit(mAdaptor);
1090 void Adaptor::RenderOnce()
1092 if(mThreadController)
1094 UpdateMode updateMode;
1095 if(mThreadMode == ThreadMode::NORMAL)
1097 updateMode = UpdateMode::NORMAL;
1101 updateMode = UpdateMode::FORCE_RENDER;
1103 ProcessCoreEvents();
1105 mThreadController->RequestUpdateOnce(updateMode);
1109 const LogFactoryInterface& Adaptor::GetLogFactory()
1111 return *mEnvironmentOptions;
1114 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1116 GetCore().RegisterProcessor(processor, postProcessor);
1119 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1121 GetCore().UnregisterProcessor(processor, postProcessor);
1124 bool Adaptor::IsMultipleWindowSupported() const
1126 return mConfigurationManager->IsMultipleWindowSupported();
1129 void Adaptor::RequestUpdateOnce()
1131 if(mThreadController)
1133 mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1137 bool Adaptor::ProcessCoreEventsFromIdle()
1139 ProcessCoreEvents();
1141 // the idle handle automatically un-installs itself
1142 mNotificationOnIdleInstalled = false;
1147 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1149 Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1151 for(auto window : mWindows)
1153 if(scene == window->GetScene())
1162 Dali::WindowContainer Adaptor::GetWindows() const
1164 Dali::WindowContainer windows;
1166 for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1168 // Downcast to Dali::Window
1169 Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1172 windows.push_back(window);
1179 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1181 Dali::SceneHolderList sceneHolderList;
1183 for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1185 sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1188 return sceneHolderList;
1191 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1193 Dali::ObjectRegistry registry;
1196 registry = mCore->GetObjectRegistry();
1201 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1203 mLanguageChangedSignal(),
1204 mWindowCreatedSignal(),
1208 mThreadController(nullptr),
1210 mDisplayConnection(nullptr),
1212 mConfigurationManager(nullptr),
1213 mPlatformAbstraction(nullptr),
1214 mCallbackManager(nullptr),
1215 mNotificationOnIdleInstalled(false),
1216 mNotificationTrigger(nullptr),
1217 mDaliFeedbackPlugin(),
1218 mFeedbackController(nullptr),
1221 mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1222 mPerformanceInterface(nullptr),
1225 mObjectProfiler(nullptr),
1227 mThreadMode(threadMode),
1228 mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1229 mUseRemoteSurface(false),
1230 mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1232 DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1233 mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1235 gThreadLocalAdaptor = this;
1238 void Adaptor::SetRootLayoutDirection(std::string locale)
1240 mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1241 for(auto& window : mWindows)
1243 Dali::Actor root = window->GetRootLayer();
1244 root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1248 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1250 bool idleAdded(false);
1252 // Only add an idle if the Adaptor is actually running
1253 if(RUNNING == mState || READY == mState || forceAdd)
1255 idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1267 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1269 mCallbackManager->RemoveIdleEntererCallback(callback);
1272 } // namespace Adaptor
1274 } // namespace Internal