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);
}
}
for (auto &e : _threads) e.join();
}
- std::future<Surface> async(RenderTask *task)
+ std::future<Surface> 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;
}
std::future<Surface> 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;
render(outRef);
+ path = VPath();
+
return std::move(rle);
}
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
for (auto &e : _threads) e.join();
}
- std::future<VRle> async(RleTask *task)
+ std::future<VRle> 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;
}
std::future<VRle> 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<VRle> 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));
}
};
template <typename Task>
class TaskQueue {
using lock_t = std::unique_lock<std::mutex>;
- std::deque<Task *> _q;
+ std::deque<Task> _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;
_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