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:
Hermet Park 2023-04-08 12:58:57 +09:00
parent 5112bdb805
commit afea40a947
3 changed files with 31 additions and 23 deletions

View file

@ -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)));

View file

@ -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)
{

View file

@ -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;