/*
- * 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.
mWorkingTasks(),
mSleepThread(MakeCallback(this, &VectorAnimationThread::OnAwakeFromSleep)),
mConditionalWait(),
+ mEventTriggerMutex(),
+ mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
+ mTraceFactory(Dali::Adaptor::Get().GetTraceFactory()),
mNeedToSleep(false),
mDestroyThread(false),
- mLogFactory(Dali::Adaptor::Get().GetLogFactory())
+ mEventTriggered(false),
+ mForceRenderOnce(false)
{
mAsyncTaskManager = Dali::AsyncTaskManager::Get();
mSleepThread.Start();
// Stop the thread
{
ConditionalWait::ScopedLock lock(mConditionalWait);
- mDestroyThread = true;
- mNeedToSleep = false;
+ // Wait until some event thread trigger relative job finished.
+ {
+ Mutex::ScopedLock lock(mEventTriggerMutex);
+ mDestroyThread = true;
+ }
+ mNeedToSleep = false;
mConditionalWait.Notify(lock);
}
+ // Stop event trigger
+ mEventTrigger.reset();
+
DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationThread::~VectorAnimationThread: Join [%p]\n", this);
Join();
}
}
-void VectorAnimationThread::AddEventTriggerCallback(CallbackBase* callback)
+void VectorAnimationThread::AddEventTriggerCallback(CallbackBase* callback, uint32_t argument)
{
- ConditionalWait::ScopedLock lock(mConditionalWait);
- mTriggerEventCallbacks.push_back(callback);
+ Mutex::ScopedLock lock(mEventTriggerMutex);
+ if(!mDestroyThread)
+ {
+ mTriggerEventCallbacks.emplace_back(callback, argument);
+
+ if(!mEventTriggered)
+ {
+ mEventTrigger->Trigger();
+ mEventTriggered = true;
+ }
+ }
+}
- if(!mEventTriggered)
+void VectorAnimationThread::RemoveEventTriggerCallbacks(CallbackBase* callback)
+{
+ Mutex::ScopedLock lock(mEventTriggerMutex);
+ if(!mDestroyThread)
{
- mEventTrigger->Trigger();
- mEventTriggered = true;
+ auto iter = std::remove_if(mTriggerEventCallbacks.begin(), mTriggerEventCallbacks.end(), [&callback](std::pair<CallbackBase*, uint32_t>& item) { return item.first == callback; });
+ mTriggerEventCallbacks.erase(iter, mTriggerEventCallbacks.end());
}
}
-void VectorAnimationThread::RemoveEventTriggerCallback(CallbackBase* callback)
+void VectorAnimationThread::RequestForceRenderOnce()
{
- ConditionalWait::ScopedLock lock(mConditionalWait);
- auto iter = std::find(mTriggerEventCallbacks.begin(), mTriggerEventCallbacks.end(), callback);
- if(iter != mTriggerEventCallbacks.end())
+ Mutex::ScopedLock lock(mEventTriggerMutex);
+ if(!mDestroyThread)
{
- mTriggerEventCallbacks.erase(iter);
+ mForceRenderOnce = true;
+
+ if(!mEventTriggered)
+ {
+ mEventTrigger->Trigger();
+ mEventTriggered = true;
+ }
}
}
{
SetThreadName("VectorAnimationThread");
mLogFactory.InstallLogFunction();
+ mTraceFactory.InstallTraceFunction();
while(!mDestroyThread)
{
void VectorAnimationThread::OnEventCallbackTriggered()
{
- ConditionalWait::ScopedLock lock(mConditionalWait);
-
- for(auto&& iter : mTriggerEventCallbacks)
+ while(true)
{
- CallbackBase::Execute(*iter);
+ auto callbackPair = GetNextEventCallback();
+ if(callbackPair.first == nullptr)
+ {
+ break;
+ }
+ CallbackBase::Execute(*callbackPair.first, callbackPair.second);
}
+ // Request update once if we need.
+ {
+ Mutex::ScopedLock lock(mEventTriggerMutex);
+ if(!mDestroyThread && mForceRenderOnce)
+ {
+ mForceRenderOnce = false;
+ if(Dali::Adaptor::IsAvailable())
+ {
+ Dali::Adaptor::Get().UpdateOnce();
+ }
+ }
+ }
+}
- mTriggerEventCallbacks.clear();
- mEventTriggered = false;
+std::pair<CallbackBase*, uint32_t> VectorAnimationThread::GetNextEventCallback()
+{
+ Mutex::ScopedLock lock(mEventTriggerMutex);
+ if(!mDestroyThread)
+ {
+ if(!mTriggerEventCallbacks.empty())
+ {
+ auto iter = mTriggerEventCallbacks.begin();
+ auto callbackIdPair = *iter;
+ mTriggerEventCallbacks.erase(iter);
+ return callbackIdPair;
+ }
+ mEventTriggered = false;
+ }
+ return std::make_pair(nullptr, 0u);
}
VectorAnimationThread::SleepThread::SleepThread(CallbackBase* callback)
mAwakeCallback(std::unique_ptr<CallbackBase>(callback)),
mSleepTimePoint(),
mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
+ mTraceFactory(Dali::Adaptor::Get().GetTraceFactory()),
mNeedToSleep(false),
mDestroyThread(false)
{
{
SetThreadName("VectorSleepThread");
mLogFactory.InstallLogFunction();
+ mTraceFactory.InstallTraceFunction();
while(!mDestroyThread)
{