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()
|
bool SwRenderer::clear()
|
||||||
{
|
{
|
||||||
for (auto task : tasks) task->get();
|
for (auto task : tasks) task->done();
|
||||||
tasks.clear();
|
tasks.clear();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -181,7 +181,7 @@ bool SwRenderer::postRender()
|
||||||
bool SwRenderer::render(const Shape& shape, void *data)
|
bool SwRenderer::render(const Shape& shape, void *data)
|
||||||
{
|
{
|
||||||
auto task = static_cast<SwTask*>(data);
|
auto task = static_cast<SwTask*>(data);
|
||||||
task->get();
|
task->done();
|
||||||
|
|
||||||
uint8_t r, g, b, a;
|
uint8_t r, g, b, a;
|
||||||
if (auto fill = task->sdata->fill()) {
|
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);
|
auto task = static_cast<SwTask*>(data);
|
||||||
if (!task) return true;
|
if (!task) return true;
|
||||||
|
|
||||||
task->get();
|
task->done();
|
||||||
shapeFree(&task->shape);
|
shapeFree(&task->shape);
|
||||||
if (task->transform) free(task->transform);
|
if (task->transform) free(task->transform);
|
||||||
delete(task);
|
delete(task);
|
||||||
|
@ -226,13 +226,13 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
|
||||||
if (flags == RenderUpdateFlag::None) return task;
|
if (flags == RenderUpdateFlag::None) return task;
|
||||||
|
|
||||||
//Finish previous task if it has duplicated request.
|
//Finish previous task if it has duplicated request.
|
||||||
if (task->valid()) task->get();
|
task->done();
|
||||||
|
|
||||||
task->sdata = &sdata;
|
task->sdata = &sdata;
|
||||||
|
|
||||||
if (compList.size() > 0) {
|
if (compList.size() > 0) {
|
||||||
//Guarantee composition targets get ready.
|
//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());
|
task->compList.assign(compList.begin(), compList.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
#include "tvgTaskScheduler.h"
|
#include "tvgTaskScheduler.h"
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -179,7 +181,12 @@ void TaskScheduler::term()
|
||||||
|
|
||||||
void TaskScheduler::request(Task* task)
|
void TaskScheduler::request(Task* task)
|
||||||
{
|
{
|
||||||
if (inst) {
|
if (inst) inst->request(task);
|
||||||
inst->request(task);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned TaskScheduler::threads()
|
||||||
|
{
|
||||||
|
if (inst) return inst->threadCnt;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -22,31 +22,40 @@
|
||||||
#ifndef _TVG_TASK_SCHEDULER_H_
|
#ifndef _TVG_TASK_SCHEDULER_H_
|
||||||
#define _TVG_TASK_SCHEDULER_H_
|
#define _TVG_TASK_SCHEDULER_H_
|
||||||
|
|
||||||
#include <future>
|
#include <mutex>
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
|
|
||||||
namespace tvg
|
namespace tvg
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct Task;
|
||||||
|
|
||||||
|
struct TaskScheduler
|
||||||
|
{
|
||||||
|
static unsigned threads();
|
||||||
|
static void init(unsigned threads);
|
||||||
|
static void term();
|
||||||
|
static void request(Task* task);
|
||||||
|
};
|
||||||
|
|
||||||
struct Task
|
struct Task
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
promise<void> sender;
|
mutex mtx;
|
||||||
future<void> receiver;
|
bool working = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Task() = default;
|
virtual ~Task() = default;
|
||||||
|
|
||||||
void get()
|
void done()
|
||||||
{
|
{
|
||||||
if (receiver.valid()) {
|
if (!working) return;
|
||||||
receiver.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid()
|
if (TaskScheduler::threads() > 0) {
|
||||||
{
|
mtx.lock();
|
||||||
return receiver.valid();
|
working = false;
|
||||||
|
mtx.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -56,25 +65,23 @@ private:
|
||||||
void operator()(unsigned tid)
|
void operator()(unsigned tid)
|
||||||
{
|
{
|
||||||
run(tid);
|
run(tid);
|
||||||
sender.set_value();
|
|
||||||
|
if (TaskScheduler::threads() > 0) mtx.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
{
|
{
|
||||||
sender = promise<void>();
|
if (TaskScheduler::threads() > 0) {
|
||||||
receiver = sender.get_future();
|
working = true;
|
||||||
|
mtx.lock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class TaskSchedulerImpl;
|
friend class TaskSchedulerImpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TaskScheduler
|
|
||||||
{
|
|
||||||
static void init(unsigned threads);
|
|
||||||
static void term();
|
|
||||||
static void request(Task* task);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //_TVG_TASK_SCHEDULER_H_
|
#endif //_TVG_TASK_SCHEDULER_H_
|
||||||
|
|
|
@ -2518,7 +2518,7 @@ bool SvgLoader::read()
|
||||||
|
|
||||||
bool SvgLoader::close()
|
bool SvgLoader::close()
|
||||||
{
|
{
|
||||||
this->get();
|
this->done();
|
||||||
|
|
||||||
if (loaderData.svgParse) {
|
if (loaderData.svgParse) {
|
||||||
free(loaderData.svgParse);
|
free(loaderData.svgParse);
|
||||||
|
@ -2541,7 +2541,7 @@ bool SvgLoader::close()
|
||||||
|
|
||||||
unique_ptr<Scene> SvgLoader::data()
|
unique_ptr<Scene> SvgLoader::data()
|
||||||
{
|
{
|
||||||
this->get();
|
this->done();
|
||||||
if (root) return move(root);
|
if (root) return move(root);
|
||||||
else return nullptr;
|
else return nullptr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue