[dali_2.3.28] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / application-impl.cpp
index 6590889..44d4146 100644 (file)
 #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>
@@ -64,16 +66,14 @@ DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_APPLICATION, true);
 ApplicationPtr Application::gPreInitializedApplication(NULL);
 
 ApplicationPtr Application::New(
-  int*                           argc,
-  char**                         argv[],
-  const std::string&             stylesheet,
-  Dali::Application::WINDOW_MODE windowMode,
-  const PositionSize&            positionSize,
-  Framework::Type                applicationType,
-  WindowType                     type,
-  bool                           useUiThread)
-{
-  ApplicationPtr application(new Application(argc, argv, stylesheet, windowMode, positionSize, applicationType, type, useUiThread));
+  int*               argc,
+  char**             argv[],
+  const std::string& stylesheet,
+  Framework::Type    applicationType,
+  bool               useUiThread,
+  const WindowData&  windowData)
+{
+  ApplicationPtr application(new Application(argc, argv, stylesheet, applicationType, useUiThread, windowData));
   return application;
 }
 
@@ -81,15 +81,43 @@ void Application::PreInitialize(int* argc, char** argv[])
 {
   if(!gPreInitializedApplication)
   {
-    Dali::TextAbstraction::FontClientPreInitialize();
+    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
 
-    gPreInitializedApplication                  = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL, WindowType::NORMAL, false);
+    Dali::TextAbstraction::FontClientPreInitialize();
+    WindowData 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, Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type, bool useUiThread)
+Application::Application(int* argc, char** argv[], const std::string& stylesheet, Framework::Type applicationType, bool useUiThread, const WindowData& windowData)
 : mInitSignal(),
   mTerminateSignal(),
   mPauseSignal(),
@@ -99,19 +127,23 @@ 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(windowMode),
+  mMainWindowMode(windowData.GetTransparency() ? WINDOW_MODE::TRANSPARENT : WINDOW_MODE::OPAQUE),
   mMainWindowName(),
+  mIsMainWindowFrontBufferRendering(windowData.GetFrontBufferRendering()),
   mStylesheet(stylesheet),
-  mWindowPositionSize(positionSize),
+  mWindowPositionSize(windowData.GetPositionSize()),
   mLaunchpadState(Launchpad::NONE),
-  mDefaultWindowType(type),
+  mDefaultWindowType(windowData.GetWindowType()),
   mUseUiThread(useUiThread),
-  mSlotDelegate(this)
+  mIsSystemInitialized(false),
+  mSlotDelegate(this),
+  mUIThreadLoader(nullptr)
 {
   // Set mName from command-line args
   if(argc && (*argc > 0))
@@ -125,11 +157,12 @@ Application::Application(int* argc, char** argv[], const std::string& stylesheet
     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()
@@ -142,12 +175,28 @@ 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)
@@ -155,6 +204,11 @@ void Application::StoreWindowPositionSize(PositionSize positionSize)
   mWindowPositionSize = positionSize;
 }
 
+void Application::StoreFrontBufferRendering(bool enable)
+{
+  mIsMainWindowFrontBufferRendering = enable;
+}
+
 void Application::ChangePreInitializedWindowInfo()
 {
   // Set window name
@@ -198,11 +252,23 @@ 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()
 {
   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)
   {
@@ -229,13 +295,15 @@ void Application::CreateWindow()
       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);
@@ -278,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()
@@ -301,6 +369,7 @@ void Application::OnInit()
   // 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();
   }
 
@@ -339,6 +408,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()
@@ -356,6 +428,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()
@@ -531,12 +612,17 @@ Dali::Window Application::GetWindow()
 
 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)