gl/memory/tests: split test into separate subtests
authorMatthew Waters <matthew@centricular.com>
Wed, 14 Mar 2018 07:20:54 +0000 (18:20 +1100)
committerMatthew Waters <matthew@centricular.com>
Sat, 5 May 2018 11:24:25 +0000 (21:24 +1000)
Allows for more fine-grained notification of failures

tests/check/libs/gstglmemory.c

index f1c3203..4373e09 100644 (file)
@@ -49,284 +49,460 @@ teardown (void)
   gst_object_unref (context);
 }
 
-GST_START_TEST (test_basic)
+/* one red rgba pixel */
+static guint8 rgba_pixel[] = {
+  0xff, 0x00, 0x00, 0xff,
+};
+
+static const struct
+{
+  GstVideoFormat format;
+  guint width;
+  guint height;
+  guint plane;
+  guint8 *data;
+  gsize size;
+} formats[] = {
+  {
+  GST_VIDEO_FORMAT_RGBA, 1, 1, 0, rgba_pixel, 4}, {
+  GST_VIDEO_FORMAT_RGB, 1, 1, 0, rgba_pixel, 3}, {
+  GST_VIDEO_FORMAT_YUY2, 1, 1, 0, rgba_pixel, 1}, {
+GST_VIDEO_FORMAT_I420, 1, 1, 0, rgba_pixel, 1},};
+
+GST_START_TEST (test_allocator_alloc)
 {
-  GstMemory *mem, *mem2;
-  GstGLMemory *gl_mem, *gl_mem2;
   GstAllocator *gl_allocator;
-  GstGLBaseMemoryAllocator *base_mem_alloc;
-  gint i, j;
-  static GstVideoFormat formats[] = {
-    GST_VIDEO_FORMAT_RGBA, GST_VIDEO_FORMAT_RGB,
-    GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_I420
-  };
+  GstMemory *mem;
 
   gl_allocator = gst_allocator_find (GST_GL_MEMORY_ALLOCATOR_NAME);
-  fail_if (gl_allocator == NULL);
-  base_mem_alloc = GST_GL_BASE_MEMORY_ALLOCATOR (gl_allocator);
 
-  /* test allocator creation */
   ASSERT_WARNING (mem = gst_allocator_alloc (gl_allocator, 0, NULL));
-
-  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
-    GstVideoInfo v_info;
-    gsize width = 320, height = 240;
-
-    gst_video_info_set_format (&v_info, formats[i], width, height);
-
-    for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&v_info); j++) {
-      GstGLFormat tex_format = gst_gl_format_from_video_info (context,
-          &v_info, j);
-      GstGLVideoAllocationParams *params;
-
-      params = gst_gl_video_allocation_params_new (context, NULL, &v_info, j,
-          NULL, GST_GL_TEXTURE_TARGET_2D, tex_format);
-
-      mem = (GstMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
-          (GstGLAllocationParams *) params);
-      fail_if (mem == NULL);
-      gl_mem = (GstGLMemory *) mem;
-
-      /* test init params */
-      fail_if (gst_video_info_is_equal (&v_info, &gl_mem->info) == FALSE);
-      fail_if (gl_mem->mem.context != context);
-      fail_if (gl_mem->tex_id == 0);
-
-      /* copy the memory */
-      mem2 = gst_memory_copy (mem, 0, -1);
-      fail_if (mem2 == NULL);
-      gl_mem2 = (GstGLMemory *) mem2;
-
-      /* test params */
-      fail_if (gst_video_info_is_equal (&gl_mem2->info,
-              &gl_mem->info) == FALSE);
-      fail_if (gl_mem->mem.context != gl_mem2->mem.context);
-
-      gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
-      gst_memory_unref (mem);
-      gst_memory_unref (mem2);
-    }
-  }
+  fail_unless (mem == NULL);
 
   gst_object_unref (gl_allocator);
 }
 
 GST_END_TEST;
 
