[Tizen] Add font thread sync creation option 49/294749/1
authorBowon Ryu <bowon.ryu@samsung.com>
Wed, 24 May 2023 10:00:18 +0000 (19:00 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Mon, 26 Jun 2023 02:23:56 +0000 (11:23 +0900)
If sync creation is true, font thread creation guarantees syncronization with the main thread.

The main thread runs the font thread and waits,
and it wakes up upon receiving a notification from the font thread.
If it doesn't receive a notification within the specified time, it wakes up due to a timeout.

test security manager sync thread issue

Change-Id: I59ef4c189f0765cfd1c955704744c219784d238b
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
dali/devel-api/text-abstraction/font-client.cpp
dali/devel-api/text-abstraction/font-client.h
dali/internal/text/text-abstraction/font-client-impl.cpp
dali/internal/text/text-abstraction/font-client-impl.h

index 8899d5b..9b3c475 100644 (file)
@@ -859,14 +859,14 @@ FontClient FontClientPreInitialize()
   return Internal::FontClient::PreInitialize();
 }
 
-void FontClientPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread)
+void FontClientPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread, bool syncCreation)
 {
-  Internal::FontClient::PreCache(fallbackFamilyList, extraFamilyList, localeFamily, useThread);
+  Internal::FontClient::PreCache(fallbackFamilyList, extraFamilyList, localeFamily, useThread, syncCreation);
 }
 
-void FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread)
+void FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread, bool syncCreation)
 {
-  Internal::FontClient::PreLoad(fontPathList, memoryFontPathList, useThread);
+  Internal::FontClient::PreLoad(fontPathList, memoryFontPathList, useThread, syncCreation);
 }
 
 } // namespace TextAbstraction
index fd28e04..4123c25 100644 (file)
@@ -660,8 +660,9 @@ DALI_ADAPTOR_API FontClient FontClientPreInitialize();
  * @param[in] extraFamilyList A list of additional font families to be pre-cached.
  * @param[in] localeFamily A locale font family to be pre-cached.
  * @param[in] useThread True if the font client should create thread and perform pre-caching, false otherwise.
+ * @param[in] syncCreation True if thread creation guarantees syncronization with the main thread, false async creation.
  */
-DALI_ADAPTOR_API void FontClientPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread);
+DALI_ADAPTOR_API void FontClientPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread, bool syncCreation);
 
 /**
  * @brief This is used to pre-load FreeType font face in order to improve the runtime performance of the application.
@@ -669,6 +670,7 @@ DALI_ADAPTOR_API void FontClientPreCache(const FontFamilyList& fallbackFamilyLis
  * @param[in] fontPathList A list of font paths to be pre-loaded.
  * @param[in] memoryFontPathList A list of memory font paths to be pre-loaded.
  * @param[in] useThread True if the font client should create thread and perform font pre-loading, false otherwise.
+ * @param[in] syncCreation True if thread creation guarantees syncronization with the main thread, false async creation.
  *
  * @note
  * The fonts in the fontPathList perform FT_New_Face during pre-loading,
@@ -678,7 +680,7 @@ DALI_ADAPTOR_API void FontClientPreCache(const FontFamilyList& fallbackFamilyLis
  * This enables the use of FT_New_Memory_Face during runtime and provides a performance boost.
  * It requires memory equivalent to the size of each font file.
  */
-DALI_ADAPTOR_API void FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread);
+DALI_ADAPTOR_API void FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread, bool syncCreation);
 
 } // namespace TextAbstraction
 
index 1a0bd45..a9fb2f2 100644 (file)
@@ -19,6 +19,7 @@
 #include <dali/internal/text/text-abstraction/font-client-impl.h>
 
 // EXTERNAL INCLUDES
+#include <condition_variable>
 #include <mutex>
 #include <thread>
 #if defined(VCONF_ENABLED)
@@ -26,6 +27,7 @@
 #endif
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
 #include <dali/devel-api/common/singleton-service.h>
 #include <dali/internal/system/common/logging.h>
 #include <dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h>
@@ -59,6 +61,10 @@ Dali::TextAbstraction::FontClient FontClient::gPreCreatedFontClient(NULL);
 std::thread                       gPreCacheThread;
 std::thread                       gPreLoadThread;
 std::mutex                        gMutex;
