mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-25 07:39:02 +00:00
common taskscheduler: revert 4db25db962
There is a report of the thread sanitizer. It could be a false-positive as far as I reviewed, but we hate to be bothered by it. So let's revert it. @Issue: https://github.com/thorvg/thorvg/issues/1409
This commit is contained in:
parent
51a31e226d
commit
e8eef1af1d
2 changed files with 23 additions and 63 deletions
|
@ -173,8 +173,6 @@ struct SwShapeTask : SwTask
|
||||||
//Clip Path
|
//Clip Path
|
||||||
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
||||||
auto clipper = static_cast<SwTask*>(*clip);
|
auto clipper = static_cast<SwTask*>(*clip);
|
||||||
//Guarantee composition targets get ready.
|
|
||||||
clipper->done(tid);
|
|
||||||
//Clip shape rle
|
//Clip shape rle
|
||||||
if (shape.rle && !clipper->clip(shape.rle)) goto err;
|
if (shape.rle && !clipper->clip(shape.rle)) goto err;
|
||||||
//Clip stroke rle
|
//Clip stroke rle
|
||||||
|
@ -225,25 +223,17 @@ struct SwSceneTask : SwTask
|
||||||
if (!sceneRle) sceneRle = static_cast<SwRleData*>(calloc(1, sizeof(SwRleData)));
|
if (!sceneRle) sceneRle = static_cast<SwRleData*>(calloc(1, sizeof(SwRleData)));
|
||||||
else rleReset(sceneRle);
|
else rleReset(sceneRle);
|
||||||
|
|
||||||
//Only one shape
|
|
||||||
if (scene.count == 1) {
|
|
||||||
auto clipper = static_cast<SwTask*>(*scene.data);
|
|
||||||
clipper->done(tid);
|
|
||||||
//Merge shapes if it has more than one shapes
|
//Merge shapes if it has more than one shapes
|
||||||
} else {
|
if (scene.count > 1) {
|
||||||
//Merge first two clippers
|
//Merge first two clippers
|
||||||
auto clipper1 = static_cast<SwTask*>(*scene.data);
|
auto clipper1 = static_cast<SwTask*>(*scene.data);
|
||||||
clipper1->done(tid);
|
|
||||||
|
|
||||||
auto clipper2 = static_cast<SwTask*>(*(scene.data + 1));
|
auto clipper2 = static_cast<SwTask*>(*(scene.data + 1));
|
||||||
clipper2->done(tid);
|
|
||||||
|
|
||||||
rleMerge(sceneRle, clipper1->rle(), clipper2->rle());
|
rleMerge(sceneRle, clipper1->rle(), clipper2->rle());
|
||||||
|
|
||||||
//Unify the remained clippers
|
//Unify the remained clippers
|
||||||
for (auto rd = scene.data + 2; rd < (scene.data + scene.count); ++rd) {
|
for (auto rd = scene.data + 2; rd < (scene.data + scene.count); ++rd) {
|
||||||
auto clipper = static_cast<SwTask*>(*rd);
|
auto clipper = static_cast<SwTask*>(*rd);
|
||||||
clipper->done(tid);
|
|
||||||
rleMerge(sceneRle, sceneRle, clipper->rle());
|
rleMerge(sceneRle, sceneRle, clipper->rle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,8 +295,6 @@ struct SwImageTask : SwTask
|
||||||
imageDelOutline(&image, mpool, tid);
|
imageDelOutline(&image, mpool, tid);
|
||||||
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
||||||
auto clipper = static_cast<SwTask*>(*clip);
|
auto clipper = static_cast<SwTask*>(*clip);
|
||||||
//Guarantee composition targets get ready.
|
|
||||||
clipper->done(tid);
|
|
||||||
if (!clipper->clip(image.rle)) goto err;
|
if (!clipper->clip(image.rle)) goto err;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -697,6 +685,15 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
|
||||||
//Finish previous task if it has duplicated request.
|
//Finish previous task if it has duplicated request.
|
||||||
task->done();
|
task->done();
|
||||||
|
|
||||||
|
//TODO: Failed threading them. It would be better if it's possible.
|
||||||
|
//See: https://github.com/thorvg/thorvg/issues/1409
|
||||||
|
if (clips.count > 0) {
|
||||||
|
//Guarantee composition targets get ready.
|
||||||
|
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
|
||||||
|
static_cast<SwTask*>(*clip)->done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
task->clips = clips;
|
task->clips = clips;
|
||||||
|
|
||||||
if (transform) {
|
if (transform) {
|
||||||
|
|
|
@ -43,77 +43,40 @@ struct TaskScheduler
|
||||||
struct Task
|
struct Task
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
mutex finishedMtx;
|
mutex mtx;
|
||||||
mutex preparedMtx;
|
|
||||||
condition_variable cv;
|
condition_variable cv;
|
||||||
bool finished = true; //if run() finished
|
bool ready = true;
|
||||||
bool prepared = false; //the task is requested
|
bool pending = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Task()
|
virtual ~Task() = default;
|
||||||
{
|
|
||||||
if (!prepared) return;
|
|
||||||
|
|
||||||
//Guarantee the task is finished by TaskScheduler.
|
|
||||||
unique_lock<mutex> lock(preparedMtx);
|
|
||||||
|
|
||||||
while (prepared) {
|
|
||||||
cv.wait(lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void done(unsigned tid = 0)
|
void done(unsigned tid = 0)
|
||||||
{
|
{
|
||||||
if (finished) return;
|
if (!pending) return;
|
||||||
|
|
||||||
lock_guard<mutex> lock(finishedMtx);
|
unique_lock<mutex> lock(mtx);
|
||||||
|
while (!ready) cv.wait(lock);
|
||||||
if (finished) return;
|
pending = false;
|
||||||
|
|
||||||
//the job hasn't been launched yet.
|
|
||||||
|
|
||||||
//set finished so that operator() quickly returns.
|
|
||||||
finished = true;
|
|
||||||
|
|
||||||
run(tid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void run(unsigned tid) = 0;
|
virtual void run(unsigned tid) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void finish()
|
|
||||||
{
|
|
||||||
lock_guard<mutex> lock(preparedMtx);
|
|
||||||
prepared = false;
|
|
||||||
cv.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(unsigned tid)
|
void operator()(unsigned tid)
|
||||||
{
|
{
|
||||||
if (finished) {
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_guard<mutex> lock(finishedMtx);
|
|
||||||
|
|
||||||
if (finished) {
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
run(tid);
|
run(tid);
|
||||||
|
|
||||||
finished = true;
|
lock_guard<mutex> lock(mtx);
|
||||||
|
ready = true;
|
||||||
finish();
|
cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
{
|
{
|
||||||
finished = false;
|
ready = false;
|
||||||
prepared = true;
|
pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend struct TaskSchedulerImpl;
|
friend struct TaskSchedulerImpl;
|
||||||
|
|
Loading…
Add table
Reference in a new issue