Browse Source

Visual tests: Show similarity score when showing reference

Michael Ragazzon 4 years ago
parent
commit
7950141288

+ 23 - 41
Tests/Source/VisualTests/CaptureScreen.cpp

@@ -95,7 +95,8 @@ struct DeferFree {
 };
 
 
-ComparisonResult CompareScreenToPreviousCapture(ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename)
+ComparisonResult CompareScreenToPreviousCapture(
+	ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename, bool write_diff_image, TextureGeometry* out_geometry)
 {
 	using Image = ShellRenderInterfaceOpenGL::Image;
 
@@ -104,7 +105,7 @@ ComparisonResult CompareScreenToPreviousCapture(ShellRenderInterfaceOpenGL* shel
 	unsigned char* data_ref = nullptr;
 	unsigned int w_ref = 0, h_ref = 0;
 
-	unsigned int lodepng_result = lodepng_decode24_file(&data_ref, &w_ref, &h_ref, input_path.c_str());
+	unsigned int lodepng_result = lodepng_decode32_file(&data_ref, &w_ref, &h_ref, input_path.c_str());
 	DeferFree defer_free{ data_ref };
 
 	if (lodepng_result)
@@ -116,6 +117,24 @@ ComparisonResult CompareScreenToPreviousCapture(ShellRenderInterfaceOpenGL* shel
 	}
 	RMLUI_ASSERT(w_ref > 0 && h_ref > 0 && data_ref);
 	
+	// Optionally render the previous capture to a texture.
+	if (out_geometry)
+	{
+		if (!shell_renderer->GenerateTexture(out_geometry->texture_handle, data_ref, Rml::Vector2i((int)w_ref, (int)h_ref)))
+		{
+			ComparisonResult result;
+			result.success = false;
+			result.error_msg = Rml::CreateString(1024, "Could not generate texture from file %s", input_path.c_str());
+			return result;
+		}
+
+		const Rml::Colourb colour = {255, 255, 255, 255};
+		const Rml::Vector2f uv_top_left = {0, 0};
+		const Rml::Vector2f uv_bottom_right = {1, 1};
+
+		Rml::GeometryUtilities::GenerateQuad(out_geometry->vertices, out_geometry->indices, Rml::Vector2f(0, 0),
+			Rml::Vector2f((float)w_ref, (float)h_ref), colour, uv_top_left, uv_bottom_right, 0);
+	}
 
 	Image screen = shell_renderer->CaptureScreen();
 	if (!screen.data)
@@ -160,7 +179,7 @@ ComparisonResult CompareScreenToPreviousCapture(ShellRenderInterfaceOpenGL* shel
 		for (int xb = 0; xb < wb_ref; xb++)
 		{
 			const int i_ref = yb_ref + xb;
-			Rml::byte pix_ref = data_ref[i_ref];
+			Rml::byte pix_ref = data_ref[(i_ref * 4) / 3];
 			Rml::byte pix_screen = screen.data[yb_screen + xb];
 			diff.data[i_ref] = (Rml::byte)std::abs((int)pix_ref - (int)pix_screen);
 			sum_diff += (size_t)diff.data[i_ref];
@@ -177,7 +196,7 @@ ComparisonResult CompareScreenToPreviousCapture(ShellRenderInterfaceOpenGL* shel
 	result.similarity_score = (sum_diff == 0 ? 1.0 : 1.0 - std::log(double(sum_diff)) / std::log(double(max_diff)));
 
 	// Write the diff image to file if they are not equal.
-	if (!result.is_equal)
+	if (write_diff_image && !result.is_equal)
 	{
 		Rml::String out_filename = filename;
 		size_t offset = filename.rfind('.');
@@ -197,43 +216,6 @@ ComparisonResult CompareScreenToPreviousCapture(ShellRenderInterfaceOpenGL* shel
 	return result;
 }
 
-bool LoadPreviousCapture(
-	ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename, TextureGeometry& out_geometry, Rml::String& out_error_msg)
-{
-	RMLUI_ASSERT(!out_geometry.texture_handle);
-
-	const Rml::String input_path = GetCompareInputDirectory() + "/" + filename;
-
-	unsigned char* data_ref = nullptr;
-	unsigned int w_ref = 0, h_ref = 0;
-
-	unsigned int lodepng_result = lodepng_decode32_file(&data_ref, &w_ref, &h_ref, input_path.c_str());
-	DeferFree defer_free{data_ref};
-
-	if (lodepng_result)
-	{
-		out_error_msg =
-			Rml::CreateString(1024, "Could not load captured screenshot from %s: %s", input_path.c_str(), lodepng_error_text(lodepng_result));
-		return false;
-	}
-	RMLUI_ASSERT(w_ref > 0 && h_ref > 0 && data_ref);
-
-	if (!shell_renderer->GenerateTexture(out_geometry.texture_handle, data_ref, Rml::Vector2i((int)w_ref, (int)h_ref)))
-	{
-		out_error_msg = Rml::CreateString(1024, "Could not generate texture from file %s", input_path.c_str());
-		return false;
-	}
-
-	const Rml::Colourb colour = {255, 255, 255, 255};
-	const Rml::Vector2f uv_top_left = {0, 0};
-	const Rml::Vector2f uv_bottom_right = {1, 1};
-
-	Rml::GeometryUtilities::GenerateQuad(out_geometry.vertices, out_geometry.indices, Rml::Vector2f(0, 0), Rml::Vector2f((float)w_ref, (float)h_ref),
-		colour, uv_top_left, uv_bottom_right, 0);
-
-	return true;
-}
-
 void RenderTextureGeometry(ShellRenderInterfaceOpenGL* shell_renderer, TextureGeometry& geometry)
 {
 	if (geometry.texture_handle)

+ 4 - 6
Tests/Source/VisualTests/CaptureScreen.h

@@ -43,18 +43,16 @@ struct ComparisonResult {
 	Rml::String error_msg;
 };
 
-bool CaptureScreenshot(ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename, int clip_width);
-
-ComparisonResult CompareScreenToPreviousCapture(ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename);
-
 struct TextureGeometry {
 	Rml::TextureHandle texture_handle = 0;
 	Rml::Vertex vertices[4];
 	int indices[6] = {};
 };
 
-bool LoadPreviousCapture(
-	ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename, TextureGeometry& out_geometry, Rml::String& out_error_msg);
+bool CaptureScreenshot(ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename, int clip_width);
+
+ComparisonResult CompareScreenToPreviousCapture(
+	ShellRenderInterfaceOpenGL* shell_renderer, const Rml::String& filename, bool write_diff_image, TextureGeometry* out_geometry);
 
 void RenderTextureGeometry(ShellRenderInterfaceOpenGL* shell_renderer, TextureGeometry& geometry);
 

+ 23 - 12
Tests/Source/VisualTests/TestNavigator.cpp

@@ -200,11 +200,11 @@ void TestNavigator::ProcessEvent(Rml::Event& event)
 					source_state = SourceType::None;
 			}
 			viewer->ShowSource(source_state);
-			ShowReference(false);
+			ShowReference(false, false);
 		}
 		else if (key_identifier == Rml::Input::KI_Q && key_ctrl)
 		{
-			ShowReference(!show_reference);
+			ShowReference(!show_reference, false);
 		}
 		else if (key_identifier == Rml::Input::KI_ESCAPE)
 		{
@@ -353,7 +353,7 @@ void TestNavigator::LoadActiveTest()
 	const TestSuite& suite = CurrentSuite();
 	viewer->LoadTest(suite.GetDirectory(), suite.GetFilename(), suite.GetIndex(), suite.GetNumTests(), suite.GetFilterIndex(), suite.GetNumFilteredTests(), suite_index, (int)test_suites.size());
 	viewer->ShowSource(source_state);
-	ShowReference(false);
+	ShowReference(false, true);
 	UpdateGoToText();
 }
 
@@ -367,7 +367,7 @@ ComparisonResult TestNavigator::CompareCurrentView()
 {
 	const Rml::String filename = GetImageFilenameFromCurrentTest();
 
-	ComparisonResult result = CompareScreenToPreviousCapture(shell_renderer, filename);
+	ComparisonResult result = CompareScreenToPreviousCapture(shell_renderer, filename, true, nullptr);
 
 	return result;
 }
@@ -546,31 +546,42 @@ void TestNavigator::UpdateGoToText(bool out_of_bounds)
 		viewer->SetGoToText("Go To out of bounds");
 	else if (goto_index > 0)
 		viewer->SetGoToText(Rml::CreateString(64, "Go To: %d", goto_index));
-	else if(goto_index == 0)
+	else if (goto_index == 0)
 		viewer->SetGoToText("Go To:");
-	else if (show_reference)
-		viewer->SetGoToText("Showing reference capture '" + GetImageFilenameFromCurrentTest() + "'");
 	else if (iteration_state == IterationState::Capture)
 		viewer->SetGoToText("Capturing all tests");
 	else if (iteration_state == IterationState::Comparison)
 		viewer->SetGoToText("Comparing all tests");
+	else if (show_reference)
+		viewer->SetGoToText(Rml::CreateString(100, "Showing reference capture (%.1f%% similar)", reference_comparison.similarity_score * 100.));
 	else
 		viewer->SetGoToText("Press 'F1' for keyboard shortcuts.");
 }
 
-void TestNavigator::ShowReference(bool in_show_reference)
+void TestNavigator::ShowReference(bool show, bool clear)
 {
-	show_reference = in_show_reference;
-	ReleaseTextureGeometry(shell_renderer, reference_geometry);
+	if (clear)
+	{
+		ReleaseTextureGeometry(shell_renderer, reference_geometry);
+		reference_comparison = {};
+	}
 
 	Rml::String error_msg;
-	if (show_reference)
-		show_reference = LoadPreviousCapture(shell_renderer, GetImageFilenameFromCurrentTest(), reference_geometry, error_msg);
+	if (show && !reference_geometry.texture_handle)
+	{
+		reference_comparison = CompareScreenToPreviousCapture(shell_renderer, GetImageFilenameFromCurrentTest(), false, &reference_geometry);
+
+		if (!reference_comparison.success)
+			error_msg = reference_comparison.error_msg;
+	}
 
+	show_reference = (show && reference_comparison.success && !reference_comparison.is_equal);
 	viewer->SetAttention(show_reference);
 
 	if (!error_msg.empty())
 		viewer->SetGoToText(error_msg);
+	else if (reference_comparison.is_equal)
+		viewer->SetGoToText("EQUAL to reference capture");
 	else
 		UpdateGoToText();
 }

+ 3 - 1
Tests/Source/VisualTests/TestNavigator.h

@@ -65,7 +65,7 @@ private:
 
 	void UpdateGoToText(bool out_of_bounds = false);
 
-	void ShowReference(bool show);
+	void ShowReference(bool show, bool clear);
 
 	Rml::String GetImageFilenameFromCurrentTest();
 
@@ -79,7 +79,9 @@ private:
 	int suite_index = 0;
 	int goto_index = -1;
 	SourceType source_state = SourceType::None;
+
 	bool show_reference = false;
+	ComparisonResult reference_comparison;
 	TextureGeometry reference_geometry;
 
 	IterationState iteration_state = IterationState::None;