Przeglądaj źródła

Tests: Implement reference image testing for LibGL

Each LibGL test can now be tested against a reference QOI image.
Initially, these images can be generated by setting `SAVE_OUTPUT` to
`true`, which will save a bunch of QOI images to `/home/anon`.
Jelle Raaijmakers 3 lat temu
rodzic
commit
8cfabbcd93

+ 2 - 1
Meta/Lagom/CMakeLists.txt

@@ -590,9 +590,10 @@ if (BUILD_LAGOM)
         endforeach()
 
         # GL
+        file(COPY "${SERENITY_PROJECT_ROOT}/Tests/LibGL/reference-images" DESTINATION "./")
         file(GLOB LIBGL_TESTS CONFIGURE_DEPENDS "../../Tests/LibGL/*.cpp")
         foreach(source ${LIBGL_TESTS})
-            lagom_test(${source} LIBS LagomGL)
+            lagom_test(${source} WORKING_DIRECTORY LIBS LagomGL LagomGPU LagomSoftGPU)
         endforeach()
 
         # PDF

+ 3 - 1
Tests/LibGL/CMakeLists.txt

@@ -3,5 +3,7 @@ set(TEST_SOURCES
 )
 
 foreach(source IN LISTS TEST_SOURCES)
-    serenity_test("${source}" LibGL LIBS LibGL)
+    serenity_test("${source}" LibGL LIBS LibCore LibGL)
 endforeach()
+
+install(DIRECTORY reference-images DESTINATION usr/Tests/LibGL)

+ 71 - 30
Tests/LibGL/TestRender.cpp

@@ -1,60 +1,101 @@
 /*
- * Copyright (c) 2021, Leon Albrecht <leon2002.la@gmail.com>.
+ * Copyright (c) 2021, Leon Albrecht <leon2002.la@gmail.com>
+ * Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <LibTest/TestCase.h>
-
-#include <AK/Debug.h>
-#include <AK/Format.h>
+#include <AK/LexicalPath.h>
+#include <AK/String.h>
+#include <LibCore/FileStream.h>
 #include <LibGL/GL/gl.h>
 #include <LibGL/GLContext.h>
-#include <LibGfx/BMPWriter.h>
 #include <LibGfx/Bitmap.h>
-#include <LibGfx/Font/FontDatabase.h>
-#include <fcntl.h>
-#include <unistd.h>
+#include <LibGfx/QOIWriter.h>
+#include <LibTest/TestCase.h>
 
-#define RENDER_WIDTH 16
-#define RENDER_HEIGHT 16
+#ifdef __serenity__
+#    define REFERENCE_IMAGE_DIR "/usr/Tests/LibGL/reference-images"
+#else
+#    define REFERENCE_IMAGE_DIR "reference-images"
+#endif
+#define SAVE_OUTPUT false
 
-TEST_CASE(simple_triangle)
+static NonnullOwnPtr<GL::GLContext> create_testing_context(int width, int height)
 {
-    auto bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRx8888, { RENDER_WIDTH, RENDER_HEIGHT }));
+    auto bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRx8888, { width, height }));
     auto context = GL::create_context(*bitmap);
-
     GL::make_context_current(context);
+    return context;
+}
+
+static void expect_bitmap_equals_reference(Gfx::Bitmap const& bitmap, StringView test_name)
+{
+    auto reference_filename = String::formatted("{}.qoi", test_name);
+
+    if constexpr (SAVE_OUTPUT) {
+        auto target_path = LexicalPath("/home/anon").append(reference_filename);
+        auto qoi_buffer = Gfx::QOIWriter::encode(bitmap);
+        auto qoi_output_stream = MUST(Core::OutputFileStream::open(target_path.string()));
+        auto number_of_bytes_written = qoi_output_stream.write(qoi_buffer);
+        qoi_output_stream.close();
+        EXPECT_EQ(number_of_bytes_written, qoi_buffer.size());
+    }
+
+    auto reference_image_path = String::formatted(REFERENCE_IMAGE_DIR "/{}", reference_filename);
+    auto reference_bitmap = MUST(Gfx::Bitmap::try_load_from_file(reference_image_path));
+    EXPECT_EQ(reference_bitmap->visually_equals(bitmap), true);
+}
+
+TEST_CASE(0001_simple_triangle)
+{
+    auto context = create_testing_context(64, 64);
 
     glFrontFace(GL_CCW);
     glCullFace(GL_BACK);
     glEnable(GL_CULL_FACE);
-    glEnable(GL_DEPTH_TEST);
 
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-    glClearDepth(1.0);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glClear(GL_COLOR_BUFFER_BIT);
 
     glBegin(GL_TRIANGLES);
-    glColor4f(1, 1, 1, 1);
+    glColor3f(1, 1, 1);
     glVertex2f(0, 1);
     glVertex2f(-1, -1);
     glVertex2f(1, -1);
     glEnd();
 
+    EXPECT_EQ(glGetError(), 0u);
+
     context->present();
+    expect_bitmap_equals_reference(context->frontbuffer(), "0001_simple_triangle");
+}
+
+TEST_CASE(0002_quad_color_interpolation)
+{
+    auto context = create_testing_context(64, 64);
+
+    glFrontFace(GL_CCW);
+    glCullFace(GL_BACK);
+    glEnable(GL_CULL_FACE);
+
+    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glBegin(GL_QUADS);
+
+    glColor3f(1, 0, 0);
+    glVertex2i(-1, -1);
+    glColor3f(0, 1, 0);
+    glVertex2i(1, -1);
+    glColor3f(0, 0, 1);
+    glVertex2i(1, 1);
+    glColor3f(1, 0, 1);
+    glVertex2i(-1, 1);
+    glEnd();
 
     EXPECT_EQ(glGetError(), 0u);
-    // FIXME: Verify that the image is indeed correct
-
-    if constexpr (GL_DEBUG) {
-        // output the image to manually verify that the output is correct
-        Gfx::BMPWriter writer {};
-        auto buffer = writer.dump(bitmap);
-        int fd = open("./picture.bmp", O_CREAT | O_WRONLY, 0755);
-        EXPECT(fd > 0);
-        ssize_t nwritten = write(fd, buffer.data(), buffer.size());
-        EXPECT_EQ((size_t)nwritten, buffer.size());
-        close(fd);
-    }
+
+    context->present();
+    expect_bitmap_equals_reference(context->frontbuffer(), "0002_quad_color_interpolation");
 }

BIN
Tests/LibGL/reference-images/0001_simple_triangle.qoi


BIN
Tests/LibGL/reference-images/0002_quad_color_interpolation.qoi