From: Bowon Ryu Date: Wed, 24 May 2023 10:00:18 +0000 (+0900) Subject: Add font thread sync creation option X-Git-Tag: dali_2.2.29~6^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git;a=commitdiff_plain;h=ebc94ea7bb5f7c8ca2d57da4b1dcf3ec16aea852 Add font thread sync creation option 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 --- diff --git a/dali/devel-api/text-abstraction/font-client.cpp b/dali/devel-api/text-abstraction/font-client.cpp index 5d9f175..5008e57 100644 --- a/dali/devel-api/text-abstraction/font-client.cpp +++ b/dali/devel-api/text-abstraction/font-client.cpp @@ -304,14 +304,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 diff --git a/dali/devel-api/text-abstraction/font-client.h b/dali/devel-api/text-abstraction/font-client.h index 3d6a2a1..7a88e0a 100644 --- a/dali/devel-api/text-abstraction/font-client.h +++ b/dali/devel-api/text-abstraction/font-client.h @@ -577,8 +577,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. @@ -586,6 +587,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, @@ -595,7 +597,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 diff --git a/dali/internal/text/text-abstraction/font-client-impl.cpp b/dali/internal/text/text-abstraction/font-client-impl.cpp index 0c1f78c..e8fd123 100644 --- a/dali/internal/text/text-abstraction/font-client-impl.cpp +++ b/dali/internal/text/text-abstraction/font-client-impl.cpp @@ -19,6 +19,7 @@ #include // EXTERNAL INCLUDES +#include #include #include #if defined(VCONF_ENABLED) @@ -26,6 +27,7 @@ #endif // INTERNAL INCLUDES +#include #include #include #include @@ -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 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 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 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 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); } } diff --git a/dali/internal/text/text-abstraction/font-client-impl.h b/dali/internal/text/text-abstraction/font-client-impl.h index 5ad3a79..79e1ab9 100644 --- a/dali/internal/text/text-abstraction/font-client-impl.h +++ b/dali/internal/text/text-abstraction/font-client-impl.h @@ -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()