gl/eglimage: add eglimage context feature
authorMatthew Waters <ystreet00@gmail.com>
Wed, 14 May 2014 07:59:52 +0000 (17:59 +1000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:41 +0000 (19:31 +0000)
Allows us to selectively use EGLImages only when available

https://bugzilla.gnome.org/show_bug.cgi?id=728234

ext/gl/gstglimagesink.c
gst-libs/gst/gl/egl/gsteglimagememory.c
gst-libs/gst/gl/egl/gstglcontext_egl.c
gst-libs/gst/gl/egl/gstglcontext_egl.h
gst-libs/gst/gl/gstglfilter.c

index b2a1d07..1311319 100644 (file)
@@ -933,9 +933,12 @@ gst_glimage_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
   gst_object_unref (allocator);
 
 #if GST_GL_HAVE_PLATFORM_EGL
-  allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
-  gst_query_add_allocation_param (query, allocator, &params);
-  gst_object_unref (allocator);
+  if (gst_gl_context_check_feature (glimage_sink->context,
+          "EGL_KHR_image_base")) {
+    allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
+    gst_query_add_allocation_param (query, allocator, &params);
+    gst_object_unref (allocator);
+  }
 #endif
 
   return TRUE;
index 665f4cc..5a023a5 100644 (file)
@@ -122,7 +122,7 @@ gst_egl_image_allocator_free_vfunc (GstAllocator * allocator, GstMemory * mem)
 
   /* Shared memory should not destroy all the data */
   if (!mem->parent) {
-    eglDestroyImageKHR (emem->context->egl_display, emem->image);
+    emem->context->eglDestroyImage (emem->context->egl_display, emem->image);
 
     if (emem->user_data_destroy)
       emem->user_data_destroy (emem->context, emem->user_data);
@@ -163,8 +163,18 @@ gst_egl_image_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
   return FALSE;
 }
 
-typedef GstAllocator GstEGLImageAllocator;
-typedef GstAllocatorClass GstEGLImageAllocatorClass;
+typedef struct _GstEGLImageAllocator GstEGLImageAllocator;
+typedef struct _GstEGLImageAllocatorClass GstEGLImageAllocatorClass;
+
+struct _GstEGLImageAllocator
+{
+  GstAllocator parent;
+};
+
+struct _GstEGLImageAllocatorClass
+{
+  GstAllocatorClass parent_class;
+};
 
 GType gst_egl_image_allocator_get_type (void);
 G_DEFINE_TYPE (GstEGLImageAllocator, gst_egl_image_allocator,
@@ -212,7 +222,7 @@ gst_egl_image_allocator_init_instance (gpointer data)
   return allocator;
 }
 
-static GstAllocator *
+static GstEGLImageAllocator *
 gst_egl_image_allocator_obtain (void)
 {
   static GOnce once = G_ONCE_INIT;
@@ -221,7 +231,7 @@ gst_egl_image_allocator_obtain (void)
 
   g_return_val_if_fail (once.retval != NULL, NULL);
 
-  return GST_ALLOCATOR (g_object_ref (once.retval));
+  return (GstEGLImageAllocator *) (g_object_ref (once.retval));
 }
 
 void
@@ -239,7 +249,7 @@ gst_egl_image_memory_del_gl_texture (GstGLContext * context, gpointer tex)
 }
 
 static GstMemory *
-gst_egl_image_allocator_wrap (GstAllocator * allocator,
+gst_egl_image_allocator_wrap (GstEGLImageAllocator * allocator,
     GstGLContextEGL * context, EGLImageKHR image, GstVideoGLTextureType type,
     GstMemoryFlags flags, gsize size, gpointer user_data,
     GstEGLImageDestroyNotify user_data_destroy)
@@ -255,7 +265,7 @@ gst_egl_image_allocator_wrap (GstAllocator * allocator,
 
   mem = g_slice_new (GstEGLImageMemory);
   gst_memory_init (GST_MEMORY_CAST (mem), flags,
-      allocator, NULL, size, 0, 0, size);
+      GST_ALLOCATOR (allocator), NULL, size, 0, 0, size);
 
   gst_object_unref (allocator);
 
@@ -339,12 +349,14 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info,
   EGLImageKHR image = EGL_NO_IMAGE_KHR;
   EGLClientBuffer client_buffer_tex[3] = { 0, 0, 0 };
   GstVideoGLTextureType texture_types[] = { 0, 0, 0, 0 };
-  GstAllocator *allocator = gst_egl_image_allocator_obtain ();
+  GstEGLImageAllocator *allocator = gst_egl_image_allocator_obtain ();
   GstGLContextEGL *context = GST_GL_CONTEXT_EGL (ctx);
 
   g_return_val_if_fail (ctx, FALSE);
   g_return_val_if_fail (info, FALSE);
   g_return_val_if_fail (buffer, FALSE);
+  g_return_val_if_fail (gst_gl_context_check_feature (ctx,
+          "EGL_KHR_image_base"), FALSE);
 
   memset (stride, 0, sizeof (stride));
   memset (offset, 0, sizeof (offset));
@@ -408,7 +420,7 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info,
         gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0, stride,
             offset, &size, (GLuint *) & client_buffer_tex[0]);
 
