diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 6a1a8819..e589d618 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -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(*clip)->done(tid); + auto clipper = &static_cast(*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(*clip)->done(tid); + auto clipper = &static_cast(*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(*clip)->done(); - } - task->clips = clips; - } + if (clips.count > 0) task->clips = clips; if (transform) { if (!task->transform) task->transform = static_cast(malloc(sizeof(Matrix))); diff --git a/src/lib/tvgTaskScheduler.cpp b/src/lib/tvgTaskScheduler.cpp index 79e34a62..6b4b93c5 100644 --- a/src/lib/tvgTaskScheduler.cpp +++ b/src/lib/tvgTaskScheduler.cpp @@ -100,13 +100,12 @@ struct TaskQueue { }; -class TaskSchedulerImpl +struct TaskSchedulerImpl { -public: - unsigned threadCnt; + uint32_t threadCnt; vector threads; vector taskQueues; - atomic idx{0}; + uint32_t idx = 0; TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt) { diff --git a/src/lib/tvgTaskScheduler.h b/src/lib/tvgTaskScheduler.h index 7dd1dce8..8f60903f 100644 --- a/src/lib/tvgTaskScheduler.h +++ b/src/lib/tvgTaskScheduler.h @@ -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 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 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;