#include <dali/devel-api/atspi-interfaces/accessible.h>
#include <dali/devel-api/text-abstraction/font-client.h>
#include <dali/internal/adaptor/common/adaptor-impl.h>
+#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/system/common/command-line-options.h>
#include <dali/internal/system/common/environment-variables.h>
+#include <dali/internal/system/common/system-settings.h>
#include <dali/internal/window-system/common/render-surface-factory.h>
#include <dali/internal/window-system/common/window-impl.h>
#include <dali/internal/window-system/common/window-render-surface.h>
const std::string& stylesheet,
Framework::Type applicationType,
bool useUiThread,
- WindowData& windowData)
+ const WindowData& windowData)
{
ApplicationPtr application(new Application(argc, argv, stylesheet, applicationType, useUiThread, windowData));
return application;
{
if(!gPreInitializedApplication)
{
+ bool isUseUIThread = false;
+
+#ifdef UI_THREAD_AVAILABLE
+ char* retEnv = std::getenv("TIZEN_UI_THREAD");
+ 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");
+ gPreInitializedApplication->mUIThreadLoader = new UIThreadLoader(argc, argv);
+ gPreInitializedApplication->mUIThreadLoader->Run([&]() { gPreInitializedApplication->CreateWindow(); });
+ }
+ else
+#endif
+ {
+ DALI_LOG_RELEASE_INFO("Only PRE_INITIALIZED");
+ gPreInitializedApplication->CreateWindow(); // Only create window
+ }
}
}
-Application::Application(int* argc, char** argv[], const std::string& stylesheet, Framework::Type applicationType, bool useUiThread, WindowData& windowData)
+Application::Application(int* argc, char** argv[], const std::string& stylesheet, Framework::Type applicationType, bool useUiThread, const WindowData& windowData)
: mInitSignal(),
mTerminateSignal(),
mPauseSignal(),
mLanguageChangedSignal(),
mRegionChangedSignal(),
mFramework(nullptr),
+ mFrameworkFactory(nullptr),
mCommandLineOptions(nullptr),
mAdaptorBuilder(nullptr),
mAdaptor(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))
mUseUiThread = true;
}
- WindowSystem::Initialize();
-
mCommandLineOptions = new CommandLineOptions(argc, argv);
- mFramework = new Framework(*this, *this, argc, argv, applicationType, mUseUiThread);
- mUseRemoteSurface = (applicationType == Framework::WATCH);
+
+ mFrameworkFactory = std::unique_ptr<FrameworkFactory>(Dali::Internal::Adaptor::CreateFrameworkFactory());
+ mFramework = mFrameworkFactory->CreateFramework(FrameworkBackend::DEFAULT, *this, *this, argc, argv, applicationType, mUseUiThread);
+
+ mUseRemoteSurface = (applicationType == Framework::WATCH);
}
Application::~Application()
}
mMainWindow.Reset();
- delete mAdaptor;
- delete mAdaptorBuilder;
+
delete mCommandLineOptions;
- delete mFramework;
- WindowSystem::Shutdown();
+ // Application is created in Main thread whether UI Threading is enabled or not.
+ // But some resources are created in Main thread or UI thread.
+ // The below code is for the resource are created in Main thread.
+ if(!mUseUiThread)
+ {
+ delete mAdaptor;
+ delete mAdaptorBuilder;
+ if(mIsSystemInitialized)
+ {
+ WindowSystem::Shutdown();
+ }
+ }
+ else
+ {
+ if(mUIThreadLoader)
+ {
+ delete mUIThreadLoader;
+ }
+ }
}
void Application::StoreWindowPositionSize(PositionSize positionSize)
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()
{
Internal::Adaptor::Window* window;
+ WindowData windowData;
+ windowData.SetTransparency(mMainWindowMode);
+ windowData.SetWindowType(mDefaultWindowType);
+ windowData.SetFrontBufferRendering(mIsMainWindowFrontBufferRendering);
+
+ DALI_LOG_RELEASE_INFO("Create Default Window");
+
+ WindowSystem::Initialize();
+ mIsSystemInitialized = true;
if(mLaunchpadState != Launchpad::PRE_INITIALIZED)
{
mMainWindowName = windowName;
}
- window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
+ windowData.SetPositionSize(mWindowPositionSize);
+ window = Internal::Adaptor::Window::New(mMainWindowName, windowClassName, windowData);
}
else
{
- // The position, size and the window name of the pre-initialized application will be updated in ChangePreInitializedWindowInfo()
- // when the real application is launched.
- window = Internal::Adaptor::Window::New(mWindowPositionSize, "", "", mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
+ // 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);
}
mMainWindow = Dali::Window(window);
// 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");
CreateWindow();
}
DALI_TRACE_END(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
mAdaptor->NotifySceneCreated();
+
+ // Ensure the join of Font thread at this point
+ Dali::TextAbstraction::FontClientJoinFontThreads();
}
void Application::OnTerminate()
}
mMainWindow.Reset(); // This only resets (clears) the default Window
+
+ // If DALi's UI Thread works, some resources are created in UI Thread, not Main thread.
+ // For that case, these resource should be deleted in UI Thread.
+ if(mUseUiThread)
+ {
+ delete mAdaptor;
+ delete mAdaptorBuilder;
+ WindowSystem::Shutdown();
+ }
}
void Application::OnPause()
std::string Application::GetResourcePath()
{
- return Internal::Adaptor::Framework::GetResourcePath();
+ return SystemSettings::GetResourcePath();
}
std::string Application::GetDataPath()
{
- return Internal::Adaptor::Framework::GetDataPath();
+ return SystemSettings::GetDataPath();
+}
+
+void Application::FlushUpdateMessages()
+{
+ Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).FlushUpdateMessages();
}
void Application::SetStyleSheet(const std::string& stylesheet)