diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp index 9141c862feac76b12d16bea5fc9380da8ca5fc99..0407bd45c56417199195ab104bcbd45e8d407b29 100644 --- a/applications/gui/src/camera.cpp +++ b/applications/gui/src/camera.cpp @@ -121,6 +121,13 @@ static Eigen::Vector3f cudaToEigen(const float3 &v) { return e; } +void ftl::gui::Camera::drawUpdated(std::vector<ftl::rgbd::FrameSet*> &fss) { + // Only draw if frameset updated. + if (!stale_frame_.test_and_set()) { + draw(fss); + } +} + void ftl::gui::Camera::draw(std::vector<ftl::rgbd::FrameSet*> &fss) { if (fid_ != 255) return; //if (fsid_ >= fss.size()) return; @@ -294,7 +301,9 @@ void ftl::gui::Camera::_draw(std::vector<ftl::rgbd::FrameSet*> &fss) { } catch(std::exception &e) { LOG(ERROR) << "Exception in render: " << e.what(); } + for (auto *fs : fss) { + if (!usesFrameset(fs->id)) continue; fs->mtx.unlock(); } } @@ -366,8 +375,6 @@ void ftl::gui::Camera::_downloadFrames(ftl::cuda::TextureObject<uchar4> &a, ftl: if (im2_.cols != im1_.cols || im2_.rows != im1_.rows) { throw FTL_Error("Left and right images are different sizes"); } - - new_frame_.clear(); } void ftl::gui::Camera::_downloadFrame(ftl::cuda::TextureObject<uchar4> &a) { @@ -381,8 +388,6 @@ void ftl::gui::Camera::_downloadFrame(ftl::cuda::TextureObject<uchar4> &a) { height_ = im1_.rows; im2_ = cv::Mat(); - - new_frame_.clear(); } void ftl::gui::Camera::update(int fsid, const ftl::codecs::Channels<0> &c) { @@ -398,6 +403,7 @@ void ftl::gui::Camera::update(std::vector<ftl::rgbd::FrameSet*> &fss) { UNIQUE_LOCK(mutex_, lk); framesets_ = &fss; + stale_frame_.clear(); //if (fss.size() <= fsid_) return; if (fid_ == 255) { @@ -405,7 +411,7 @@ void ftl::gui::Camera::update(std::vector<ftl::rgbd::FrameSet*> &fss) { // Do a draw if not active. If active the draw function will be called // directly. if (screen_->activeCamera() != this) { - _draw(fss); + //_draw(fss); } } else { for (auto *fs : fss) { @@ -707,7 +713,7 @@ const void ftl::gui::Camera::captureFrame() { if (framesets_) draw(*framesets_); { - //UNIQUE_LOCK(mutex_, lk); + UNIQUE_LOCK(mutex_, lk); if (im1_.rows != 0) { texture1_.update(im1_); } diff --git a/applications/gui/src/camera.hpp b/applications/gui/src/camera.hpp index d044151da12113c7eff28978c527b557d355bcc6..9e034c83a9509aa7663648d3f12ecc8390b39bd0 100644 --- a/applications/gui/src/camera.hpp +++ b/applications/gui/src/camera.hpp @@ -67,6 +67,12 @@ class Camera { */ void update(int fsid, const ftl::codecs::Channels<0> &c); + /** + * Draw virtual camera only if the frameset has been updated since last + * draw. + */ + void drawUpdated(std::vector<ftl::rgbd::FrameSet*> &fss); + void draw(std::vector<ftl::rgbd::FrameSet*> &fss); inline int64_t getFrameTimeMS() const { return int64_t(delta_ * 1000.0f); } @@ -131,7 +137,7 @@ class Camera { cv::Mat im1_; // first channel (left) cv::Mat im2_; // second channel ("right") bool stereo_; - std::atomic_flag new_frame_; + std::atomic_flag stale_frame_; int rx_; int ry_; std::vector<ftl::rgbd::FrameSet*> *framesets_; diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp index e2f8a7f161c961a5f50753da736b263a91f6afda..efd853eaf9fdc7596871284bc84a9c0b8624171e 100644 --- a/applications/gui/src/screen.cpp +++ b/applications/gui/src/screen.cpp @@ -551,6 +551,12 @@ void ftl::gui::Screen::draw(NVGcontext *ctx) { mShader.drawIndexed(GL_TRIANGLES, 0, 2); //glDisable(GL_SCISSOR_TEST); } + } else { + // Must periodically render the cameras here to update any thumbnails. + auto cams = swindow_->getCameras(); + for (auto *c : cams) { + c->drawUpdated(swindow_->getFramesets()); + } } nvgTextAlign(ctx, NVG_ALIGN_RIGHT); diff --git a/applications/gui/src/src_window.cpp b/applications/gui/src/src_window.cpp index 5b6b84174cf8271ee2348988a0e6a9f6417ee427..5620e1928632dae4a9f34390fee702f5827bb526 100644 --- a/applications/gui/src/src_window.cpp +++ b/applications/gui/src/src_window.cpp @@ -74,6 +74,12 @@ SourceWindow::SourceWindow(ftl::gui::Screen *screen) new Label(this, "Select Camera","sans-bold",20); + // FIXME: Reallocating the vector may currently causes thread issues since + // it might be in use elsewhere. A safer mechanism is needed for sharing + // framesets. Temporary solution: preallocate enough slots. + pre_pipelines_.reserve(5); + framesets_.reserve(5); + auto vscroll = new VScrollPanel(this); ipanel_ = new Widget(vscroll); ipanel_->setLayout(new GridLayout(nanogui::Orientation::Horizontal, 2, @@ -179,11 +185,6 @@ bool SourceWindow::_processFrameset(ftl::rgbd::FrameSet &fs, bool fromstream) { interceptor_->select(fs.id, cs); } - /*if (fs.id > 0) { - LOG(INFO) << "Got frameset: " << fs.id; - return true; - }*/ - // Make sure there are enough framesets allocated _checkFrameSets(fs.id); @@ -375,6 +376,7 @@ void SourceWindow::draw(NVGcontext *ctx) { cv::Mat t; auto *cam = camera.second.camera; if (cam) { + //cam->draw(framesets_); if (cam->thumbnail(t)) { thumbs_[i].update(t); }