Skip to content
Snippets Groups Projects
Commit a43ed9b5 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Render in GUI thread

parent 79f496d3
Branches
Tags
1 merge request!316Resolves #343 GUI and Frame Refactor
Pipeline #28240 failed
...@@ -124,6 +124,8 @@ void FTLGui::mainloop() { ...@@ -124,6 +124,8 @@ void FTLGui::mainloop() {
// at full FPS (25 without VR and 90 with VR currently) // at full FPS (25 without VR and 90 with VR currently)
//screen_->render(); //screen_->render();
io_->feed()->render();
// Only draw the GUI at 25fps // Only draw the GUI at 25fps
//if (delta >= 0.04f) { //if (delta >= 0.04f) {
last_draw_time = now; last_draw_time = now;
......
...@@ -74,8 +74,8 @@ void Camera::setVolume(float v) { ...@@ -74,8 +74,8 @@ void Camera::setVolume(float v) {
} }
std::unordered_set<Channel> Camera::availableChannels() { std::unordered_set<Channel> Camera::availableChannels() {
if (std::atomic_load(&current_fs_)) { if (std::atomic_load(&latest_)) {
return current_fs_->frames[frame_idx].available(); return latest_->frames[frame_idx].available();
} }
return {}; return {};
} }
...@@ -90,12 +90,12 @@ void Camera::activate(ftl::data::FrameID id) { ...@@ -90,12 +90,12 @@ void Camera::activate(ftl::data::FrameID id) {
touch_ = false; touch_ = false;
movable_ = false; movable_ = false;
std::mutex m; //std::mutex m;
std::condition_variable cv; //std::condition_variable cv;
filter = io->feed()->filter(std::unordered_set<unsigned int>{id.frameset()}, {Channel::Left}); filter = io->feed()->filter(std::unordered_set<unsigned int>{id.frameset()}, {Channel::Left});
filter->on( filter->on(
[this,&cv,&m, speaker = io->speaker()](ftl::data::FrameSetPtr fs){ [this, speaker = io->speaker()](ftl::data::FrameSetPtr fs){
if (paused) return true; if (paused) return true;
std::atomic_store(&current_fs_, fs); std::atomic_store(&current_fs_, fs);
...@@ -103,13 +103,15 @@ void Camera::activate(ftl::data::FrameID id) { ...@@ -103,13 +103,15 @@ void Camera::activate(ftl::data::FrameID id) {
// Need to notify GUI thread when first data comes // Need to notify GUI thread when first data comes
if (!has_seen_frame_) { if (!has_seen_frame_) {
std::unique_lock<std::mutex> lk(m); //std::unique_lock<std::mutex> lk(m);
has_seen_frame_ = true; has_seen_frame_ = true;
cv.notify_one(); //cv.notify_one();
} }
if (!view) return true; if (!view) return true;
LOG(INFO) << "Got frameset: " << fs->timestamp();
if (live_ && touch_) { if (live_ && touch_) {
if (point_.id >= 0) { if (point_.id >= 0) {
auto response = fs->frames[frame_idx].response(); auto response = fs->frames[frame_idx].response();
...@@ -130,11 +132,20 @@ void Camera::activate(ftl::data::FrameID id) { ...@@ -130,11 +132,20 @@ void Camera::activate(ftl::data::FrameID id) {
} }
); );
auto sets = filter->getLatestFrameSets();
if (sets.size() > 0) {
std::atomic_store(&current_fs_, sets.front());
std::atomic_store(&latest_, sets.front());
initiate_(sets.front()->frames[frame_idx]);
} else {
throw FTL_Error("Cannot activate camera, no data");
}
// For first data, extract useful things and create view // For first data, extract useful things and create view
// Must be done in GUI thread, hence use of cv. // Must be done in GUI thread, hence use of cv.
std::unique_lock<std::mutex> lk(m); //std::unique_lock<std::mutex> lk(m);
cv.wait_for(lk, 1s, [this](){ return has_seen_frame_; }); //cv.wait_for(lk, 1s, [this](){ return has_seen_frame_; });
initiate_(std::atomic_load(&current_fs_)->frames[frame_idx]); //initiate_(std::atomic_load(&current_fs_)->frames[frame_idx]);
} }
void Camera::setChannel(Channel c) { void Camera::setChannel(Channel c) {
......
...@@ -231,7 +231,6 @@ bool CameraView::mouseButtonEvent(const Eigen::Vector2i &p, int button, bool dow ...@@ -231,7 +231,6 @@ bool CameraView::mouseButtonEvent(const Eigen::Vector2i &p, int button, bool dow
} }
void CameraView::draw(NVGcontext*ctx) { void CameraView::draw(NVGcontext*ctx) {
if (ctrl_->hasFrame()) { if (ctrl_->hasFrame()) {
imview_->copyFrom(ctrl_->getFrame()); imview_->copyFrom(ctrl_->getFrame());
} }
......
...@@ -92,6 +92,7 @@ private: ...@@ -92,6 +92,7 @@ private:
std::unordered_map<uint32_t, ftl::rgbd::Source*> devices_; std::unordered_map<uint32_t, ftl::rgbd::Source*> devices_;
std::unordered_map<uint32_t, ftl::render::Source*> renderers_; std::unordered_map<uint32_t, ftl::render::Source*> renderers_;
std::unordered_map<uint32_t, ftl::operators::Graph*> pre_pipelines_; std::unordered_map<uint32_t, ftl::operators::Graph*> pre_pipelines_;
std::list<ftl::streams::ManualSourceBuilder*> render_builders_;
std::vector<std::string> netcams_; std::vector<std::string> netcams_;
ftl::Handler<uint32_t> new_sources_cb_; ftl::Handler<uint32_t> new_sources_cb_;
...@@ -142,6 +143,12 @@ public: ...@@ -142,6 +143,12 @@ public:
bool sourceAvailable(const std::string &uri); bool sourceAvailable(const std::string &uri);
bool sourceActive(const std::string &uri); bool sourceActive(const std::string &uri);
/**
* Perform a render tick for all render sources. Note that this must be
* called from the GUI / OpenGL thread.
*/
void render();
inline ftl::Handle onNewSources(const std::function<bool(uint32_t)> &cb) { return new_sources_cb_.on(cb); } inline ftl::Handle onNewSources(const std::function<bool(uint32_t)> &cb) { return new_sources_cb_.on(cb); }
inline ftl::Handle onRemoveSources(const std::function<bool(uint32_t)> &cb) { return remove_sources_cb_.on(cb); } inline ftl::Handle onRemoveSources(const std::function<bool(uint32_t)> &cb) { return remove_sources_cb_.on(cb); }
......
...@@ -579,12 +579,20 @@ uint32_t Feed::add(const std::string &path) { ...@@ -579,12 +579,20 @@ uint32_t Feed::add(const std::string &path) {
auto *rsource = ftl::create<ftl::render::Source>(this, srcname, this); auto *rsource = ftl::create<ftl::render::Source>(this, srcname, this);
renderers_[fsid] = rsource; renderers_[fsid] = rsource;
source = rsource; source = rsource;
// Create local builder instance
auto *creator = new ftl::streams::ManualSourceBuilder(pool_.get(), fsid, source);
std::shared_ptr<ftl::streams::BaseBuilder> creatorptr(creator);
lk.lock();
receiver_->registerBuilder(creatorptr);
// FIXME: pointer is deleted when removed from receiver
render_builders_.push_back(creator);
} else { } else {
auto *dsource = ftl::create<ftl::rgbd::Source>(this, srcname, net_); auto *dsource = ftl::create<ftl::rgbd::Source>(this, srcname, net_);
devices_[fsid] = dsource; devices_[fsid] = dsource;
source = dsource; source = dsource;
_createPipeline(fsid); _createPipeline(fsid);
}
// Create local builder instance // Create local builder instance
auto *creator = new ftl::streams::IntervalSourceBuilder(pool_.get(), fsid, {source}); auto *creator = new ftl::streams::IntervalSourceBuilder(pool_.get(), fsid, {source});
...@@ -594,6 +602,8 @@ uint32_t Feed::add(const std::string &path) { ...@@ -594,6 +602,8 @@ uint32_t Feed::add(const std::string &path) {
receiver_->registerBuilder(creatorptr); receiver_->registerBuilder(creatorptr);
creator->start(); creator->start();
}
return fsid; return fsid;
} }
...@@ -631,6 +641,16 @@ uint32_t Feed::add(const std::string &path) { ...@@ -631,6 +641,16 @@ uint32_t Feed::add(const std::string &path) {
return -1; return -1;
} }
void Feed::render() {
SHARED_LOCK(mtx_, lk);
auto builders = render_builders_;
lk.unlock();
for (auto *r : builders) {
r->tick();
}
}
uint32_t Feed::getID(const std::string &source) { uint32_t Feed::getID(const std::string &source) {
return fsid_lookup_.at(source); return fsid_lookup_.at(source);
} }
......
...@@ -89,7 +89,7 @@ bool OpenVRRender::initVR() { ...@@ -89,7 +89,7 @@ bool OpenVRRender::initVR() {
} }
bool OpenVRRender::supported() { bool OpenVRRender::supported() {
#ifdef HAVR_OPENVR #ifdef HAVE_OPENVR
return vr::VR_IsHmdPresent(); return vr::VR_IsHmdPresent();
#else #else
return false; return false;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment