From 35554cc8b7adb1ca6c037d67f502e139563c2528 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Wed, 12 Aug 2020 18:53:15 +0300
Subject: [PATCH] Add render unit tests and VR log output

---
 components/renderers/cpp/CMakeLists.txt       |   4 +-
 components/renderers/cpp/test/CMakeLists.txt  |  12 ++
 components/renderers/cpp/test/render_unit.cpp | 134 ++++++++++++++++++
 .../streams/src/renderers/openvr_render.cpp   |   6 +
 4 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 components/renderers/cpp/test/CMakeLists.txt
 create mode 100644 components/renderers/cpp/test/render_unit.cpp

diff --git a/components/renderers/cpp/CMakeLists.txt b/components/renderers/cpp/CMakeLists.txt
index 5b720cf77..bf3c36d83 100644
--- a/components/renderers/cpp/CMakeLists.txt
+++ b/components/renderers/cpp/CMakeLists.txt
@@ -33,4 +33,6 @@ target_precompile_headers(ftlrender REUSE_FROM ftldata)
 
 set_property(TARGET ftlrender PROPERTY CUDA_ARCHITECTURES OFF)
 
-#ADD_SUBDIRECTORY(test)
+if (BUILD_TESTS)
+	ADD_SUBDIRECTORY(test)
+endif()
diff --git a/components/renderers/cpp/test/CMakeLists.txt b/components/renderers/cpp/test/CMakeLists.txt
new file mode 100644
index 000000000..6212e13bd
--- /dev/null
+++ b/components/renderers/cpp/test/CMakeLists.txt
@@ -0,0 +1,12 @@
+### Renderer Unit ##############################################################
+add_executable(render_unit
+	$<TARGET_OBJECTS:CatchTest>
+	./render_unit.cpp
+)
+target_include_directories(render_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")
+target_link_libraries(render_unit
+	ftlcommon ftlcodecs ftldata ftlrgbd)
+
+	target_precompile_headers(render_unit REUSE_FROM ftlcommon)
+
+add_test(RenderUnitTest render_unit)
\ No newline at end of file
diff --git a/components/renderers/cpp/test/render_unit.cpp b/components/renderers/cpp/test/render_unit.cpp
new file mode 100644
index 000000000..8fb470a86
--- /dev/null
+++ b/components/renderers/cpp/test/render_unit.cpp
@@ -0,0 +1,134 @@
+#include "catch.hpp"
+
+#include <ftl/data/new_frameset.hpp>
+#include <ftl/data/framepool.hpp>
+#include <ftl/render/CUDARender.hpp>
+
+#include <nlohmann/json.hpp>
+
+using ftl::data::Frame;
+using ftl::data::FrameSet;
+using ftl::config::json_t;
+using ftl::codecs::Channel;
+
+TEST_CASE("Renderer Single Frame", "") {
+	json_t global = json_t{{"$id","ftl://test"}};
+	auto *root = ftl::config::configure(global);
+
+	ftl::data::Pool pool(5,7);
+
+	Frame f = pool.allocate(ftl::data::FrameID(0,0), 1000);
+	f.store();
+	auto fsptr = FrameSet::fromFrame(f);
+
+	auto renderer = std::unique_ptr<ftl::render::CUDARender>(
+		ftl::create<ftl::render::CUDARender>(root, "renderer")
+	);
+
+	Frame out = pool.allocate(ftl::data::FrameID(1,0), 1000);
+	out.store();
+
+	ftl::rgbd::Frame &rgbdframe = out.cast<ftl::rgbd::Frame>();
+	auto &calib = rgbdframe.setLeft();
+	calib.width = 640;
+	calib.height = 480;
+	calib.fx = 700;
+	calib.fy = 700;
+	calib.cx = -250;
+	calib.cy = -200;
+	calib.minDepth = 0.1f;
+	calib.maxDepth = 10.0f;
+	rgbdframe.setPose() = Eigen::Matrix4d::Identity();
+
+	int width = rgbdframe.getLeft().width;
+	int height = rgbdframe.getLeft().height;
+	
+	auto &colour = rgbdframe.create<cv::cuda::GpuMat>(Channel::Colour);
+	colour.create(height, width, CV_8UC4);
+	rgbdframe.create<cv::cuda::GpuMat>(Channel::Depth).create(height, width, CV_32F);
+	rgbdframe.createTexture<float>(Channel::Depth);
+
+	SECTION("copes with single frame missing colour") {
+		for (int i=0; i<20; ++i) {
+			renderer->begin(out.cast<ftl::rgbd::Frame>(), Channel::Colour);
+
+			Eigen::Matrix4d pose;
+			pose.setIdentity();
+			renderer->submit(fsptr.get(), ftl::codecs::Channels<0>(Channel::Colour), pose);
+			renderer->render();
+			renderer->end();
+		}
+	}
+
+	/*SECTION("single colour empty mat") {
+		fsptr->frames[0].create<cv::cuda::GpuMat>(Channel::Colour);
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setLeft() = calib;
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setPose() = Eigen::Matrix4d::Identity();
+
+		for (int i=0; i<20; ++i) {
+			renderer->begin(out.cast<ftl::rgbd::Frame>(), Channel::Colour);
+
+			Eigen::Matrix4d pose;
+			pose.setIdentity();
+			renderer->submit(fsptr.get(), ftl::codecs::Channels<0>(Channel::Colour), pose);
+			renderer->render();
+			renderer->end();
+		}
+	}*/
+
+	SECTION("single colour only frame") {
+		fsptr->frames[0].create<cv::cuda::GpuMat>(Channel::Colour).create(640,480,CV_8UC4);
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setLeft() = calib;
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setPose() = Eigen::Matrix4d::Identity();
+
+		for (int i=0; i<20; ++i) {
+			renderer->begin(out.cast<ftl::rgbd::Frame>(), Channel::Colour);
+
+			Eigen::Matrix4d pose;
+			pose.setIdentity();
+			renderer->submit(fsptr.get(), ftl::codecs::Channels<0>(Channel::Colour), pose);
+			renderer->render();
+			renderer->end();
+		}
+	}
+
+	SECTION("single full only frame") {
+		fsptr->frames[0].create<cv::cuda::GpuMat>(Channel::Colour).create(640,480,CV_8UC4);
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setLeft() = calib;
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setPose() = Eigen::Matrix4d::Identity();
+
+		auto &depth = fsptr->frames[0].create<cv::cuda::GpuMat>(Channel::Colour);
+		depth.create(640,480,CV_8UC4);
+		depth.setTo(cv::Scalar(5.0f));
+
+		for (int i=0; i<20; ++i) {
+			renderer->begin(out.cast<ftl::rgbd::Frame>(), Channel::Colour);
+
+			Eigen::Matrix4d pose;
+			pose.setIdentity();
+			renderer->submit(fsptr.get(), ftl::codecs::Channels<0>(Channel::Colour), pose);
+			renderer->render();
+			renderer->end();
+		}
+	}
+
+	SECTION("single frame empty depth") {
+		fsptr->frames[0].create<cv::cuda::GpuMat>(Channel::Colour).create(640,480,CV_8UC4);
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setLeft() = calib;
+		fsptr->frames[0].cast<ftl::rgbd::Frame>().setPose() = Eigen::Matrix4d::Identity();
+
+		auto &depth = fsptr->frames[0].create<cv::cuda::GpuMat>(Channel::Colour);
+		//depth.create(640,480,CV_8UC4);
+		//depth.setTo(cv::Scalar(5.0f));
+
+		for (int i=0; i<20; ++i) {
+			renderer->begin(out.cast<ftl::rgbd::Frame>(), Channel::Colour);
+
+			Eigen::Matrix4d pose;
+			pose.setIdentity();
+			renderer->submit(fsptr.get(), ftl::codecs::Channels<0>(Channel::Colour), pose);
+			renderer->render();
+			renderer->end();
+		}
+	}
+}
diff --git a/components/streams/src/renderers/openvr_render.cpp b/components/streams/src/renderers/openvr_render.cpp
index 2a23beb3e..62e1b1088 100644
--- a/components/streams/src/renderers/openvr_render.cpp
+++ b/components/streams/src/renderers/openvr_render.cpp
@@ -233,6 +233,9 @@ bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
 			right.cx = intrinsic(0,2);
 			right.cy = intrinsic(1,2);
 
+			LOG(INFO) << "VR Left Intrinsics: fx=" << left.fx << ",cx=" << left.cx << ",cy=" << left.cy;
+			LOG(INFO) << "VR Right Intrinsics: fx=" << right.fx << ",cx=" << right.cx << ",cy=" << right.cy;
+
 			if (!frame_out.has(Channel::Capabilities)) {
 				auto &cap = frame_out.create<std::unordered_set<Capability>>(Channel::Capabilities);
 				cap.emplace(Capability::VIDEO);
@@ -282,6 +285,8 @@ bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
 				auto cur_right = rgbdframe.getRight();
 				cur_right.baseline = baseline_;
 				rgbdframe.setRight() = cur_right;
+
+				LOG(INFO) << "VR Baseline: " << baseline_;
 			}
 			Eigen::Matrix4d pose = ConvertSteamVRMatrixToMatrix4(rTrackedDevicePose_[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);
 			Eigen::Vector3d ea = pose.block<3, 3>(0, 0).eulerAngles(0, 1, 2);
@@ -455,6 +460,7 @@ bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
 
 		if (!post_pipe_) {
 			post_pipe_ = ftl::config::create<ftl::operators::Graph>(host(), "post_filters");
+			post_pipe_->append<ftl::operators::Poser>("poser");
 			post_pipe_->append<ftl::operators::FXAA>("fxaa");
 			post_pipe_->append<ftl::operators::GTAnalysis>("gtanalyse");
 		}
-- 
GitLab