void VDrawable::preprocess(const VRect &clip)
{
if (mFlag & (DirtyState::Path)) {
+
+ if (!mRleFuture) mRleFuture = std::make_shared<VSharedState<VRle>>();
+
+ mRleFuture->reuse();
+
if (mStroke.enable) {
if (mStroke.mDash.size()) {
VDasher dasher(mStroke.mDash.data(), mStroke.mDash.size());
mPath = dasher.dashed(mPath);
}
- mRleTask = VRaster::generateStrokeInfo(
+ VRaster::generateStrokeInfo(mRleFuture,
std::move(mPath), std::move(mRle), mStroke.cap, mStroke.join,
mStroke.width, mStroke.meterLimit, clip);
} else {
- mRleTask = VRaster::generateFillInfo(
+ VRaster::generateFillInfo(mRleFuture,
std::move(mPath), std::move(mRle), mFillRule, clip);
}
mRle = VRle();
VRle VDrawable::rle()
{
- if (mRleTask.valid()) {
- mRle = mRleTask.get();
+ if (mRleFuture && mRleFuture->valid()) {
+ mRle = mRleFuture->get();
}
return mRle;
}
}
struct RleTask {
- std::promise<VRle> sender;
+ RleShare mRlePromise;
VPath path;
VRle rle;
float width;
if (!success && !_q[i].pop(task)) break;
- task.sender.set_value((task)(outlineRef, stroker));
+ task.mRlePromise->set_value((task)(outlineRef, stroker));
}
// cleanup
for (auto &e : _threads) e.join();
}
- std::future<VRle> async(RleTask &&task)
+ void async(RleTask &&task)
{
- 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(std::move(task))) return receiver;
+ if (_q[(i + n) % _count].try_push(std::move(task))) return;
}
_q[i % _count].push(std::move(task));
-
- return receiver;
}
- std::future<VRle> strokeRle(VPath &&path, VRle &&rle, CapStyle cap, JoinStyle join,
+ void strokeRle(RleShare &promise, VPath &&path, VRle &&rle, CapStyle cap, JoinStyle join,
float width, float meterLimit, const VRect &clip)
{
RleTask task;
task.width = width;
task.meterLimit = meterLimit;
task.clip = clip;
- return async(std::move(task));
+ task.mRlePromise = promise;
+
+ async(std::move(task));
}
- std::future<VRle> fillRle(VPath &&path, VRle &&rle, FillRule fillRule, const VRect &clip)
+ void fillRle(RleShare &promise, VPath &&path, VRle &&rle, FillRule fillRule, const VRect &clip)
{
RleTask task;
task.path = std::move(path);
task.fillRule = fillRule;
task.clip = clip;
task.stroke = false;
- return async(std::move(task));
+ task.mRlePromise = promise;
+
+ async(std::move(task));
}
};
static RleTaskScheduler raster_scheduler;
-std::future<VRle> VRaster::generateFillInfo(VPath &&path, VRle &&rle,
- FillRule fillRule, const VRect &clip)
+void VRaster::generateFillInfo(RleShare &promise, VPath &&path, VRle &&rle,
+ FillRule fillRule, const VRect &clip)
{
if (path.empty()) {
- std::promise<VRle> promise;
- promise.set_value(VRle());
- return promise.get_future();
+ promise->set_value(VRle());
+ return;
}
- return raster_scheduler.fillRle(std::move(path), std::move(rle), fillRule, clip);
+ return raster_scheduler.fillRle(promise, std::move(path), std::move(rle), fillRule, clip);
}
-std::future<VRle> VRaster::generateStrokeInfo(VPath &&path, VRle &&rle, CapStyle cap,
- JoinStyle join, float width,
- float meterLimit, const VRect &clip)
+void VRaster::generateStrokeInfo(RleShare &promise, VPath &&path, VRle &&rle, CapStyle cap,
+ JoinStyle join, float width,
+ float meterLimit, const VRect &clip)
{
if (path.empty()) {
- std::promise<VRle> promise;
- promise.set_value(VRle());
- return promise.get_future();
+ promise->set_value(VRle());
+ return;
}
- return raster_scheduler.strokeRle(std::move(path), std::move(rle), cap, join, width, meterLimit, clip);
+ return raster_scheduler.strokeRle(promise, std::move(path), std::move(rle), cap, join, width, meterLimit, clip);
}
V_END_NAMESPACE
class VPath;
class VRle;
+template <class R>
+class VSharedState {
+public:
+ void set_value(R value) {
+ if (_ready) return;
+
+ {
+ std::lock_guard<std::mutex> lock(_mutex);
+ _value = std::move(value);
+ _ready = true;
+ }
+ _cv.notify_one();
+ }
+ R get(){
+ std::unique_lock<std::mutex> lock(_mutex);
+ while(!_ready) _cv.wait(lock);
+ _valid = false;
+ return std::move(_value);
+ }
+ bool valid() const {return _valid;}
+ void reuse() {
+ _ready = false;
+ _valid = true;
+ }
+private:
+ R _value;
+ std::mutex _mutex;
+ std::condition_variable _cv;
+ bool _ready{false};
+ bool _valid{true};
+};
+
+using RleShare = std::shared_ptr<VSharedState<VRle>>;
+
struct VRaster {
- static std::future<VRle>
- generateFillInfo(VPath &&path, VRle &&rle,
+ static void
+ generateFillInfo(RleShare &promise, VPath &&path, VRle &&rle,
FillRule fillRule = FillRule::Winding, const VRect &clip = VRect());
- static std::future<VRle>
- generateStrokeInfo(VPath &&path, VRle &&rle,
+ static void
+ generateStrokeInfo(RleShare &promise, VPath &&path, VRle &&rle,
CapStyle cap, JoinStyle join,
float width, float meterLimit, const VRect &clip = VRect());
};