-        image = eglCreateImageKHR (context->egl_display,
+        image = context->eglCreateImage (context->egl_display,
             context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[0],
             NULL);
         if (eglGetError () != EGL_SUCCESS)
@@ -461,7 +473,7 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info,
           gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0,
               stride, offset, size, (GLuint *) & client_buffer_tex[i]);
 
-          image = eglCreateImageKHR (context->egl_display,
+          image = context->eglCreateImage (context->egl_display,
               context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i],
               NULL);
           if (eglGetError () != EGL_SUCCESS)
@@ -527,7 +539,7 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info,
           gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, i,
               stride, offset, size, (GLuint *) & client_buffer_tex[i]);
 
-          image = eglCreateImageKHR (context->egl_display,
+          image = context->eglCreateImage (context->egl_display,
               context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i],
               NULL);
           if (eglGetError () != EGL_SUCCESS)
index 06e7a9b..d3c8d96 100644 (file)
@@ -53,6 +53,8 @@ static GstGLPlatform gst_gl_context_egl_get_gl_platform (GstGLContext *
     context);
 static gpointer gst_gl_context_egl_get_proc_address (GstGLContext * context,
     const gchar * name);
+static gboolean gst_gl_context_egl_check_feature (GstGLContext * context,
+    const gchar * feature);
 
 G_DEFINE_TYPE (GstGLContextEGL, gst_gl_context_egl, GST_GL_TYPE_CONTEXT);
 
@@ -78,6 +80,8 @@ gst_gl_context_egl_class_init (GstGLContextEGLClass * klass)
       GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_gl_platform);
   context_class->get_proc_address =
       GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_proc_address);
+  context_class->check_feature =
+      GST_DEBUG_FUNCPTR (gst_gl_context_egl_check_feature);
 }
 
 static void
@@ -404,6 +408,23 @@ gst_gl_context_egl_create_context (GstGLContext * context,
     }
   }
 
+  /* EGLImage functions */
+  if (GST_GL_CHECK_GL_VERSION (majorVersion, minorVersion, 1, 5)) {
+    egl->eglCreateImage = gst_gl_context_get_proc_address (context,
+        "eglCreateImage");
+    egl->eglDestroyImage = gst_gl_context_get_proc_address (context,
+        "eglDestroyImage");
+  } else if (gst_gl_check_extension ("EGL_KHR_image_base", egl_exts)) {
+    egl->eglCreateImage = gst_gl_context_get_proc_address (context,
+        "eglCreateImageKHR");
+    egl->eglDestroyImage = gst_gl_context_get_proc_address (context,
+        "eglDestroyImageKHR");
+  }
+  if (egl->eglCreateImage == NULL || egl->eglDestroyImage == NULL) {
+    egl->eglCreateImage = NULL;
+    egl->eglDestroyImage = NULL;
+  }
+
   if (window)
     gst_object_unref (window);
 
@@ -525,3 +546,16 @@ gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name)
 
   return result;
 }
+
+static gboolean
+gst_gl_context_egl_check_feature (GstGLContext * context, const gchar * feature)
+{
+  GstGLContextEGL *context_egl = GST_GL_CONTEXT_EGL (context);
+
+  if (g_strcmp0 (feature, "EGL_KHR_image_base") == 0) {
+    return context_egl->eglCreateImage != NULL &&
+        context_egl->eglDestroyImage != NULL;
+  }
+
+  return FALSE;
+}
index 5e84d3e..9601865 100644 (file)
@@ -45,6 +45,10 @@ struct _GstGLContextEGL {
   EGLConfig  egl_config;
 
   GstGLAPI gl_api;
+
+  EGLImageKHR (*eglCreateImage) (EGLDisplay dpy, EGLContext ctx, EGLenum target,
+      EGLClientBuffer buffer, const EGLint *attrib_list);
+  EGLBoolean (*eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
 };
 
 struct _GstGLContextEGLClass {
index 2193d21..50db294 100644 (file)
@@ -890,9 +890,11 @@ gst_gl_filter_propose_allocation (GstBaseTransform * trans,
   gst_object_unref (allocator);
 
 #if GST_GL_HAVE_PLATFORM_EGL
-  allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
-  gst_query_add_allocation_param (query, allocator, &params);
-  gst_object_unref (allocator);
+  if (gst_gl_context_check_feature (filter->context, "EGL_KHR_image_base")) {
+    allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
+    gst_query_add_allocation_param (query, allocator, &params);
+    gst_object_unref (allocator);
+  }
 #endif
 
   return TRUE;