-/* one red rgba pixel */
-static gchar rgba_pixel[] = {
-  0xff, 0x00, 0x00, 0xff,
-};
+GST_START_TEST (test_allocator_pbo_alloc)
+{
+  GstAllocator *gl_allocator;
+  GstMemory *mem;
 
-static void
-test_transfer_allocator (const gchar * allocator_name)
+  gl_allocator = gst_allocator_find (GST_GL_MEMORY_PBO_ALLOCATOR_NAME);
+
+  ASSERT_WARNING (mem = gst_allocator_alloc (gl_allocator, 0, NULL));
+  fail_unless (mem == NULL);
+
+  gst_object_unref (gl_allocator);
+}
+
+GST_END_TEST;
+
+static GstMemory *
+create_memory (const gchar * allocator_name, GstVideoInfo * v_info, guint plane)
 {
   GstAllocator *gl_allocator;
   GstGLBaseMemoryAllocator *base_mem_alloc;
-  GstVideoInfo v_info;
-  GstMemory *mem, *mem2, *mem3;
-  GstMapInfo map_info;
   GstGLVideoAllocationParams *params;
+  GstGLMemory *gl_mem;
+  GstMemory *mem;
+
+  GST_DEBUG ("creating from %s texture for format %s, %ux%u plane %u",
+      allocator_name, GST_VIDEO_INFO_NAME (v_info),
+      GST_VIDEO_INFO_WIDTH (v_info), GST_VIDEO_INFO_HEIGHT (v_info), plane);
 
   gl_allocator = gst_allocator_find (allocator_name);
   fail_if (gl_allocator == NULL);
   base_mem_alloc = GST_GL_BASE_MEMORY_ALLOCATOR (gl_allocator);
 
-  gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 1, 1);
-
-  params = gst_gl_video_allocation_params_new (context, NULL, &v_info, 0,
+  params = gst_gl_video_allocation_params_new (context, NULL, v_info, plane,
       NULL, GST_GL_TEXTURE_TARGET_2D, GST_GL_RGBA);
 
   /* texture creation */
   mem = (GstMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
       (GstGLAllocationParams *) params);
-  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
+  gl_mem = (GstGLMemory *) mem;
   fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
   fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
-  /* test wrapping raw data */
+  fail_unless_equals_int (TRUE, gst_video_info_is_equal (v_info,
+          &gl_mem->info));
+  fail_unless_equals_int (plane, gl_mem->plane);
+  fail_if (gl_mem->mem.context != context);
+  fail_if (gl_mem->tex_id == 0);
+
+  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
+  gst_object_unref (gl_allocator);
+
+  return mem;
+}
+
+GST_START_TEST (test_allocator_create)
+{
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
+    GstVideoInfo v_info;
+    GstMemory *mem;
+
+    gst_video_info_set_format (&v_info, formats[i].format, formats[i].width,
+        formats[i].height);
+    mem = create_memory (GST_GL_MEMORY_ALLOCATOR_NAME, &v_info,
+        formats[i].plane);
+    gst_memory_unref (mem);
+    mem = create_memory (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info,
+        formats[i].plane);
+    gst_memory_unref (mem);
+  }
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_memory_copy)
+{
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
+    GstVideoInfo v_info;
+    GstMemory *mem, *mem2;
+    GstGLMemory *gl_mem, *gl_mem2;
+
+    gst_video_info_set_format (&v_info, formats[i].format, formats[i].width,
+        formats[i].height);
+    mem = create_memory (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info,
+        formats[i].plane);
+    gl_mem = (GstGLMemory *) mem;
+    mem2 = gst_memory_copy (mem, 0, -1);
+    gl_mem2 = (GstGLMemory *) mem;
+
+    fail_unless (gl_mem->mem.context == context);
+    fail_unless_equals_int (gl_mem->tex_id, gl_mem2->tex_id);
+    fail_unless_equals_int (gl_mem->tex_target, gl_mem2->tex_target);
+    fail_unless_equals_int (gl_mem->tex_format, gl_mem2->tex_format);
+    fail_unless_equals_int (TRUE, gst_video_info_is_equal (&gl_mem2->info,
+            &gl_mem->info));
+    fail_unless_equals_int (gl_mem->plane, gl_mem2->plane);
+
+    gst_memory_unref (mem);
+    gst_memory_unref (mem2);
+  }
+}
+
+GST_END_TEST;
+
+static GstMemory *
+wrap_raw_data (const gchar * allocator_name, GstVideoInfo * v_info,
+    guint plane, guint8 * data)
+{
+  GstAllocator *gl_allocator;
+  GstGLBaseMemoryAllocator *base_mem_alloc;
+  GstGLVideoAllocationParams *params;
+  GstMemory *mem;
+  GstGLMemory *gl_mem;
+  GstGLFormat gl_format;
+
+  GST_DEBUG ("wrapping from %s data pointer %p for format %s, %ux%u plane %u",
+      allocator_name, data, GST_VIDEO_INFO_NAME (v_info),
+      GST_VIDEO_INFO_WIDTH (v_info), GST_VIDEO_INFO_HEIGHT (v_info), plane);
+
+  gl_allocator = gst_allocator_find (allocator_name);
+  fail_if (gl_allocator == NULL);
+  base_mem_alloc = GST_GL_BASE_MEMORY_ALLOCATOR (gl_allocator);
+
+  gl_format = gst_gl_format_from_video_info (context, v_info, plane);
   params = gst_gl_video_allocation_params_new_wrapped_data (context, NULL,
-      &v_info, 0, NULL, GST_GL_TEXTURE_TARGET_2D,
-      GST_GL_RGBA, rgba_pixel, NULL, NULL);
-  mem2 =
+      v_info, plane, NULL, GST_GL_TEXTURE_TARGET_2D,
+      gl_format, data, NULL, NULL);
+  mem =
       (GstMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
       (GstGLAllocationParams *) params);
