/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/internal/adaptor/common/framework-factory.h>
#include <dali/internal/adaptor/common/framework.h>
#include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
+#include <dali/internal/graphics/common/graphics-factory-interface.h>
#include <dali/internal/system/common/command-line-options.h>
#include <dali/internal/system/common/environment-variables.h>
#include <dali/internal/system/common/system-settings.h>
{
namespace Adaptor
{
+namespace
+{
+#ifdef UI_THREAD_AVAILABLE
+const char* TIZEN_UI_THREAD_ENV = "TIZEN_UI_THREAD";
+#endif
DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_APPLICATION, true);
+} // namespace
ApplicationPtr Application::gPreInitializedApplication(NULL);
{
if(!gPreInitializedApplication)
{
+ bool isUseUIThread = false;
+
+#ifdef UI_THREAD_AVAILABLE
+ const char* retEnv = Dali::EnvironmentVariable::GetEnvironmentVariable(TIZEN_UI_THREAD_ENV);
+ if(retEnv)
+ {
+ std::string uiThreadEnv = retEnv;
+ std::string enabledString = "true";
+ if(uiThreadEnv == enabledString)
+ {
+ isUseUIThread = true;
+ }
+ }
+#endif
+
Dali::TextAbstraction::FontClientPreInitialize();
WindowData windowData;
- gPreInitializedApplication = new Application(argc, argv, "", Framework::NORMAL, false, windowData);
+ gPreInitializedApplication = new Application(argc, argv, "", Framework::NORMAL, isUseUIThread, windowData);
gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
- gPreInitializedApplication->CreateWindow(); // Only create window
+
+#ifdef UI_THREAD_AVAILABLE
+ if(isUseUIThread)
+ {
+ DALI_LOG_RELEASE_INFO("PRE_INITIALIZED with UI Threading\n");
+ gPreInitializedApplication->mUIThreadLoader = new UIThreadLoader(argc, argv);
+ gPreInitializedApplication->mUIThreadLoader->Run([&]() { gPreInitializedApplication->CreateWindow(); });
+ }
+ else
+#endif
+ {
+ DALI_LOG_RELEASE_INFO("Only PRE_INITIALIZED\n");
+ gPreInitializedApplication->CreateWindow(); // Only create window
+ }
}
}
mLanguageChangedSignal(),
mRegionChangedSignal(),
mFramework(nullptr),
+ mFrameworkFactory(nullptr),
mCommandLineOptions(nullptr),
- mAdaptorBuilder(nullptr),
mAdaptor(nullptr),
mEnvironmentOptions(nullptr),
mMainWindow(),
mMainWindowMode(windowData.GetTransparency() ? WINDOW_MODE::TRANSPARENT : WINDOW_MODE::OPAQUE),
mMainWindowName(),
+ mIsMainWindowFrontBufferRendering(windowData.GetFrontBufferRendering()),
mStylesheet(stylesheet),
mWindowPositionSize(windowData.GetPositionSize()),
mLaunchpadState(Launchpad::NONE),
mDefaultWindowType(windowData.GetWindowType()),
mUseUiThread(useUiThread),
- mSlotDelegate(this)
+ mIsSystemInitialized(false),
+ mSlotDelegate(this),
+ mUIThreadLoader(nullptr)
{
// Set mName from command-line args
if(argc && (*argc > 0))
}
mCommandLineOptions = new CommandLineOptions(argc, argv);
- mFramework = Dali::Internal::Adaptor::GetFrameworkFactory()->CreateFramework(FrameworkBackend::DEFAULT, *this, *this, argc, argv, applicationType, mUseUiThread);
+
+ mFrameworkFactory = std::unique_ptr<FrameworkFactory>(Dali::Internal::Adaptor::CreateFrameworkFactory());
+ mFramework = mFrameworkFactory->CreateFramework(FrameworkBackend::DEFAULT, *this, *this, argc, argv, applicationType, mUseUiThread);
mUseRemoteSurface = (applicationType == Framework::WATCH);
}
if(!mUseUiThread)
{
delete mAdaptor;
- delete mAdaptorBuilder;
- WindowSystem::Shutdown();
+ if(mIsSystemInitialized)
+ {
+ WindowSystem::Shutdown();
+ }
+ }
+ else
+ {
+ if(mUIThreadLoader)
+ {
+ delete mUIThreadLoader;
+ }
}
}
mWindowPositionSize = positionSize;
}
+void Application::StoreFrontBufferRendering(bool enable)
+{
+ mIsMainWindowFrontBufferRendering = enable;
+}
+
void Application::ChangePreInitializedWindowInfo()
{
// Set window name
mWindowPositionSize.height = screenHeight;
mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
}
+
+ // Set front buffer rendering
+ Dali::DevelWindow::SetFrontBufferRendering(mMainWindow, mIsMainWindowFrontBufferRendering);
}
void Application::CreateWindow()
WindowData windowData;
windowData.SetTransparency(mMainWindowMode);
windowData.SetWindowType(mDefaultWindowType);
+ windowData.SetFrontBufferRendering(mIsMainWindowFrontBufferRendering);
+
+ DALI_LOG_RELEASE_INFO("Create Default Window\n");
WindowSystem::Initialize();
+ mIsSystemInitialized = true;
if(mLaunchpadState != Launchpad::PRE_INITIALIZED)
{
}
else
{
- // The position, size and the window name of the pre-initialized application will be updated in ChangePreInitializedWindowInfo()
- // when the real application is launched.
+ // The position, size, window name, and frontbuffering of the pre-initialized application
+ // will be updated in ChangePreInitializedWindowInfo() when the real application is launched.
windowData.SetPositionSize(mWindowPositionSize);
window = Internal::Adaptor::Window::New("", "", windowData);
}
GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
}
-void Application::CreateAdaptor()
+void Application::CreateAdaptor(AdaptorBuilder& adaptorBuilder)
{
DALI_ASSERT_ALWAYS(mMainWindow && "Window required to create adaptor");
- auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
+ auto& graphicsFactory = adaptorBuilder.GetGraphicsFactory();
Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
}
-void Application::CreateAdaptorBuilder()
-{
- mAdaptorBuilder = new AdaptorBuilder(*mEnvironmentOptions);
-}
-
void Application::MainLoop()
{
// Run the application
{
// Actually quit the application.
// Force a call to Quit even if adaptor is not running.
- Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false, true);
+ Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false);
}
void Application::QuitFromMainLoop()
mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
- CreateAdaptorBuilder();
+ auto& adaptorBuilder = AdaptorBuilder::Get(*mEnvironmentOptions);
// If an application was pre-initialized, a window was made in advance
if(mLaunchpadState == Launchpad::NONE)
{
+ DALI_LOG_RELEASE_INFO("default Window is created in standalone\n");
CreateWindow();
}
- CreateAdaptor();
+ CreateAdaptor(adaptorBuilder);
+
+ // adaptorBuilder invalidate after now.
+ AdaptorBuilder::Finalize();
if(mLaunchpadState == Launchpad::PRE_INITIALIZED)
{
DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_ADAPTOR_START");
mAdaptor->Start();
DALI_TRACE_END(gTraceFilter, "DALI_APP_ADAPTOR_START");
- Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
if(!mStylesheet.empty())
{
if(mUseUiThread)
{
delete mAdaptor;
- delete mAdaptorBuilder;
WindowSystem::Shutdown();
}
}
void Application::OnPause()
{
+ Accessibility::Bridge::GetCurrentBridge()->ApplicationPaused();
+
// A DALi app should handle Pause/Resume events.
// DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
// Pausing DALi core only occurs on the Window Hidden framework event
void Application::OnResume()
{
+ Accessibility::Bridge::GetCurrentBridge()->ApplicationResumed();
+
// Emit the signal first so the application can queue any messages before we do an update/render
// This ensures we do not just redraw the last frame before pausing if that's not required
Dali::Application application(this);
return SystemSettings::GetDataPath();
}
+void Application::FlushUpdateMessages()
+{
+ Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).FlushUpdateMessages();
+}
+
void Application::SetStyleSheet(const std::string& stylesheet)
{
mStylesheet = stylesheet;