mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-23 14:48:24 +00:00
common taskScheduler: thread sync optmization
replaced future/promise with mutex since they use a lot of memory allocation number. plus, binary size is reduced from 2094896 -> 1746864
This commit is contained in:
parent
e445b7f579
commit
9872cf066d
4 changed files with 45 additions and 31 deletions
|
@ -139,7 +139,7 @@ SwRenderer::~SwRenderer()
|
|||
|
||||
bool SwRenderer::clear()
|
||||
{
|
||||
for (auto task : tasks) task->get();
|
||||
for (auto task : tasks) task->done();
|
||||
tasks.clear();
|
||||
|
||||
return true;
|
||||
|
@ -181,7 +181,7 @@ bool SwRenderer::postRender()
|
|||
bool SwRenderer::render(const Shape& shape, void *data)
|
||||
{
|
||||
auto task = static_cast<SwTask*>(data);
|
||||
task->get();
|
||||
task->done();
|
||||
|
||||
uint8_t r, g, b, a;
|
||||
if (auto fill = task->sdata->fill()) {
|
||||
|
@ -205,7 +205,7 @@ bool SwRenderer::dispose(TVG_UNUSED const Shape& sdata, void *data)
|
|||
auto task = static_cast<SwTask*>(data);
|
||||
if (!task) return true;
|
||||
|
||||
task->get();
|
||||
task->done();
|
||||
shapeFree(&task->shape);
|
||||
if (task->transform) free(task->transform);
|
||||
delete(task);
|
||||
|
@ -226,13 +226,13 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
|
|||
if (flags == RenderUpdateFlag::None) return task;
|
||||
|
||||
//Finish previous task if it has duplicated request.
|
||||
if (task->valid()) task->get();
|
||||
task->done();
|
||||
|
||||
task->sdata = &sdata;
|
||||
|
||||
if (compList.size() > 0) {
|
||||
//Guarantee composition targets get ready.
|
||||
for (auto comp : compList) static_cast<SwTask*>(comp.edata)->get();
|
||||
for (auto comp : compList) static_cast<SwTask*>(comp.edata)->done();
|
||||
task->compList.assign(compList.begin(), compList.end());
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <deque>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include "tvgTaskScheduler.h"
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -179,7 +181,12 @@ void TaskScheduler::term()
|
|||
|
||||
void TaskScheduler::request(Task* task)
|
||||
{
|
||||
if (inst) {
|
||||
inst->request(task);
|
||||
}
|
||||
if (inst) inst->request(task);
|
||||
}
|
||||
|
||||
|
||||
unsigned TaskScheduler::threads()
|
||||
{
|
||||
if (inst) return inst->threadCnt;
|
||||
return 0;
|
||||
}
|
|
@ -22,31 +22,40 @@
|
|||
#ifndef _TVG_TASK_SCHEDULER_H_
|
||||
#define _TVG_TASK_SCHEDULER_H_
|
||||
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
#include "tvgCommon.h"
|
||||
|
||||
namespace tvg
|
||||
{
|
||||
|
||||
struct Task;
|
||||
|
||||
struct TaskScheduler
|
||||
{
|
||||
static unsigned threads();
|
||||
static void init(unsigned threads);
|
||||
static void term();
|
||||
static void request(Task* task);
|
||||
};
|
||||
|
||||
struct Task
|
||||
{
|
||||
private:
|
||||
promise<void> sender;
|
||||
future<void> receiver;
|
||||
mutex mtx;
|
||||
bool working = false;
|
||||
|
||||
public:
|
||||
virtual ~Task() = default;
|
||||
|
||||
void get()
|
||||
void done()
|
||||
{
|
||||
if (receiver.valid()) {
|
||||
receiver.get();
|
||||
}
|
||||
}
|
||||
if (!working) return;
|
||||
|
||||
bool valid()
|
||||
{
|
||||
return receiver.valid();
|
||||
if (TaskScheduler::threads() > 0) {
|
||||
mtx.lock();
|
||||
working = false;
|
||||
mtx.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -56,24 +65,22 @@ private:
|
|||
void operator()(unsigned tid)
|
||||
{
|
||||
run(tid);
|
||||
sender.set_value();
|
||||
|
||||
if (TaskScheduler::threads() > 0) mtx.unlock();
|
||||
}
|
||||
|
||||
void prepare()
|
||||
{
|
||||
sender = promise<void>();
|
||||
receiver = sender.get_future();
|
||||
if (TaskScheduler::threads() > 0) {
|
||||
working = true;
|
||||
mtx.lock();
|
||||
}
|
||||
}
|
||||
|
||||
friend class TaskSchedulerImpl;
|
||||
};
|
||||
|
||||
struct TaskScheduler
|
||||
{
|
||||
static void init(unsigned threads);
|
||||
static void term();
|
||||
static void request(Task* task);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2518,7 +2518,7 @@ bool SvgLoader::read()
|
|||
|
||||
bool SvgLoader::close()
|
||||
{
|
||||
this->get();
|
||||
this->done();
|
||||
|
||||
if (loaderData.svgParse) {
|
||||
free(loaderData.svgParse);
|
||||
|
@ -2541,7 +2541,7 @@ bool SvgLoader::close()
|
|||
|
||||
unique_ptr<Scene> SvgLoader::data()
|
||||
{
|
||||
this->get();
|
||||
this->done();
|
||||
if (root) return move(root);
|
||||
else return nullptr;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue