[dali_2.3.42] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / application-impl.cpp
index 3efd7a5..41c8f64 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -34,6 +34,7 @@
 #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>
@@ -61,7 +62,13 @@ namespace Internal
 {
 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);
 
@@ -81,11 +88,39 @@ void Application::PreInitialize(int* argc, char** argv[])
 {
   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
+    }
   }
 }
 
@@ -99,19 +134,22 @@ Application::Application(int* argc, char** argv[], const std::string& stylesheet
   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))
@@ -126,7 +164,9 @@ Application::Application(int* argc, char** argv[], const std::string& stylesheet
   }
 
   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);
 }
@@ -150,8 +190,17 @@ Application::~Application()
   if(!mUseUiThread)
   {
     delete mAdaptor;
-    delete mAdaptorBuilder;
-    WindowSystem::Shutdown();
+    if(mIsSystemInitialized)
+    {
+      WindowSystem::Shutdown();
+    }
+  }
+  else
+  {
+    if(mUIThreadLoader)
+    {
+      delete mUIThreadLoader;
+    }
   }
 }
 
@@ -160,6 +209,11 @@ void Application::StoreWindowPositionSize(PositionSize positionSize)
   mWindowPositionSize = positionSize;
 }
 
+void Application::StoreFrontBufferRendering(bool enable)
+{
+  mIsMainWindowFrontBufferRendering = enable;
+}
+
 void Application::ChangePreInitializedWindowInfo()
 {
   // Set window name
@@ -203,6 +257,9 @@ void Application::ChangePreInitializedWindowInfo()
     mWindowPositionSize.height = screenHeight;
     mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
   }
+
+  // Set front buffer rendering
+  Dali::DevelWindow::SetFrontBufferRendering(mMainWindow, mIsMainWindowFrontBufferRendering);
 }
 
 void Application::CreateWindow()
@@ -211,8 +268,12 @@ 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)
   {
@@ -244,8 +305,8 @@ void Application::CreateWindow()
   }
   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);
   }
@@ -256,11 +317,11 @@ void Application::CreateWindow()
   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));
 
@@ -269,11 +330,6 @@ void Application::CreateAdaptor()
   Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
 }
 
-void Application::CreateAdaptorBuilder()
-{
-  mAdaptorBuilder = new AdaptorBuilder(*mEnvironmentOptions);
-}
-
 void Application::MainLoop()
 {
   // Run the application
@@ -290,7 +346,7 @@ void Application::Quit()
 {
   // 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()
@@ -309,14 +365,18 @@ void Application::OnInit()
 
   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)
   {
@@ -327,7 +387,6 @@ void Application::OnInit()
   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())
   {
@@ -377,13 +436,14 @@ void Application::OnTerminate()
   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
@@ -393,6 +453,8 @@ void Application::OnPause()
 
 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);
@@ -563,6 +625,11 @@ std::string Application::GetDataPath()
   return SystemSettings::GetDataPath();
 }
 
+void Application::FlushUpdateMessages()
+{
+  Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).FlushUpdateMessages();
+}
+
 void Application::SetStyleSheet(const std::string& stylesheet)
 {
   mStylesheet = stylesheet;