-  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
+  gl_mem = (GstGLMemory *) mem;
   fail_if (mem == NULL);
 
-  fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
-  /* wrapped texture creation */
-  params = gst_gl_video_allocation_params_new_wrapped_texture (context, NULL,
-      &v_info, 0, NULL, GST_GL_TEXTURE_TARGET_2D,
-      GST_GL_RGBA, ((GstGLMemory *) mem)->tex_id, NULL, NULL);
-  mem3 =
-      (GstMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
-      (GstGLAllocationParams *) params);
+  fail_unless_equals_int (TRUE, gst_video_info_is_equal (v_info,
+          &gl_mem->info));
+  fail_unless_equals_int (gl_mem->plane, plane);
+
   gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (GST_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
+  gst_object_unref (gl_allocator);
 
-  /* check data/flags are correct */
-  fail_unless (gst_memory_map (mem2, &map_info, GST_MAP_READ));
+  return mem;
+}
 
-  fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
+GST_START_TEST (test_wrap_raw)
+{
+  int i;
 
-  fail_unless (memcmp (map_info.data, rgba_pixel,
-          G_N_ELEMENTS (rgba_pixel)) == 0,
-      "0x%02x%02x%02x%02x != 0x%02x%02x%02x%02x", map_info.data[0],
-      map_info.data[1], map_info.data[2], map_info.data[3],
-      (guint8) rgba_pixel[0], (guint8) rgba_pixel[1], (guint8) rgba_pixel[2],
-      (guint8) rgba_pixel[3]);
+  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
+    GstVideoInfo v_info;
+    GstMemory *mem;
+    GstGLMemory *gl_mem;
+    GstMapInfo map_info;
 
-  gst_memory_unmap (mem2, &map_info);
+    gst_video_info_set_format (&v_info, formats[i].format, formats[i].width,
+        formats[i].height);
+    mem = wrap_raw_data (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info,
+        formats[i].plane, formats[i].data);
+    gl_mem = (GstGLMemory *) mem;
 
-  fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
+    fail_unless (gl_mem->mem.context == context);
 
-  fail_unless (gst_memory_map (mem2, &map_info, GST_MAP_READ | GST_MAP_GL));
+    fail_unless (gst_memory_map (mem, &map_info, GST_MAP_READ));
+    fail_unless (memcmp (map_info.data, formats[i].data, formats[i].size) == 0);
+    gst_memory_unmap (mem, &map_info);
 
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
+    gst_memory_unref (mem);
+  }
+}
 
