diff options
author | Hyunjun Ko <zzoon@igalia.com> | 2016-09-22 16:34:38 +0900 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <victorx.jaquez@intel.com> | 2016-09-22 17:01:59 +0200 |
commit | a80e10ac5c85107592da3ce327d7739415cc9cb7 (patch) | |
tree | fd8980f07075c91c5895857173aafb3be31335bd | |
parent | f974c91d73b669e90cfaeed095c8e6f7dbee9103 (diff) |
libs: display{egl,glx}: cache GstVaapiTextures
instances when created and reuse
This patch improves performance when glimagesink uploads a GL texture.
It caches the GStVaapiTexture instances in GstVaapiDisplay{GLX,EGL}, using an
instance of GstVaapiTextureMap, so our internal texture structure can be found
by matching the GL texture id for each frame upload process, avoiding the
internal texture structure creation and its following destruction.
https://bugzilla.gnome.org/show_bug.cgi?id=769293
Signed-off-by: Víctor Manuel Jáquez Leal <victorx.jaquez@intel.com>
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay.c | 26 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay.h | 3 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_egl.c | 48 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h | 3 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 46 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 3 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 4 | ||||
-rw-r--r-- | gst/vaapi/gstvaapivideometa_texture.c | 22 |
8 files changed, 141 insertions, 14 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index a733423d..32738a11 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -32,6 +32,7 @@ #include "gstvaapiutils.h" #include "gstvaapivalue.h" #include "gstvaapidisplay.h" +#include "gstvaapitexturemap.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiworkarounds.h" #include "gstvaapiversion.h" @@ -2149,3 +2150,28 @@ gst_vaapi_display_has_opengl (GstVaapiDisplay * display) return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX || klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL); } + +/** + * gst_vaapi_display_reset_texture_map: + * @display: a #GstVaapiDisplay + * + * Reset the internal #GstVaapiTextureMap if available. + * + * This function is thread safe. + */ +void +gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display) +{ + GstVaapiDisplayClass *klass; + GstVaapiTextureMap *map; + + g_return_if_fail (display != NULL); + + if (!gst_vaapi_display_has_opengl (display)) + return; + klass = GST_VAAPI_DISPLAY_GET_CLASS (display); + if (!klass->get_texture_map) + return; + if ((map = klass->get_texture_map (display))) + gst_vaapi_texture_map_reset (map); +} diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index f4cc8653..600f276e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -257,6 +257,9 @@ gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display); gboolean gst_vaapi_display_has_opengl (GstVaapiDisplay * display); +void +gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c index feab6408..f049de98 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl.c @@ -232,14 +232,49 @@ gst_vaapi_display_egl_create_window (GstVaapiDisplay * display, GstVaapiID id, return gst_vaapi_window_egl_new (display, width, height); } +static void +ensure_texture_map (GstVaapiDisplayEGL * display) +{ + if (!display->texture_map) + display->texture_map = gst_vaapi_texture_map_new (); +} + static GstVaapiTexture * gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height) { - if (id != GST_VAAPI_ID_INVALID) - return gst_vaapi_texture_egl_new_wrapped (display, id, target, format, - width, height); - return gst_vaapi_texture_egl_new (display, target, format, width, height); + GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (display); + GstVaapiTexture *texture; + + if (id == GST_VAAPI_ID_INVALID) + return gst_vaapi_texture_egl_new (display, target, format, width, height); + + ensure_texture_map (dpy); + if (!(texture = gst_vaapi_texture_map_lookup (dpy->texture_map, id))) { + if ((texture = + gst_vaapi_texture_egl_new_wrapped (display, id, target, format, + width, height))) { + gst_vaapi_texture_map_add (dpy->texture_map, texture, id); + } + } + + return texture; +} + +static GstVaapiTextureMap * +gst_vaapi_display_egl_get_texture_map (GstVaapiDisplay * display) +{ + return GST_VAAPI_DISPLAY_EGL (display)->texture_map; +} + +static void +gst_vaapi_display_egl_finalize (GstVaapiDisplay * display) +{ + GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (display); + + if (dpy->texture_map) + gst_object_unref (dpy->texture_map); + GST_VAAPI_DISPLAY_EGL_GET_CLASS (display)->parent_finalize (display); } static void @@ -254,6 +289,10 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) gst_vaapi_display_class_init (dpy_class); + /* chain up destructor */ + klass->parent_finalize = object_class->finalize; + object_class->finalize = (GDestroyNotify) gst_vaapi_display_egl_finalize; + object_class->size = sizeof (GstVaapiDisplayEGL); dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_EGL; dpy_class->bind_display = (GstVaapiDisplayBindFunc) @@ -280,6 +319,7 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass) gst_vaapi_display_egl_create_window; dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc) gst_vaapi_display_egl_create_texture; + dpy_class->get_texture_map = gst_vaapi_display_egl_get_texture_map; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h index 3db5ad89..96e2b43b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_egl_priv.h @@ -24,6 +24,7 @@ #define GST_VAAPI_DISPLAY_EGL_PRIV_H #include <gst/vaapi/gstvaapiwindow.h> +#include <gst/vaapi/gstvaapitexturemap.h> #include "gstvaapidisplay_egl.h" #include "gstvaapidisplay_priv.h" #include "gstvaapiutils_egl.h" @@ -79,6 +80,7 @@ struct _GstVaapiDisplayEGL EglDisplay *egl_display; EglContext *egl_context; guint gles_version; + GstVaapiTextureMap *texture_map; }; /** @@ -90,6 +92,7 @@ struct _GstVaapiDisplayEGLClass { /*< private >*/ GstVaapiDisplayClass parent_class; + GDestroyNotify parent_finalize; }; G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 32aa7141..9b4a007c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -50,13 +50,48 @@ gst_vaapi_display_glx_create_window (GstVaapiDisplay * display, GstVaapiID id, gst_vaapi_window_glx_new (display, width, height); } +static void +ensure_texture_map (GstVaapiDisplayGLX * display) +{ + if (!display->texture_map) + display->texture_map = gst_vaapi_texture_map_new (); +} + static GstVaapiTexture * gst_vaapi_display_glx_create_texture (GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height) { - return id != GST_VAAPI_ID_INVALID ? - gst_vaapi_texture_glx_new_wrapped (display, id, target, format) : - gst_vaapi_texture_glx_new (display, target, format, width, height); + GstVaapiTexture *texture; + GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (display); + + if (id == GST_VAAPI_ID_INVALID) + return gst_vaapi_texture_glx_new (display, target, format, width, height); + + ensure_texture_map (dpy); + if (!(texture = gst_vaapi_texture_map_lookup (dpy->texture_map, id))) { + if ((texture = + gst_vaapi_texture_glx_new_wrapped (display, id, target, format))) { + gst_vaapi_texture_map_add (dpy->texture_map, texture, id); + } + } + + return texture; +} + +static GstVaapiTextureMap * +gst_vaapi_display_glx_get_texture_map (GstVaapiDisplay * display) +{ + return GST_VAAPI_DISPLAY_GLX (display)->texture_map; +} + +static void +gst_vaapi_display_glx_finalize (GstVaapiDisplay * display) +{ + GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (display); + + if (dpy->texture_map) + gst_object_unref (dpy->texture_map); + GST_VAAPI_DISPLAY_GLX_GET_CLASS (display)->parent_finalize (display); } static void @@ -68,10 +103,15 @@ gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass) gst_vaapi_display_x11_class_init (&klass->parent_class); + /* chain up destructor */ + klass->parent_finalize = object_class->finalize; + object_class->finalize = (GDestroyNotify) gst_vaapi_display_glx_finalize; + object_class->size = sizeof (GstVaapiDisplayGLX); dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; dpy_class->create_window = gst_vaapi_display_glx_create_window; dpy_class->create_texture = gst_vaapi_display_glx_create_texture; + dpy_class->get_texture_map = gst_vaapi_display_glx_get_texture_map; } static inline const GstVaapiDisplayClass * diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index 63f7175c..4da88228 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -25,6 +25,7 @@ #include <gst/vaapi/gstvaapiutils_glx.h> #include <gst/vaapi/gstvaapidisplay_glx.h> +#include <gst/vaapi/gstvaapitexturemap.h> #include "gstvaapidisplay_x11_priv.h" G_BEGIN_DECLS @@ -53,6 +54,7 @@ struct _GstVaapiDisplayGLX { /*< private >*/ GstVaapiDisplayX11 parent_instance; + GstVaapiTextureMap *texture_map; }; /** @@ -64,6 +66,7 @@ struct _GstVaapiDisplayGLXClass { /*< private >*/ GstVaapiDisplayX11Class parent_class; + GDestroyNotify parent_finalize; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index fd50fe79..12b5184b 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -29,6 +29,7 @@ #include <gst/vaapi/gstvaapidisplaycache.h> #include <gst/vaapi/gstvaapiwindow.h> #include <gst/vaapi/gstvaapitexture.h> +#include <gst/vaapi/gstvaapitexturemap.h> #include "gstvaapiminiobject.h" G_BEGIN_DECLS @@ -73,6 +74,8 @@ typedef GstVaapiWindow *(*GstVaapiDisplayCreateWindowFunc) ( typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, guint width, guint height); +typedef GstVaapiTextureMap *(*GstVaapiDisplayGetTextureMapFunc) ( + GstVaapiDisplay * display); typedef guintptr (*GstVaapiDisplayGetVisualIdFunc) (GstVaapiDisplay * display, GstVaapiWindow * window); @@ -226,6 +229,7 @@ struct _GstVaapiDisplayClass GstVaapiDisplayGetColormapFunc get_colormap; GstVaapiDisplayCreateWindowFunc create_window; GstVaapiDisplayCreateTextureFunc create_texture; + GstVaapiDisplayGetTextureMapFunc get_texture_map; }; /* Initialization types */ diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 01e33852..fb1535a7 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -176,26 +176,34 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, gst_vaapi_video_meta_get_surface_proxy (vmeta); GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); + GstVaapiTexture *texture = NULL; if (!gst_vaapi_display_has_opengl (dpy)) return FALSE; - if (!meta_texture->texture || + if (meta_texture->texture /* Check whether VA display changed */ - GST_VAAPI_OBJECT_DISPLAY (meta_texture->texture) != dpy || + && GST_VAAPI_OBJECT_DISPLAY (meta_texture->texture) == dpy /* Check whether texture id changed */ - gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) { + && (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) { + texture = meta_texture->texture; + } + + if (!texture) { /* FIXME: should we assume target? */ - GstVaapiTexture *const texture = + texture = gst_vaapi_texture_new_wrapped (dpy, texture_id[0], GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width, meta_texture->height); + } + + if (meta_texture->texture != texture) { gst_vaapi_texture_replace (&meta_texture->texture, texture); - if (!texture) - return FALSE; - gst_vaapi_texture_unref (texture); } + if (!texture) + return FALSE; + gst_vaapi_texture_set_orientation_flags (meta_texture->texture, get_texture_orientation_flags (meta->texture_orientation)); |