2 * Copyright (c) 2024 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/integration-api/trace.h>
38 #include <dali/public-api/actors/layer.h>
39 #include <dali/public-api/events/wheel-event.h>
40 #include <dali/public-api/object/any.h>
41 #include <dali/public-api/object/object-registry.h>
46 #include <dali/internal/adaptor/common/lifecycle-observer.h>
47 #include <dali/internal/adaptor/common/thread-controller-interface.h>
48 #include <dali/internal/system/common/performance-interface-factory.h>
49 #include <dali/internal/system/common/thread-controller.h>
50 #include <dali/public-api/dali-adaptor-common.h>
52 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
53 #include <dali/internal/graphics/gles/egl-graphics.h>
55 #include <dali/devel-api/text-abstraction/font-client.h>
57 #include <dali/internal/accessibility/common/tts-player-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/system/common/system-factory.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/event-handler.h>
68 #include <dali/internal/window-system/common/window-impl.h>
69 #include <dali/internal/window-system/common/window-render-surface.h>
70 #include <dali/internal/window-system/common/window-system.h>
72 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
73 #include <dali/internal/system/common/logging.h>
75 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
76 #include <dali/internal/imaging/common/image-loader.h>
77 #include <dali/internal/system/common/locale-utils.h>
79 #include <dali/devel-api/adaptor-framework/environment-variable.h>
80 #include <dali/internal/system/common/configuration-manager.h>
81 #include <dali/internal/system/common/environment-variables.h>
83 using Dali::TextAbstraction::FontClient;
85 extern std::string GetSystemCachePath();
95 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
97 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
98 } // unnamed namespace
100 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
102 Dali::Adaptor* adaptor = new Dali::Adaptor;
103 Adaptor* impl = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode);
104 adaptor->mImpl = impl;
106 Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder(*(impl->mEnvironmentOptions));
107 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
109 impl->Initialize(graphicsFactory);
110 delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
115 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
117 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
118 Dali::Adaptor* adaptor = New(window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
119 windowImpl.SetAdaptor(*adaptor);
123 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
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;
129 impl->Initialize(graphicsFactory);
134 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
136 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
137 Dali::Adaptor* adaptor = New(graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
138 windowImpl.SetAdaptor(*adaptor);
142 void Adaptor::Initialize(GraphicsFactory& graphicsFactory)
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
149 mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
152 GetDataStoragePath(path);
153 mPlatformAbstraction->SetDataStoragePath(path);
155 if(mEnvironmentOptions->PerformanceServerRequired())
157 mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface(*this, *mEnvironmentOptions);
160 mEnvironmentOptions->CreateTraceManager(mPerformanceInterface);
161 mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
163 mCallbackManager = Dali::Internal::Adaptor::GetSystemFactory()->CreateCallbackManager();
165 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
167 DALI_ASSERT_DEBUG(defaultWindow->GetSurface() && "Surface not initialized");
169 mGraphics = std::unique_ptr<GraphicsInterface>(&graphicsFactory.Create());
171 // Create the AddOnManager
172 mAddOnManager.reset(Dali::Internal::AddOnManagerFactory::CreateAddOnManager());
174 Integration::CorePolicyFlags corePolicyFlags = Integration::CorePolicyFlags::DEFAULT;
175 if(0u != mEnvironmentOptions->GetRenderToFboInterval())
177 corePolicyFlags |= Integration::CorePolicyFlags::RENDER_TO_FRAME_BUFFER;
179 if(Integration::DepthBufferAvailable::TRUE == mGraphics->GetDepthBufferRequired())
181 corePolicyFlags |= Integration::CorePolicyFlags::DEPTH_BUFFER_AVAILABLE;
183 if(Integration::StencilBufferAvailable::TRUE == mGraphics->GetStencilBufferRequired())
185 corePolicyFlags |= Integration::CorePolicyFlags::STENCIL_BUFFER_AVAILABLE;
187 if(Integration::PartialUpdateAvailable::TRUE == mGraphics->GetPartialUpdateRequired())
189 corePolicyFlags |= Integration::CorePolicyFlags::PARTIAL_UPDATE_AVAILABLE;
192 mCore = Integration::Core::New(*this,
193 *mPlatformAbstraction,
194 mGraphics->GetController(),
197 // Create TextureUploadManager after mCore created
198 mTextureUploadManager = Dali::Devel::TextureUploadManager::Get();
200 defaultWindow->SetAdaptor(Get());
202 Dali::Integration::SceneHolder defaultSceneHolder(defaultWindow);
204 mWindowCreatedSignal.Emit(defaultSceneHolder);
206 const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
207 if(0u < timeInterval)
209 mObjectProfiler = new ObjectProfiler(mCore->GetObjectRegistry(), timeInterval);
212 const uint32_t poolTimeInterval = mEnvironmentOptions->GetMemoryPoolInterval();
213 if(0u < poolTimeInterval)
215 mMemoryPoolTimer = Dali::Timer::New(poolTimeInterval * 1000);
216 mMemoryPoolTimer.TickSignal().Connect(mMemoryPoolTimerSlotDelegate, &Adaptor::MemoryPoolTimeout);
217 mMemoryPoolTimer.Start();
220 mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &Adaptor::ProcessCoreEvents), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
222 mDisplayConnection = Dali::DisplayConnection::New(*mGraphics, defaultWindow->GetSurface()->GetSurfaceType());
224 mThreadController = new ThreadController(*this, *mEnvironmentOptions, mThreadMode);
226 // Should be called after Core creation
227 if(mEnvironmentOptions->GetPanGestureLoggingLevel())
229 Integration::EnableProfiling(Dali::Integration::PROFILING_TYPE_PAN_GESTURE);
231 if(mEnvironmentOptions->GetPanGesturePredictionMode() >= 0)
233 Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
235 if(mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0)
237 Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
239 if(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0)
241 Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
243 if(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0)
245 Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
247 if(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0)
249 Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
251 if(mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0)
253 Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
255 if(mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f)
257 Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
259 if(mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0)
261 Integration::SetPanGestureUseActualTimes(mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false);
263 if(mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0)
265 Integration::SetPanGestureInterpolationTimeRange(mEnvironmentOptions->GetPanGestureInterpolationTimeRange());
267 if(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0)
269 Integration::SetPanGestureScalarOnlyPredictionEnabled(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false);
271 if(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0)
273 Integration::SetPanGestureTwoPointPredictionEnabled(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false);
275 if(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0)
277 Integration::SetPanGestureTwoPointInterpolatePastTime(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime());
279 if(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f)
281 Integration::SetPanGestureTwoPointVelocityBias(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias());
283 if(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f)
285 Integration::SetPanGestureTwoPointAccelerationBias(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias());
287 if(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0)
289 Integration::SetPanGestureMultitapSmoothingRange(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange());
291 if(mEnvironmentOptions->GetMinimumPanDistance() >= 0)
293 Integration::SetPanGestureMinimumDistance(mEnvironmentOptions->GetMinimumPanDistance());
295 if(mEnvironmentOptions->GetMinimumPanEvents() >= 0)
297 Integration::SetPanGestureMinimumPanEvents(mEnvironmentOptions->GetMinimumPanEvents());
299 if(mEnvironmentOptions->GetMinimumPinchDistance() >= 0)
301 Integration::SetPinchGestureMinimumDistance(mEnvironmentOptions->GetMinimumPinchDistance());
303 if(mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0)
305 Integration::SetPinchGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumPinchTouchEvents());
307 if(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0)
309 Integration::SetPinchGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart());
311 if(mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0)
313 Integration::SetRotationGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumRotationTouchEvents());
315 if(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0)
317 Integration::SetRotationGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart());
319 if(mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0)
321 Integration::SetLongPressMinimumHoldingTime(mEnvironmentOptions->GetLongPressMinimumHoldingTime());
323 if(mEnvironmentOptions->GetTapMaximumAllowedTime() > 0)
325 Integration::SetTapMaximumAllowedTime(mEnvironmentOptions->GetTapMaximumAllowedTime());
328 std::string systemCachePath = GetSystemCachePath();
329 if(!systemCachePath.empty())
331 const int dir_err = mkdir(systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
332 if(0 != dir_err && errno != EEXIST)
334 DALI_LOG_ERROR("Error creating system cache directory: %s!\n", systemCachePath.c_str());
338 mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
343 Accessibility::Bridge::GetCurrentBridge()->Terminate();
345 // Ensure stop status
348 // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
349 gThreadLocalAdaptor = NULL;
351 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
353 (*iter)->OnDestroy();
356 // Clear out all the handles to Windows
359 delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
360 delete mObjectProfiler;
364 delete mDisplayConnection;
365 delete mPlatformAbstraction;
367 mCallbackManager.reset();
369 delete mPerformanceInterface;
371 mGraphics->Destroy();
373 // uninstall it on this thread (main actor thread)
374 Dali::Integration::Log::UninstallLogFunction();
376 // Delete environment options if we own it
377 if(mEnvironmentOptionsOwned)
379 delete mEnvironmentOptions;
383 void Adaptor::Start()
385 // It doesn't support restart after stop at this moment to support restarting, need more testing
393 SetupSystemInformation();
395 // Start the callback manager
396 mCallbackManager->Start();
398 // Initialize accessibility bridge after callback manager is started to use Idler callback
399 auto appName = GetApplicationPackageName();
400 auto bridge = Accessibility::Bridge::GetCurrentBridge();
401 bridge->SetApplicationName(appName);
402 bridge->Initialize();
404 Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
406 unsigned int dpiHor, dpiVer;
409 defaultWindow->GetSurface()->GetDpi(dpiHor, dpiVer);
410 Dali::Internal::Adaptor::WindowSystem::SetDpi(dpiHor, dpiVer);
412 // Initialize the thread controller
413 mThreadController->Initialize();
415 // Set max texture size
416 if(mEnvironmentOptions->GetMaxTextureSize() > 0)
418 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(mEnvironmentOptions->GetMaxTextureSize());
422 unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
423 Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(maxTextureSize);
426 // cache advanced blending and shader language version
427 mGraphics->CacheConfigurations(*mConfigurationManager.get());
429 ProcessCoreEvents(); // Ensure any startup messages are processed.
431 // Initialize the image loader plugin
432 auto enablePluginString = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_ENABLE_IMAGE_LOADER_PLUGIN);
433 bool enablePlugin = enablePluginString ? std::atoi(enablePluginString) : false;
436 Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
439 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
446 mAddOnManager->Start();
450 // Dali::Internal::Adaptor::Adaptor::Pause
451 void Adaptor::Pause()
453 // Only pause the adaptor if we're actually running.
454 if(RUNNING == mState)
456 // Inform observers that we are about to be paused.
457 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
465 mAddOnManager->Pause();
468 // Pause all windows event handlers when adaptor paused
469 for(auto window : mWindows)
474 mThreadController->Pause();
477 // Ensure any messages queued during pause callbacks are processed by doing another update.
480 DALI_LOG_RELEASE_INFO("Adaptor::Pause: Paused\n");
484 DALI_LOG_RELEASE_INFO("Adaptor::Pause: Not paused [%d]\n", mState);
488 // Dali::Internal::Adaptor::Adaptor::Resume
489 void Adaptor::Resume()
491 // Only resume the adaptor if we are in the suspended state.
496 // Reset the event handlers when adaptor resumed
497 for(auto window : mWindows)
502 // Resume AddOnManager
505 mAddOnManager->Resume();
508 // Inform observers that we have resumed.
509 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
514 // Trigger processing of events queued up while paused
515 mCore->ProcessEvents();
517 // Do at end to ensure our first update/render after resumption includes the processed messages as well
518 mThreadController->Resume();
520 DALI_LOG_RELEASE_INFO("Adaptor::Resume: Resumed\n");
524 DALI_LOG_RELEASE_INFO("Adaptor::Resume: Not resumed [%d]\n", mState);
530 if(RUNNING == mState ||
532 PAUSED_WHILE_HIDDEN == mState)
534 for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
541 mAddOnManager->Stop();
544 mThreadController->Stop();
546 // Delete the TTS player
547 for(int i = 0; i < Dali::TtsPlayer::MODE_NUM; i++)
551 mTtsPlayers[i].Reset();
555 // Destroy the image loader plugin
556 auto enablePluginString = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_ENABLE_IMAGE_LOADER_PLUGIN);
557 bool enablePlugin = enablePluginString ? std::atoi(enablePluginString) : false;
560 Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
563 delete mNotificationTrigger;
564 mNotificationTrigger = NULL;
566 mCallbackManager->Stop();
568 mCore->UnregisterProcessors();
570 RemoveSystemInformation();
572 // Note: Must change the state at end of function.
575 DALI_LOG_RELEASE_INFO("Adaptor::Stop\n");
579 void Adaptor::ContextLost()
581 mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
584 void Adaptor::ContextRegained()
586 // Inform core, so that texture resources can be reloaded
587 mCore->RecoverFromContextLoss();
589 mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
592 void Adaptor::FeedTouchPoint(TouchPoint& point, int timeStamp)
594 Integration::Point convertedPoint(point);
595 mWindows.front()->FeedTouchPoint(convertedPoint, timeStamp);
598 void Adaptor::FeedWheelEvent(Dali::WheelEvent& wheelEvent)
600 Integration::WheelEvent event(static_cast<Integration::WheelEvent::Type>(wheelEvent.GetType()), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime());
601 mWindows.front()->FeedWheelEvent(event);
604 void Adaptor::FeedKeyEvent(Dali::KeyEvent& keyEvent)
606 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());
607 mWindows.front()->FeedKeyEvent(convertedEvent);
610 void Adaptor::ReplaceSurface(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface)
612 Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation(window);
613 for(auto windowPtr : mWindows)
615 if(windowPtr == windowImpl) // the window is not deleted
617 mResizedSignal.Emit(mAdaptor);
619 windowImpl->SetSurface(&newSurface);
621 // Flush the event queue to give the update-render thread chance
622 // to start processing messages for new camera setup etc as soon as possible
625 // This method blocks until the render thread has completed the replace.
626 mThreadController->ReplaceSurface(&newSurface);
632 void Adaptor::DeleteSurface(Dali::RenderSurfaceInterface& surface)
634 // Flush the event queue to give the update-render thread chance
635 // to start processing messages for new camera setup etc as soon as possible
638 // This method blocks until the render thread has finished rendering the current surface.
639 mThreadController->DeleteSurface(&surface);
642 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
644 return *mWindows.front()->GetSurface();
647 void Adaptor::ReleaseSurfaceLock()
649 mWindows.front()->GetSurface()->ReleaseLock();
652 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
654 if(!mTtsPlayers[mode])
656 // Create the TTS player when it needed, because it can reduce launching time.
657 mTtsPlayers[mode] = TtsPlayer::New(mode);
660 return mTtsPlayers[mode];
663 bool Adaptor::AddIdle(CallbackBase* callback, bool hasReturnValue)
665 bool idleAdded(false);
667 // We want to run the processes even when paused
668 if(STOPPED != mState)
670 idleAdded = mCallbackManager->AddIdleCallback(callback, hasReturnValue);
682 void Adaptor::RemoveIdle(CallbackBase* callback)
684 mCallbackManager->RemoveIdleCallback(callback);
687 void Adaptor::ProcessIdle()
689 bool idleProcessed = mCallbackManager->ProcessIdle();
690 mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
693 void Adaptor::SetPreRenderCallback(CallbackBase* callback)
695 mThreadController->SetPreRenderCallback(callback);
698 bool Adaptor::AddWindow(Dali::Integration::SceneHolder childWindow)
700 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(childWindow);
701 windowImpl.SetAdaptor(Get());
703 // ChildWindow is set to the layout direction of the default window.
704 windowImpl.GetRootLayer().SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
706 // Add the new Window to the container - the order is not important
708 Dali::Mutex::ScopedLock lock(mMutex);
709 mWindows.push_back(&windowImpl);
712 Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
714 mThreadController->AddSurface(surface);
716 mWindowCreatedSignal.Emit(childWindow);
721 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
723 Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
724 for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
726 if(*iter == &windowImpl)
728 Dali::Mutex::ScopedLock lock(mMutex);
729 mWindows.erase(iter);
737 bool Adaptor::RemoveWindow(std::string childWindowName)
739 for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
741 if((*iter)->GetName() == childWindowName)
743 Dali::Mutex::ScopedLock lock(mMutex);
744 mWindows.erase(iter);
752 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
754 for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
756 if((*iter)->GetId() == childWindow->GetId())
758 Dali::Mutex::ScopedLock lock(mMutex);
759 mWindows.erase(iter);
767 Dali::Adaptor& Adaptor::Get()
769 DALI_ASSERT_ALWAYS((gThreadLocalAdaptor != NULL) && "Adaptor not instantiated");
770 return gThreadLocalAdaptor->mAdaptor;
773 bool Adaptor::IsAvailable()
775 return gThreadLocalAdaptor != NULL && (gThreadLocalAdaptor->mState != Adaptor::State::STOPPED);
778 void Adaptor::SceneCreated()
780 mCore->SceneCreated();
783 Dali::Integration::Core& Adaptor::GetCore()
788 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
790 mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
793 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
795 DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
796 return *mDisplayConnection;
799 GraphicsInterface& Adaptor::GetGraphicsInterface()
801 DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
802 return *(mGraphics.get());
805 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
807 return *mPlatformAbstraction;
810 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
812 return *mNotificationTrigger;
815 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
817 return mSocketFactory;
820 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
822 if(!mWindows.empty())
824 return mWindows.front()->GetSurface();
830 TraceInterface& Adaptor::GetKernelTraceInterface()
832 return mKernelTracer;
835 TraceInterface& Adaptor::GetSystemTraceInterface()
837 return mSystemTracer;
840 PerformanceInterface* Adaptor::GetPerformanceInterface()
842 return mPerformanceInterface;
845 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
847 DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
848 return *mPlatformAbstraction;
851 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
853 Dali::Mutex::ScopedLock lock(mMutex);
857 Devel::TextureUploadManager& Adaptor::GetTextureUploadManager()
859 return mTextureUploadManager;
862 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
864 if(mTtsPlayers[mode])
866 mTtsPlayers[mode].Reset();
870 Any Adaptor::GetNativeWindowHandle()
872 return mWindows.front()->GetNativeHandle();
875 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
877 Any nativeWindowHandle;
879 Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
881 for(auto sceneHolder : mWindows)
883 if(scene == sceneHolder->GetScene())
885 nativeWindowHandle = sceneHolder->GetNativeHandle();
890 return nativeWindowHandle;
893 Any Adaptor::GetGraphicsDisplay()
899 GraphicsInterface* graphics = mGraphics.get(); // This interface is temporary until Core has been updated to match
900 auto eglGraphics = static_cast<EglGraphics*>(graphics);
902 EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
903 display = eglImpl.GetDisplay();
909 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
911 mUseRemoteSurface = useRemoteSurface;
914 void Adaptor::AddObserver(LifeCycleObserver& observer)
916 ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
918 if(match == mObservers.end())
920 mObservers.push_back(&observer);
924 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
926 ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
928 if(match != mObservers.end())
930 mObservers.erase(match);
934 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
938 mCore->QueueEvent(event);
942 void Adaptor::FlushUpdateMessages()
946 DALI_TRACE_SCOPE(gTraceFilter, "DALI_FLUSH_UPDATE_MESSAGES");
948 mCore->ForceRelayout();
952 void Adaptor::ProcessCoreEvents()
956 DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
958 if(mPerformanceInterface)
960 mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
963 mCore->ProcessEvents();
965 if(mPerformanceInterface)
967 mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
972 void Adaptor::RequestUpdate()
978 mThreadController->RequestUpdate();
982 case PAUSED_WHILE_HIDDEN:
984 // Update (and resource upload) without rendering
985 mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
996 void Adaptor::RequestProcessEventsOnIdle()
998 // We want to run the processes even when paused
999 if(STOPPED != mState)
1001 if(!mNotificationOnIdleInstalled)
1003 // If we haven't installed the idle notification, install it idle enterer.
1004 mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle));
1008 // Request comes during ProcessCoreEventsFromIdle running.
1009 // Mark as we need to call ProcessEvents in next idle events.
1010 mRequiredIdleRepeat = true;
1015 void Adaptor::OnWindowShown()
1017 if(PAUSED_WHILE_HIDDEN == mState)
1019 // Adaptor can now be resumed
1024 // Force a render task
1025 RequestUpdateOnce();
1027 else if(RUNNING == mState)
1029 // Force a render task
1030 RequestUpdateOnce();
1032 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
1034 else if(PAUSED_WHILE_INITIALIZING == mState)
1036 // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
1041 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
1045 void Adaptor::OnWindowHidden()
1047 if(RUNNING == mState || READY == mState)
1049 bool allWindowsHidden = true;
1051 for(auto window : mWindows)
1053 if(window->IsVisible())
1055 allWindowsHidden = false;
1060 // Only pause the adaptor when all the windows are hidden
1061 if(allWindowsHidden)
1063 if(mState == RUNNING)
1067 // Adaptor cannot be resumed until any window is shown
1068 mState = PAUSED_WHILE_HIDDEN;
1070 else // mState is READY
1072 // Pause the adaptor after the state gets RUNNING
1073 mState = PAUSED_WHILE_INITIALIZING;
1078 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1083 DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1087 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1088 void Adaptor::OnDamaged(const DamageArea& area)
1090 // This is needed for the case where Dali window is partially obscured
1094 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1096 mResizedSignal.Emit(mAdaptor);
1099 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1101 // Nofify surface resizing before flushing event queue
1102 mThreadController->ResizeSurface();
1104 // Flush the event queue to give the update-render thread chance
1105 // to start processing messages for new camera setup etc as soon as possible
1106 ProcessCoreEvents();
1109 void Adaptor::IncreaseSurfaceResizeCounter()
1111 // Nofify surface resizing before flushing event queue
1112 if(mThreadController)
1114 mThreadController->ResizeSurface();
1118 void Adaptor::NotifySceneCreated()
1120 GetCore().SceneCreated();
1122 // Flush the event queue to give the update-render thread chance
1123 // to start processing messages for new camera setup etc as soon as possible
1124 ProcessCoreEvents();
1126 // Start thread controller after the scene has been created
1127 mThreadController->Start();
1129 // Process after surface is created (registering to remote surface provider if required)
1130 SurfaceInitialized();
1132 if(mState != PAUSED_WHILE_INITIALIZING)
1136 DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1144 mState = PAUSED_WHILE_HIDDEN;
1146 DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1150 void Adaptor::NotifyLanguageChanged()
1152 mLanguageChangedSignal.Emit(mAdaptor);
1155 void Adaptor::RenderOnce()
1157 if(mThreadController)
1159 UpdateMode updateMode;
1160 if(mThreadMode == ThreadMode::NORMAL)
1162 updateMode = UpdateMode::NORMAL;
1166 updateMode = UpdateMode::FORCE_RENDER;
1168 ProcessCoreEvents();
1172 for(auto&& iter : mWindows)
1174 iter->GetSurface()->SetFullSwapNextFrame();
1177 mThreadController->RequestUpdateOnce(updateMode);
1181 const LogFactoryInterface& Adaptor::GetLogFactory()
1183 return *mEnvironmentOptions;
1186 const TraceFactoryInterface& Adaptor::GetTraceFactory()
1188 return *mEnvironmentOptions;
1191 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1193 GetCore().RegisterProcessor(processor, postProcessor);
1196 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1198 GetCore().UnregisterProcessor(processor, postProcessor);
1201 bool Adaptor::IsMultipleWindowSupported() const
1203 return mConfigurationManager->IsMultipleWindowSupported();
1206 int32_t Adaptor::GetRenderThreadId() const
1208 if(mThreadController)
1210 return mThreadController->GetThreadId();
1215 void Adaptor::RequestUpdateOnce()
1217 if(mThreadController)
1219 mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1223 bool Adaptor::ProcessCoreEventsFromIdle()
1225 // Reset repeat idler flag.
1226 mRequiredIdleRepeat = false;
1227 ProcessCoreEvents();
1229 // If someone request ProcessCoreEvents during above ProcessCoreEvents call, we might need to run idle one more times.
1230 // Else, the idle handle automatically un-installs itself
1231 mNotificationOnIdleInstalled = mRequiredIdleRepeat;
1233 if(mRequiredIdleRepeat)
1235 DALI_LOG_DEBUG_INFO("Required ProcessCoreEvents one more times\n");
1238 return mRequiredIdleRepeat;
1241 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1243 Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1245 for(auto window : mWindows)
1247 if(scene == window->GetScene())
1256 Dali::WindowContainer Adaptor::GetWindows() const
1258 Dali::WindowContainer windows;
1260 for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1262 // Downcast to Dali::Window
1263 Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1266 windows.push_back(window);
1273 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1275 Dali::SceneHolderList sceneHolderList;
1277 for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1279 sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1282 return sceneHolderList;
1285 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1287 Dali::ObjectRegistry registry;
1290 registry = mCore->GetObjectRegistry();
1295 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1297 mLanguageChangedSignal(),
1298 mWindowCreatedSignal(),
1302 mThreadController(nullptr),
1304 mDisplayConnection(nullptr),
1306 mConfigurationManager(nullptr),
1307 mPlatformAbstraction(nullptr),
1308 mCallbackManager(nullptr),
1309 mNotificationOnIdleInstalled(false),
1310 mRequiredIdleRepeat(false),
1311 mNotificationTrigger(nullptr),
1312 mDaliFeedbackPlugin(),
1313 mFeedbackController(nullptr),
1316 mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1317 mPerformanceInterface(nullptr),
1320 mTextureUploadManager(),
1321 mObjectProfiler(nullptr),
1322 mMemoryPoolTimerSlotDelegate(this),
1325 mThreadMode(threadMode),
1326 mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1327 mUseRemoteSurface(false),
1328 mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1330 DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1331 mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1333 gThreadLocalAdaptor = this;
1336 void Adaptor::SetRootLayoutDirection(std::string locale)
1338 mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1339 for(auto& window : mWindows)
1341 Dali::Actor root = window->GetRootLayer();
1342 root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1346 bool Adaptor::AddIdleEnterer(CallbackBase* callback)
1348 bool idleAdded(false);
1350 // We want to run the processes even when paused
1351 if(STOPPED != mState)
1353 idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1365 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1367 mCallbackManager->RemoveIdleEntererCallback(callback);
1370 bool Adaptor::MemoryPoolTimeout()
1372 mCore->LogMemoryPools();
1373 return true; // Keep logging forever
1376 } // namespace Adaptor
1378 } // namespace Internal