-  /* test texture copy */
-  fail_unless (gst_gl_memory_copy_into ((GstGLMemory *) mem2,
-          ((GstGLMemory *) mem)->tex_id, GST_GL_TEXTURE_TARGET_2D,
-          GST_GL_RGBA, 1, 1));
-  GST_MINI_OBJECT_FLAG_SET (mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD);
+GST_END_TEST;
+
+static GstMemory *
+wrap_gl_memory (GstGLMemory * gl_mem)
+{
+  GstGLBaseMemoryAllocator *base_mem_alloc;
+  GstGLVideoAllocationParams *params;
+  GstMemory *mem, *mem2;
+  GstGLMemory *gl_mem2;
+
+  mem = (GstMemory *) gl_mem;
+  base_mem_alloc = GST_GL_BASE_MEMORY_ALLOCATOR (mem->allocator);
+
+  GST_DEBUG ("wrapping from %s %" GST_PTR_FORMAT " for format %s, %ux%u "
+      "plane %u", mem->allocator->mem_type, gl_mem,
+      GST_VIDEO_INFO_NAME (&gl_mem->info), GST_VIDEO_INFO_WIDTH (&gl_mem->info),
+      GST_VIDEO_INFO_HEIGHT (&gl_mem->info), gl_mem->plane);
+
+  params = gst_gl_video_allocation_params_new_wrapped_texture (context, NULL,
+      &gl_mem->info, gl_mem->plane, NULL, gl_mem->tex_target,
+      gl_mem->tex_format, gl_mem->tex_id, NULL, NULL);
+  mem2 =
+      (GstMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
+      (GstGLAllocationParams *) params);
+  gl_mem2 = (GstGLMemory *) mem2;
+  fail_if (mem == NULL);
 
   fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (GST_MEMORY_FLAG_IS_SET (mem,
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
-  gst_memory_unmap (mem2, &map_info);
+  fail_unless (gl_mem->mem.context == context);
+  fail_unless_equals_int (gl_mem->tex_id, gl_mem2->tex_id);
+  fail_unless_equals_int (gl_mem->tex_target, gl_mem2->tex_target);
+  fail_unless_equals_int (gl_mem->tex_format, gl_mem2->tex_format);
+  fail_unless_equals_int (TRUE, gst_video_info_is_equal (&gl_mem2->info,
+          &gl_mem->info));
+  fail_unless_equals_int (gl_mem->plane, gl_mem2->plane);
 
-  /* test download of copied texture */
-  fail_unless (gst_memory_map (mem, &map_info, GST_MAP_READ));
+  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
 
-  fail_unless (memcmp (map_info.data, rgba_pixel,
-          G_N_ELEMENTS (rgba_pixel)) == 0,
-      "0x%02x%02x%02x%02x != 0x%02x%02x%02x%02x", (guint8) map_info.data[0],
-      (guint8) map_info.data[1], (guint8) map_info.data[2],
-      (guint8) map_info.data[3], (guint8) rgba_pixel[0], (guint8) rgba_pixel[1],
-      (guint8) rgba_pixel[2], (guint8) rgba_pixel[3]);
+  return mem2;
+}
 
-  gst_memory_unmap (mem, &map_info);
+GST_START_TEST (test_wrap_gl_memory)
+{
+  int i;
 
-  /* test download of wrapped copied texture */
-  fail_unless (gst_memory_map (mem3, &map_info, GST_MAP_READ));
+  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
+    GstVideoInfo v_info;
+    GstMemory *mem, *mem2;
+    GstGLMemory *gl_mem;
+
+    gst_video_info_set_format (&v_info, formats[i].format, formats[i].width,
+        formats[i].height);
+    mem = create_memory (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info,
+        formats[i].plane);
+    gl_mem = (GstGLMemory *) mem;
+    mem2 = wrap_gl_memory (gl_mem);
+
+    gst_memory_unref (mem);
+    gst_memory_unref (mem2);
+  }
+}
 
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
+GST_END_TEST;
 
-  fail_unless (memcmp (map_info.data, rgba_pixel,
-          G_N_ELEMENTS (rgba_pixel)) == 0,
-      "0x%02x%02x%02x%02x != 0x%02x%02x%02x%02x", (guint8) map_info.data[0],
-      (guint8) map_info.data[1], (guint8) map_info.data[2],
-      (guint8) map_info.data[3], (guint8) rgba_pixel[0], (guint8) rgba_pixel[1],
-      (guint8) rgba_pixel[2], (guint8) rgba_pixel[3]);
+GST_START_TEST (test_wrap_data_copy_into)
+{
+  int i;
+
+  /* FIXME: in GLES2 only supported with RGBA */
+  for (i = 0; i < 1 /*G_N_ELEMENTS (formats) */ ; i++) {
+    GstVideoInfo v_info;
+    GstMemory *mem, *mem2;
+    GstGLMemory *gl_mem, *gl_mem2;
+    GstMapInfo map_info;
+
+    gst_video_info_set_format (&v_info, formats[i].format, formats[i].width,
+        formats[i].height);
+    /* wrap some data */
+    mem = wrap_raw_data (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info,
+        formats[i].plane, formats[i].data);
+    gl_mem = (GstGLMemory *) mem;
+    mem2 = create_memory (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info,
+        formats[i].plane);
+    gl_mem2 = (GstGLMemory *) mem2;
+
+    fail_unless (gst_memory_map (mem, &map_info, GST_MAP_READ | GST_MAP_GL));
+
+    /* copy wrapped data into another texture */
+    fail_unless (gst_gl_memory_copy_into (gl_mem,
+            gl_mem2->tex_id, GST_GL_TEXTURE_TARGET_2D, gl_mem2->tex_format,
+            formats[i].width, formats[i].height));
+    GST_MINI_OBJECT_FLAG_SET (mem2, GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD);
+
+    fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+            GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
+    fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+            GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
+    fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+            GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
+    fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
+            GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
+
+    gst_memory_unmap (mem, &map_info);
+
+    /* check copied texture is the same as the wrapped data */
+    fail_unless (gst_memory_map (mem2, &map_info, GST_MAP_READ));
+    fail_unless (memcmp (map_info.data, formats[i].data, formats[i].size) == 0);
+    gst_memory_unmap (mem2, &map_info);
+
+    gst_memory_unref (mem);
+    gst_memory_unref (mem2);
+  }
+}
+
+GST_END_TEST;
 
-  gst_memory_unmap (mem3, &map_info);
+GST_START_TEST (test_transfer_state)
+{
+  GstVideoInfo v_info;
+  GstMapInfo map_info;
+  GstMemory *mem;
 
-  /* test upload flag */
-  fail_unless (gst_memory_map (mem3, &map_info, GST_MAP_WRITE));
-  gst_memory_unmap (mem3, &map_info);
+  gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 1, 1);
+  mem = create_memory (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info, 0);
 
-  fail_unless (GST_MEMORY_FLAG_IS_SET (mem3,
+  /* initial state is no transfer needed */
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem3,
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
-  /* test download flag */
-  fail_unless (gst_memory_map (mem3, &map_info, GST_MAP_WRITE | GST_MAP_GL));
-  gst_memory_unmap (mem3, &map_info);
-
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem3,
+  GST_DEBUG ("read-only map");
+  gst_memory_map (mem, &map_info, GST_MAP_READ);
+  gst_memory_unmap (mem, &map_info);
+  /* read map does not change transfer state */
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
-  fail_unless (GST_MEMORY_FLAG_IS_SET (mem3,
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
-  gst_memory_unref (mem);
-  gst_memory_unref (mem2);
-  gst_memory_unref (mem3);
-  gst_object_unref (gl_allocator);
-}
+  GST_DEBUG ("read/GL-only map");
+  gst_memory_map (mem, &map_info, GST_MAP_READ | GST_MAP_GL);
+  gst_memory_unmap (mem, &map_info);
+  /* read | GL map does not change transfer state */
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
+  GST_DEBUG ("write-only map");
+  gst_memory_map (mem, &map_info, GST_MAP_WRITE);
+  gst_memory_unmap (mem, &map_info);
+  /* write map causes need-upload */
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
-GST_START_TEST (test_transfer)
-{
-  test_transfer_allocator (GST_GL_MEMORY_ALLOCATOR_NAME);
-  test_transfer_allocator (GST_GL_MEMORY_PBO_ALLOCATOR_NAME);
+  GST_DEBUG ("write/GL-only map");
+  gst_memory_map (mem, &map_info, GST_MAP_WRITE | GST_MAP_GL);
+  gst_memory_unmap (mem, &map_info);
+  /* write | GL map from need-upload causes only need-download */
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 }
 
 GST_END_TEST;
 
-GST_START_TEST (test_separate_transfer)
+GST_START_TEST (test_separate_upload_transfer)
 {
-  GstGLBaseMemoryAllocator *base_mem_alloc;
-  GstGLVideoAllocationParams *params;
-  GstAllocator *gl_allocator;
   GstVideoInfo v_info;
   GstMemory *mem;
   GstMapInfo info;
 
-  gl_allocator = gst_allocator_find (GST_GL_MEMORY_PBO_ALLOCATOR_NAME);
-  fail_if (gl_allocator == NULL);
-  base_mem_alloc = GST_GL_BASE_MEMORY_ALLOCATOR (gl_allocator);
-
   gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 1, 1);
-
-  params = gst_gl_video_allocation_params_new_wrapped_data (context, NULL,
-      &v_info, 0, NULL, GST_GL_TEXTURE_TARGET_2D,
-      GST_GL_RGBA, rgba_pixel, NULL, NULL);
   mem =
-      (GstMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
-      (GstGLAllocationParams *) params);
-  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
-  fail_if (mem == NULL);
-  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
-
+      wrap_raw_data (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info, 0, rgba_pixel);
   gst_gl_memory_pbo_upload_transfer ((GstGLMemoryPBO *) mem);
 
   fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
           GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD));
 
-  fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
+  /* complete the upload */
+  fail_unless (gst_memory_map (mem, &info, GST_MAP_READ | GST_MAP_GL));
+  gst_memory_unmap (mem, &info);
 
+  /* force a download */
+  fail_unless (gst_memory_map (mem, &info, GST_MAP_WRITE | GST_MAP_GL));
+  gst_memory_unmap (mem, &info);
+
+  /* check the downloaded data is the same */
+  fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
   fail_unless (memcmp (info.data, rgba_pixel, G_N_ELEMENTS (rgba_pixel)) == 0,
       "0x%02x%02x%02x%02x != 0x%02x%02x%02x%02x", (guint8) info.data[0],
       (guint8) info.data[1], (guint8) info.data[2],
       (guint8) info.data[3], (guint8) rgba_pixel[0], (guint8) rgba_pixel[1],
       (guint8) rgba_pixel[2], (guint8) rgba_pixel[3]);
+  gst_memory_unmap (mem, &info);
+
+  gst_memory_unref (mem);
+}
+
+GST_END_TEST;
 
+GST_START_TEST (test_separate_download_transfer)
+{
+  GstVideoInfo v_info;
+  GstMemory *mem;
+  GstMapInfo info;
+
+  gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 1, 1);
+  mem =
+      wrap_raw_data (GST_GL_MEMORY_PBO_ALLOCATOR_NAME, &v_info, 0, rgba_pixel);
+
+  /* complete the upload */
+  fail_unless (gst_memory_map (mem, &info, GST_MAP_READ | GST_MAP_GL));
+  gst_memory_unmap (mem, &info);
+
+  /* force a download */
+  fail_unless (gst_memory_map (mem, &info, GST_MAP_WRITE | GST_MAP_GL));
   gst_memory_unmap (mem, &info);
 
-  /* FIXME: add download transfer */
+  gst_gl_memory_pbo_download_transfer ((GstGLMemoryPBO *) mem);
+
+  /* check the downloaded data is the same */
+  fail_unless (gst_memory_map (mem, &info, GST_MAP_READ));
+  fail_unless (memcmp (info.data, rgba_pixel, G_N_ELEMENTS (rgba_pixel)) == 0,
+      "0x%02x%02x%02x%02x != 0x%02x%02x%02x%02x", (guint8) info.data[0],
+      (guint8) info.data[1], (guint8) info.data[2],
+      (guint8) info.data[3], (guint8) rgba_pixel[0], (guint8) rgba_pixel[1],
+      (guint8) rgba_pixel[2], (guint8) rgba_pixel[3]);
+  gst_memory_unmap (mem, &info);
 
   gst_memory_unref (mem);
-  gst_object_unref (gl_allocator);
 }
 
 GST_END_TEST;
@@ -339,9 +515,16 @@ gst_gl_memory_suite (void)
 
   suite_add_tcase (s, tc_chain);
   tcase_add_checked_fixture (tc_chain, setup, teardown);
-  tcase_add_test (tc_chain, test_basic);
-  tcase_add_test (tc_chain, test_transfer);
-  tcase_add_test (tc_chain, test_separate_transfer);
+  tcase_add_test (tc_chain, test_allocator_alloc);
+  tcase_add_test (tc_chain, test_allocator_pbo_alloc);
+  tcase_add_test (tc_chain, test_allocator_create);
+  tcase_add_test (tc_chain, test_memory_copy);
+  tcase_add_test (tc_chain, test_wrap_raw);
+  tcase_add_test (tc_chain, test_wrap_gl_memory);
+  tcase_add_test (tc_chain, test_wrap_data_copy_into);
+  tcase_add_test (tc_chain, test_transfer_state);
+  tcase_add_test (tc_chain, test_separate_upload_transfer);
+  tcase_add_test (tc_chain, test_separate_download_transfer);
 
   return s;
 }