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
* @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.
* @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,
* 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
#include <dali/internal/text/text-abstraction/font-client-impl.h>
// EXTERNAL INCLUDES
+#include <condition_variable>
#include <mutex>
#include <thread>
#if defined(VCONF_ENABLED)
#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>
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
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)
{
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)
{
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);
}
}
/**
* @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()