+std::condition_variable           gPreCacheCond;
+std::condition_variable           gPreLoadCond;
+bool                              gPreCacheThreadReady;
+bool                              gPreLoadThreadReady;
 
 /* TODO: This is to prevent duplicate calls of font pre-cache.
  * We may support this later, but currently we can't guarantee the behaviour
@@ -157,21 +163,41 @@ Dali::TextAbstraction::FontClient FontClient::PreInitialize()
   return gPreCreatedFontClient;
 }
 
-void FontClient::PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
+void FontClient::PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool syncCreation)
 {
+  SetThreadName("FontThread-fc");
+
+  if(syncCreation)
+  {
+    std::unique_lock<std::mutex> lock(gMutex);
+    gPreCacheThreadReady = true;
+    gPreCacheCond.notify_one();
+    lock.unlock();
+  }
+
   FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_RUN\n");
   GetImplementation(gPreCreatedFontClient).FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
   FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_RUN\n");
 }
 
-void FontClient::PreLoadRun(const FontPathList& fontPathList, const FontPathList& memoryFontPathList)
+void FontClient::PreLoadRun(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool syncCreation)
 {
+  SetThreadName("FontThread-ft");
+
+  if(syncCreation)
+  {
+    std::unique_lock<std::mutex> lock(gMutex);
+    gPreLoadThreadReady = true;
+    gPreLoadCond.notify_one();
+    lock.unlock();
+  }
+
   FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_FONT_PRELOAD_RUN\n");
   GetImplementation(gPreCreatedFontClient).FontPreLoad(fontPathList, memoryFontPathList);
   FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_FONT_PRELOAD_RUN\n");
 }
 
-void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread)
+void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread, bool syncCreation)
 {
   if(!gFontPreCacheAvailable)
   {
@@ -198,15 +224,30 @@ void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFa
 
   if(useThread)
   {
-    gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily);
+    if(syncCreation)
+    {
+      // The main thread wakes up upon receiving a notification from the pre-cache thread.
+      // If it doesn't receive a notification within the specified time, it wakes up due to a timeout.
+      const std::chrono::milliseconds timeout(1000);
+      gPreCacheThreadReady = false;
+      std::unique_lock<std::mutex> lock(gMutex);
+      FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_THREAD_SYNC_CREATION\n");
+      gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily, syncCreation);
+      gPreCacheCond.wait_for(lock, timeout, []{return gPreCacheThreadReady;});
+      FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_THREAD_SYNC_CREATION\n");
+    }
+    else
+    {
+      gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily, syncCreation);
+    }
   }
   else
   {
-    PreCacheRun(fallbackFamilyList, extraFamilyList, localeFamily);
+    GetImplementation(gPreCreatedFontClient).FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
   }
 }
 
-void FontClient::PreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread)
+void FontClient::PreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread, bool syncCreation)
 {
   if(!gFontPreLoadAvailable)
   {
@@ -233,11 +274,26 @@ void FontClient::PreLoad(const FontPathList& fontPathList, const FontPathList& m
 
   if(useThread)
   {
-    gPreLoadThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList);
+    if(syncCreation)
+    {
+      // The main thread wakes up upon receiving a notification from the pre-load thread.
+      // If it doesn't receive a notification within the specified time, it wakes up due to a timeout.
+      const std::chrono::milliseconds timeout(1000);
+      gPreLoadThreadReady = false;
+      std::unique_lock<std::mutex> lock(gMutex);
+      FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_FONT_PRELOAD_THREAD_SYNC_CREATION\n");
+      gPreLoadThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList, syncCreation);
+      gPreLoadCond.wait_for(lock, timeout, []{return gPreLoadThreadReady;});
+      FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_FONT_PRELOAD_THREAD_SYNC_CREATION\n");
+    }
+    else
+    {
+      gPreLoadThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList, syncCreation);
+    }
   }
   else
   {
-    PreLoadRun(fontPathList, memoryFontPathList);
+    GetImplementation(gPreCreatedFontClient).FontPreLoad(fontPathList, memoryFontPathList);
   }
 }
 
index d0f7494..9f69794 100644 (file)
@@ -66,26 +66,26 @@ public: // API for Dali::TextAbstraction::FontClient used.
   /**
    * @brief This is used to pre-cache FontConfig in order to improve the runtime performance of the application.
    *
-   * @see Dali::TextAbstraction::FontClientPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread);
+   * @see Dali::TextAbstraction::FontClientPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread, bool syncCreation);
    */
-  static void PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread);
+  static void PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread, bool syncCreation);
 
   /**
    * @brief This is used to creates a global font client and pre-caches the FontConfig.
    */
-  static void PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily);
+  static void PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool syncCreation);
 
   /**
    * @brief This is used to pre-load FreeType font face in order to improve the runtime performance of the application.
    *
-   * @see Dali::TextAbstraction:FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread);
+   * @see Dali::TextAbstraction:FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread, bool syncCreation);
    */
-  static void PreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread);
+  static void PreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread, bool syncCreation);
 
   /**
    * @brief This is used to creates a global font client and pre-loads the FreeType font face.
    */
-  static void PreLoadRun(const FontPathList& fontPathList, const FontPathList& memoryFontPathList);
+  static void PreLoadRun(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool syncCreation);
 
   /**
    * @copydoc Dali::TextAbstraction::FontClient::ClearCache()