Ensure join of font thread
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / application-impl.cpp
index c44318e..5fb0f6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -83,9 +83,9 @@ void Application::PreInitialize(int* argc, char** argv[])
   {
     Dali::TextAbstraction::FontClientPreInitialize();
 
-    gPreInitializedApplication = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL, WindowType::NORMAL, false);
-    gPreInitializedApplication->CreateWindow(); // Only create window
+    gPreInitializedApplication                  = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL, WindowType::NORMAL, false);
     gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
+    gPreInitializedApplication->CreateWindow(); // Only create window
   }
 }
 
@@ -98,27 +98,24 @@ Application::Application(int* argc, char** argv[], const std::string& stylesheet
   mAppControlSignal(),
   mLanguageChangedSignal(),
   mRegionChangedSignal(),
-  mEventLoop(nullptr),
   mFramework(nullptr),
   mCommandLineOptions(nullptr),
   mAdaptorBuilder(nullptr),
   mAdaptor(nullptr),
+  mEnvironmentOptions(nullptr),
   mMainWindow(),
   mMainWindowMode(windowMode),
   mMainWindowName(),
   mStylesheet(stylesheet),
-  mEnvironmentOptions(),
   mWindowPositionSize(positionSize),
   mLaunchpadState(Launchpad::NONE),
   mDefaultWindowType(type),
   mUseUiThread(useUiThread),
   mSlotDelegate(this)
 {
-  // Get mName from environment options
-  mMainWindowName = mEnvironmentOptions.GetWindowName();
-  if(mMainWindowName.empty() && argc && (*argc > 0))
+  // Set mName from command-line args
+  if(argc && (*argc > 0))
   {
-    // Set mName from command-line args if environment option not set
     mMainWindowName = (*argv)[0];
   }
 
@@ -143,10 +140,19 @@ Application::~Application()
   }
 
   mMainWindow.Reset();
-  delete mAdaptor;
-  delete mAdaptorBuilder;
+
   delete mCommandLineOptions;
   delete mFramework;
+
+  // 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;
+    WindowSystem::Shutdown();
+  }
 }
 
 void Application::StoreWindowPositionSize(PositionSize positionSize)
@@ -154,14 +160,24 @@ void Application::StoreWindowPositionSize(PositionSize positionSize)
   mWindowPositionSize = positionSize;
 }
 
