From 015fed3c84c5d052c2410abd84bb4a251e998070 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Mon, 3 Aug 2020 20:23:43 +0300
Subject: [PATCH] Allow render cancel on exception

---
 components/renderers/cpp/include/ftl/render/CUDARender.hpp | 2 ++
 components/renderers/cpp/include/ftl/render/renderer.hpp   | 2 ++
 components/renderers/cpp/src/CUDARender.cpp                | 7 +++++++
 components/streams/src/renderers/openvr_render.cpp         | 3 +++
 components/streams/src/renderers/screen_render.cpp         | 2 ++
 components/structures/include/ftl/data/messages.hpp        | 1 +
 6 files changed, 17 insertions(+)

diff --git a/components/renderers/cpp/include/ftl/render/CUDARender.hpp b/components/renderers/cpp/include/ftl/render/CUDARender.hpp
index d5b3ce675..a4e65bce6 100644
--- a/components/renderers/cpp/include/ftl/render/CUDARender.hpp
+++ b/components/renderers/cpp/include/ftl/render/CUDARender.hpp
@@ -33,6 +33,8 @@ class CUDARender : public ftl::render::FSRenderer {
 
 	void blend(ftl::codecs::Channel) override;
 
+	void cancel() override;
+
 	/**
 	 * Returns all inter-frameset collisions in camera coordinates.
 	 */
diff --git a/components/renderers/cpp/include/ftl/render/renderer.hpp b/components/renderers/cpp/include/ftl/render/renderer.hpp
index 07f92083e..598e2a6ee 100644
--- a/components/renderers/cpp/include/ftl/render/renderer.hpp
+++ b/components/renderers/cpp/include/ftl/render/renderer.hpp
@@ -47,6 +47,8 @@ class Renderer : public ftl::Configurable {
 
 	virtual void blend(ftl::codecs::Channel)=0;
 
+	virtual void cancel()=0;
+
 	protected:
 	Stage stage_;
 };
diff --git a/components/renderers/cpp/src/CUDARender.cpp b/components/renderers/cpp/src/CUDARender.cpp
index b3d07ac29..b2973f0a7 100644
--- a/components/renderers/cpp/src/CUDARender.cpp
+++ b/components/renderers/cpp/src/CUDARender.cpp
@@ -498,6 +498,13 @@ void CUDARender::_renderPass2(Channels<0> chans, const Eigen::Matrix4d &t) {
 	}
 }
 
+void CUDARender::cancel() {
+	out_ = nullptr;
+	scene_ = nullptr;
+	stage_ = Stage::Finished;
+	cudaSafeCall(cudaStreamSynchronize(stream_));
+}
+
 void CUDARender::begin(ftl::rgbd::Frame &out, ftl::codecs::Channel chan) {
 	if (stage_ != Stage::Finished) {
 		throw FTL_Error("Already rendering");
diff --git a/components/streams/src/renderers/openvr_render.cpp b/components/streams/src/renderers/openvr_render.cpp
index 386c8b6aa..2a23beb3e 100644
--- a/components/streams/src/renderers/openvr_render.cpp
+++ b/components/streams/src/renderers/openvr_render.cpp
@@ -448,6 +448,9 @@ bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
 			renderer2_->end();
 		} catch (const ftl::exception &e) {
 			LOG(ERROR) << "Render exception: " << e.what();
+			renderer_->cancel();
+			renderer2_->cancel();
+			frame_out.message(ftl::data::Message::Error_RENDER, e.what());
 		}
 
 		if (!post_pipe_) {
diff --git a/components/streams/src/renderers/screen_render.cpp b/components/streams/src/renderers/screen_render.cpp
index 36da28dac..3df19e7a3 100644
--- a/components/streams/src/renderers/screen_render.cpp
+++ b/components/streams/src/renderers/screen_render.cpp
@@ -206,6 +206,8 @@ bool ScreenRender::retrieve(ftl::data::Frame &frame_out) {
 			if (!data_only) renderer_->end();
 		} catch (const ftl::exception &e) {
 			LOG(ERROR) << "Render exception: " << e.what();
+			renderer_->cancel();
+			frame_out.message(ftl::data::Message::Error_RENDER, e.what());
 		}
 
 		if (!data_only) {
diff --git a/components/structures/include/ftl/data/messages.hpp b/components/structures/include/ftl/data/messages.hpp
index 9f90263fd..74bcfccb0 100644
--- a/components/structures/include/ftl/data/messages.hpp
+++ b/components/structures/include/ftl/data/messages.hpp
@@ -13,6 +13,7 @@ enum class Message : int {
 	Error_FRAME_GRAB,
 	Error_BAD_FORMAT,
 	Error_OPENVR,
+	Error_RENDER,
 	Warning_UNKNOWN = 1024,
 	Warning_FRAME_DROP,
 	Warning_PIPELINE_DROP,
-- 
GitLab