mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
common taskscheduler: increase thread efficiency.
Revise the logic to avoid potential blocking of the main thread. Move the clippers job completion to worker-threads to prevent main thread blocks and enhance maximum parallelization efficiency.
This commit is contained in:
parent
5112bdb805
commit
afea40a947
3 changed files with 31 additions and 23 deletions
|
@ -150,6 +150,9 @@ struct SwShapeTask : SwTask
|
|||
|
||||
//Clip Path
|
||||
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
||||
//Guarantee composition targets get ready.
|
||||
static_cast<SwShapeTask*>(*clip)->done(tid);
|
||||
|
||||
auto clipper = &static_cast<SwShapeTask*>(*clip)->shape;
|
||||
//Clip shape rle
|
||||
if (shape.rle) {
|
||||
|
@ -202,6 +205,9 @@ struct SwImageTask : SwTask
|
|||
if (!imageGenRle(&image, bbox, false)) goto end;
|
||||
if (image.rle) {
|
||||
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
||||
//Guarantee composition targets get ready.
|
||||
static_cast<SwShapeTask*>(*clip)->done(tid);
|
||||
|
||||
auto clipper = &static_cast<SwShapeTask*>(*clip)->shape;
|
||||
if (clipper->fastTrack) rleClipRect(image.rle, &clipper->bbox);
|
||||
else if (clipper->rle) rleClipPath(image.rle, clipper->rle);
|
||||
|
@ -590,13 +596,7 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
|
|||
//Finish previous task if it has duplicated request.
|
||||
task->done();
|
||||
|
||||
if (clips.count > 0) {
|
||||
//Guarantee composition targets get ready.
|
||||
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
||||
static_cast<SwShapeTask*>(*clip)->done();
|
||||
}
|
||||
task->clips = clips;
|
||||
}
|
||||
if (clips.count > 0) task->clips = clips;
|
||||
|
||||
if (transform) {
|
||||
if (!task->transform) task->transform = static_cast<Matrix*>(malloc(sizeof(Matrix)));
|
||||
|
|
|
@ -100,13 +100,12 @@ struct TaskQueue {
|
|||
};
|
||||
|
||||
|
||||
class TaskSchedulerImpl
|
||||
struct TaskSchedulerImpl
|
||||
{
|
||||
public:
|
||||
unsigned threadCnt;
|
||||
uint32_t threadCnt;
|
||||
vector<thread> threads;
|
||||
vector<TaskQueue> taskQueues;
|
||||
atomic<unsigned> idx{0};
|
||||
uint32_t idx = 0;
|
||||
|
||||
TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt)
|
||||
{
|
||||
|
|
|
@ -44,20 +44,25 @@ struct Task
|
|||
{
|
||||
private:
|
||||
mutex mtx;
|
||||
condition_variable cv;
|
||||
bool ready{true};
|
||||
bool pending{false};
|
||||
bool finished = true;
|
||||
bool running = false;
|
||||
|
||||
public:
|
||||
virtual ~Task() = default;
|
||||
|
||||
void done()
|
||||
void done(unsigned tid = 0)
|
||||
{
|
||||
if (!pending) return;
|
||||
if (finished) return;
|
||||
|
||||
unique_lock<mutex> lock(mtx);
|
||||
while (!ready) cv.wait(lock);
|
||||
pending = false;
|
||||
|
||||
if (finished) return;
|
||||
|
||||
//the job hasn't been launched yet.
|
||||
running = true;
|
||||
run(tid);
|
||||
running = false;
|
||||
finished = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -66,17 +71,21 @@ protected:
|
|||
private:
|
||||
void operator()(unsigned tid)
|
||||
{
|
||||
run(tid);
|
||||
if (finished || running) return;
|
||||
|
||||
lock_guard<mutex> lock(mtx);
|
||||
ready = true;
|
||||
cv.notify_one();
|
||||
|
||||
if (finished || running) return;
|
||||
|
||||
running = true;
|
||||
run(tid);
|
||||
running = false;
|
||||
finished = true;
|
||||
}
|
||||
|
||||
void prepare()
|
||||
{
|
||||
ready = false;
|
||||
pending = true;
|
||||
finished = false;
|
||||
}
|
||||
|
||||
friend class TaskSchedulerImpl;
|
||||
|
|
Loading…
Add table
Reference in a new issue