-void Application::ChangePreInitializedWindowSize()
+void Application::ChangePreInitializedWindowInfo()
 {
+  // Set window name
+  auto windowClassName = mEnvironmentOptions->GetWindowClassName();
+  auto windowName      = mEnvironmentOptions->GetWindowName();
+  if(!windowName.empty())
+  {
+    mMainWindowName = windowName;
+  }
+  mMainWindow.SetClass(mMainWindowName, windowClassName);
+
   // The real screen size may be different from the value of the preinitialized state. Update it.
   Dali::Internal::Adaptor::WindowSystem::UpdateScreenSize();
 
   int screenWidth, screenHeight;
   Dali::Internal::Adaptor::WindowSystem::GetScreenSize(screenWidth, screenHeight);
 
+  // Set window position / size
   if(mWindowPositionSize != PositionSize(0, 0, 0, 0))
   {
     Dali::DevelWindow::SetPositionSize(mMainWindow, mWindowPositionSize);
@@ -173,11 +189,11 @@ void Application::ChangePreInitializedWindowSize()
     mWindowPositionSize.height = mCommandLineOptions->stageHeight;
     mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
   }
-  else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
+  else if(mEnvironmentOptions->GetWindowWidth() && mEnvironmentOptions->GetWindowHeight())
   {
     // Environment options override full screen functionality if command line arguments not provided
-    mWindowPositionSize.width  = mEnvironmentOptions.GetWindowWidth();
-    mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
+    mWindowPositionSize.width  = mEnvironmentOptions->GetWindowWidth();
+    mWindowPositionSize.height = mEnvironmentOptions->GetWindowHeight();
     mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
   }
   else if(screenWidth != mWindowPositionSize.width || screenHeight != mWindowPositionSize.height)
@@ -191,26 +207,45 @@ void Application::ChangePreInitializedWindowSize()
 
 void Application::CreateWindow()
 {
-  if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
+  Internal::Adaptor::Window* window;
+
+  WindowSystem::Initialize();
+
+  if(mLaunchpadState != Launchpad::PRE_INITIALIZED)
   {
-    if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
+    if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
     {
-      // Command line options override environment options and full screen
-      mWindowPositionSize.width  = mCommandLineOptions->stageWidth;
-      mWindowPositionSize.height = mCommandLineOptions->stageHeight;
+      if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
+      {
+        // Command line options override environment options and full screen
+        mWindowPositionSize.width  = mCommandLineOptions->stageWidth;
+        mWindowPositionSize.height = mCommandLineOptions->stageHeight;
+      }
+      else if(mEnvironmentOptions->GetWindowWidth() && mEnvironmentOptions->GetWindowHeight())
+      {
+        // Environment options override full screen functionality if command line arguments not provided
+        mWindowPositionSize.width  = mEnvironmentOptions->GetWindowWidth();
+        mWindowPositionSize.height = mEnvironmentOptions->GetWindowHeight();
+      }
     }
-    else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
+
+    auto windowClassName = mEnvironmentOptions->GetWindowClassName();
+    auto windowName      = mEnvironmentOptions->GetWindowName();
+    if(!windowName.empty())
     {
-      // Environment options override full screen functionality if command line arguments not provided
-      mWindowPositionSize.width  = mEnvironmentOptions.GetWindowWidth();
-      mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
+      mMainWindowName = windowName;
     }
-  }
 
-  const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
+    window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
+  }
+  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);
+  }
 
-  Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
-  mMainWindow                       = Dali::Window(window);
+  mMainWindow = Dali::Window(window);
 
   // Quit the application when the window is closed
   GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
@@ -224,14 +259,14 @@ void Application::CreateAdaptor()
 
   Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
 
-  mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, &mEnvironmentOptions);
+  mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, mEnvironmentOptions.get());
 
   Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
 }
 
 void Application::CreateAdaptorBuilder()
 {
-  mAdaptorBuilder = new AdaptorBuilder(mEnvironmentOptions);
+  mAdaptorBuilder = new AdaptorBuilder(*mEnvironmentOptions);
 }
 
 void Application::MainLoop()
@@ -265,6 +300,8 @@ void Application::QuitFromMainLoop()
 
 void Application::OnInit()
 {
+  mEnvironmentOptions = std::unique_ptr<EnvironmentOptions>(new EnvironmentOptions());
+
   mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
 
   CreateAdaptorBuilder();
@@ -278,7 +315,7 @@ void Application::OnInit()
 
   if(mLaunchpadState == Launchpad::PRE_INITIALIZED)
   {
-    ChangePreInitializedWindowSize();
+    ChangePreInitializedWindowInfo();
   }
 
   // Run the adaptor
@@ -309,6 +346,9 @@ void Application::OnInit()
   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()
@@ -326,6 +366,15 @@ 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()
@@ -521,6 +570,12 @@ void Application::SetCommandLineOptions(int* argc, char** argv[])
   mCommandLineOptions = new CommandLineOptions(argc, argv);
 
   mFramework->SetCommandLineOptions(argc, argv);
+
+  if(argc && (*argc > 0))
+  {
+    // Set mName from command-line args
+    mMainWindowName = (*argv)[0];
+  }
 }
 
 void Application::SetDefaultWindowType(WindowType type)
@@ -529,6 +584,15 @@ void Application::SetDefaultWindowType(WindowType type)
   mMainWindow.SetType(type);
 }
 
+int32_t Application::GetRenderThreadId() const
+{
+  if(mAdaptor)
+  {
+    return Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).GetRenderThreadId();
+  }
+  return 0;
+}
+
 ApplicationPtr Application::GetPreInitializedApplication()
 {
   // Reset the handle to decrease the reference count