Test gltexture update functionality
authorMatthias Clasen <mclasen@redhat.com>
Mon, 15 May 2023 16:50:28 +0000 (12:50 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 15 May 2023 16:50:28 +0000 (12:50 -0400)
testsuite/gdk/gltexture.c
testsuite/gdk/meson.build

index 1b964e7c752b01a59192c0ca28a8eec19a364829..f1145647c3400ac8a543f4204761a42d214f289a 100644 (file)
@@ -1,5 +1,6 @@
 #include <gtk/gtk.h>
 #include <epoxy/gl.h>
+#include "gdk/gdktextureprivate.h"
 
 static cairo_surface_t *
 make_surface (void)
@@ -20,6 +21,23 @@ make_surface (void)
   return surface;
 }
 
+static unsigned int
+make_gl_texture (GdkGLContext    *context,
+                 cairo_surface_t *surface)
+{
+  unsigned int id;
+
+  glGenTextures (1, &id);
+  glActiveTexture (GL_TEXTURE0);
+  glBindTexture (GL_TEXTURE_2D, id);
+  glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, 64, 64, 0, GL_BGRA, GL_UNSIGNED_BYTE,
+                cairo_image_surface_get_data (surface));
+
+  g_assert_true (glGetError () == GL_NO_ERROR);
+
+  return id;
+}
+
 enum {
   SAME_CONTEXT,
   NO_CONTEXT,
@@ -59,13 +77,7 @@ test_gltexture (int test)
 
   gdk_gl_context_make_current (context);
 
-  glGenTextures (1, &id);
-  glActiveTexture (GL_TEXTURE0);
-  glBindTexture (GL_TEXTURE_2D, id);
-  glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, 64, 64, 0, GL_BGRA, GL_UNSIGNED_BYTE,
-                cairo_image_surface_get_data (surface));
-
-  g_assert_true (glGetError () == GL_NO_ERROR);
+  id = make_gl_texture (context, surface);
 
   if (test == NO_CONTEXT)
     gdk_gl_context_clear_current ();
@@ -122,6 +134,98 @@ test_gltexture_shared_context (void)
   test_gltexture (SHARED_CONTEXT);
 }
 
+static void
+test_gltexture_updates (void)
+{
+  GdkDisplay *display;
+  GdkGLContext *context;
+  GdkGLTextureBuilder *builder;
+  cairo_surface_t *surface;
+  GError *error = NULL;
+  unsigned int id;
+  guchar *data;
+  gpointer sync;
+  GdkTexture *old_texture;
+  GdkTexture *texture;
+  cairo_region_t *update_region, *diff;
+
+  display = gdk_display_get_default ();
+  if (!gdk_display_prepare_gl (display, &error))
+    {
+      g_test_message ("no GL support: %s", error->message);
+      g_test_skip ("no GL support");
+      g_clear_error (&error);
+      return;
+    }
+
+  context = gdk_display_create_gl_context (display, &error);
+  g_assert_nonnull (context);
+  g_assert_no_error (error);
+
+  builder = gdk_gl_texture_builder_new ();
+  gdk_gl_texture_builder_set_id (builder, 10);
+
+  surface = make_surface ();
+
+  gdk_gl_context_make_current (context);
+
+  id = make_gl_texture (context, surface);
+
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  old_texture = gdk_gl_texture_new (context, id, 64, 64, NULL, NULL);
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+  id = make_gl_texture (context, surface);
+
+  sync = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+
+  update_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { 10, 10, 32, 32 });
+
+  builder = gdk_gl_texture_builder_new ();
+  g_object_set (builder,
+                "context", context,
+                "id", id,
+                "width", 64,
+                "height", 64,
+                "sync", sync,
+                "update-texture", old_texture,
+                "update-region", update_region,
+                NULL);
+
+  g_assert_true (gdk_gl_texture_builder_get_sync (builder) == sync);
+  g_assert_true (gdk_gl_texture_builder_get_update_texture (builder) == old_texture);
+  g_assert_true (cairo_region_equal (gdk_gl_texture_builder_get_update_region (builder), update_region));
+
+  texture = gdk_gl_texture_builder_build (builder, NULL, NULL);
+
+  data = g_malloc0 (64 * 64 * 4);
+  gdk_texture_download (texture, data, 64 * 4);
+
+  g_assert_true (memcmp (data, cairo_image_surface_get_data (surface), 64 * 64 * 4) == 0);
+
+  diff = cairo_region_create ();
+  gdk_texture_diff (texture, old_texture, diff);
+  g_assert_true (cairo_region_equal (diff, update_region));
+  cairo_region_destroy (diff);
+
+  diff = cairo_region_create ();
+  gdk_texture_diff (old_texture, texture, diff);
+  g_assert_true (cairo_region_equal (diff, update_region));
+  cairo_region_destroy (diff);
+
+  g_free (data);
+  g_object_unref (texture);
+  g_object_unref (builder);
+
+  cairo_surface_destroy (surface);
+
+  glDeleteSync (sync);
+  cairo_region_destroy (update_region);
+  g_object_unref (old_texture);
+
+  g_object_unref (context);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -130,6 +234,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/gltexture/same-context", test_gltexture_same_context);
   g_test_add_func ("/gltexture/no-context", test_gltexture_no_context);
   g_test_add_func ("/gltexture/shared-context", test_gltexture_shared_context);
+  g_test_add_func ("/gltexture/updates", test_gltexture_updates);
 
   return g_test_run ();
 }
index 157c9d4daaa0dd2453bc398ba50d45d49cb795bf..32a31da5ad28e5cfb45918676a91ac8b181c1c05 100644 (file)
@@ -17,7 +17,6 @@ tests = [
   { 'name': 'displaymanager' },
   { 'name': 'encoding' },
   { 'name': 'glcontext' },
-  { 'name': 'gltexture' },
   { 'name': 'keysyms' },
   { 'name': 'memorytexture' },
   { 'name': 'rectangle' },
@@ -55,6 +54,7 @@ endforeach
 internal_tests = [
   'image',
   'texture',
+  'gltexture',
 ]
 
 foreach t : internal_tests