From 39118e21c4c0cb8ef50e0937a05d7b9324613a96 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Tue, 4 Dec 2018 10:07:34 +0900 Subject: [PATCH] lottie: Refactor task queue to accept move only task object instead of pointer to task object. Change-Id: Iaa94efcef94fd128681fd45efa91f6e5340f85a6 --- src/lottie/lottieanimation.cpp | 34 ++++++++++---------- src/vector/vraster.cpp | 58 +++++++++++++++++++--------------- src/vector/vtaskqueue.h | 19 +++++------ 3 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/lottie/lottieanimation.cpp b/src/lottie/lottieanimation.cpp index 7fdb861..831bb8e 100644 --- a/src/lottie/lottieanimation.cpp +++ b/src/lottie/lottieanimation.cpp @@ -114,17 +114,19 @@ class RenderTaskScheduler { void run(unsigned i) { + RenderTask task; while (true) { - RenderTask *task = nullptr; - + bool success = false; for (unsigned n = 0; n != _count * 32; ++n) { - if (_q[(i + n) % _count].try_pop(task)) break; + if (_q[(i + n) % _count].try_pop(task)) { + success = true; + break; + } } - if (!task && !_q[i].pop(task)) break; + if (!success && !_q[i].pop(task)) break; - auto result = task->playerImpl->render(task->frameNo, task->surface); - task->sender.set_value(result); - delete task; + auto result = task.playerImpl->render(task.frameNo, task.surface); + task.sender.set_value(result); } } @@ -143,16 +145,16 @@ public: for (auto &e : _threads) e.join(); } - std::future async(RenderTask *task) + std::future async(RenderTask &&task) { - auto receiver = std::move(task->receiver); + auto receiver = std::move(task.receiver); auto i = _index++; for (unsigned n = 0; n != _count; ++n) { - if (_q[(i + n) % _count].try_push(task)) return receiver; + if (_q[(i + n) % _count].try_push(std::move(task))) return receiver; } - _q[i % _count].push(task); + _q[i % _count].push(std::move(task)); return receiver; } @@ -160,11 +162,11 @@ public: std::future render(AnimationImpl *impl, size_t frameNo, Surface &&surface) { - RenderTask *task = new RenderTask(); - task->playerImpl = impl; - task->frameNo = frameNo; - task->surface = std::move(surface); - return async(task); + RenderTask task; + task.playerImpl = impl; + task.frameNo = frameNo; + task.surface = std::move(surface); + return async(std::move(task)); } }; static RenderTaskScheduler render_scheduler; diff --git a/src/vector/vraster.cpp b/src/vector/vraster.cpp index ea254ca..cb2a7ae 100644 --- a/src/vector/vraster.cpp +++ b/src/vector/vraster.cpp @@ -314,6 +314,8 @@ VRle RleTask::operator()(FTOutline &outRef, SW_FT_Stroker &stroker) render(outRef); + path = VPath(); + return std::move(rle); } @@ -333,16 +335,20 @@ class RleTaskScheduler { SW_FT_Stroker_New(&stroker); // Task Loop + RleTask task; while (true) { - RleTask *task = nullptr; + bool success = false; for (unsigned n = 0; n != _count * 32; ++n) { - if (_q[(i + n) % _count].try_pop(task)) break; + if (_q[(i + n) % _count].try_pop(task)) { + success = true; + break; + } } - if (!task && !_q[i].pop(task)) break; - task->sender.set_value((*task)(outlineRef, stroker)); - delete task; + if (!success && !_q[i].pop(task)) break; + + task.sender.set_value((task)(outlineRef, stroker)); } // cleanup @@ -364,16 +370,16 @@ public: for (auto &e : _threads) e.join(); } - std::future async(RleTask *task) + std::future async(RleTask &&task) { - auto receiver = std::move(task->sender.get_future()); + auto receiver = std::move(task.sender.get_future()); auto i = _index++; for (unsigned n = 0; n != _count; ++n) { - if (_q[(i + n) % _count].try_push(task)) return receiver; + if (_q[(i + n) % _count].try_push(std::move(task))) return receiver; } - _q[i % _count].push(task); + _q[i % _count].push(std::move(task)); return receiver; } @@ -381,27 +387,27 @@ public: std::future strokeRle(VPath &&path, VRle &&rle, CapStyle cap, JoinStyle join, float width, float meterLimit, const VRect &clip) { - RleTask *task = new RleTask(); - task->stroke = true; - task->path = std::move(path); - task->rle = std::move(rle); - task->cap = cap; - task->join = join; - task->width = width; - task->meterLimit = meterLimit; - task->clip = clip; - return async(task); + RleTask task; + task.stroke = true; + task.path = std::move(path); + task.rle = std::move(rle); + task.cap = cap; + task.join = join; + task.width = width; + task.meterLimit = meterLimit; + task.clip = clip; + return async(std::move(task)); } std::future fillRle(VPath &&path, VRle &&rle, FillRule fillRule, const VRect &clip) { - RleTask *task = new RleTask(); - task->path = std::move(path); - task->rle = std::move(rle); - task->fillRule = fillRule; - task->clip = clip; - task->stroke = false; - return async(task); + RleTask task; + task.path = std::move(path); + task.rle = std::move(rle); + task.fillRule = fillRule; + task.clip = clip; + task.stroke = false; + return async(std::move(task)); } }; diff --git a/src/vector/vtaskqueue.h b/src/vector/vtaskqueue.h index 5700eab..ce02dad 100644 --- a/src/vector/vtaskqueue.h +++ b/src/vector/vtaskqueue.h @@ -6,27 +6,27 @@ template class TaskQueue { using lock_t = std::unique_lock; - std::deque _q; + std::deque _q; bool _done{false}; std::mutex _mutex; std::condition_variable _ready; public: - bool try_pop(Task *&task) + bool try_pop(Task &task) { lock_t lock{_mutex, std::try_to_lock}; if (!lock || _q.empty()) return false; - task = _q.front(); + task = std::move(_q.front()); _q.pop_front(); return true; } - bool try_push(Task *task) + bool try_push(Task &&task) { { lock_t lock{_mutex, std::try_to_lock}; if (!lock) return false; - _q.push_back(task); + _q.push_back(std::move(task)); } _ready.notify_one(); return true; @@ -41,24 +41,25 @@ public: _ready.notify_all(); } - bool pop(Task *&task) + bool pop(Task &task) { lock_t lock{_mutex}; while (_q.empty() && !_done) _ready.wait(lock); if (_q.empty()) return false; - task = _q.front(); + task = std::move(_q.front()); _q.pop_front(); return true; } - void push(Task *task) + void push(Task &&task) { { lock_t lock{_mutex}; - _q.push_back(task); + _q.push_back(std::move(task)); } _ready.notify_one(); } + }; #endif // VTASKQUEUE_H -- 2.34.1