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>
This commit is contained in:
Hyunjun Ko 2016-09-22 16:34:38 +09:00 committed by Víctor Manuel Jáquez Leal
parent f974c91d73
commit a80e10ac5c
8 changed files with 142 additions and 15 deletions

View file

@ -32,6 +32,7 @@
#include "gstvaapiutils.h" #include "gstvaapiutils.h"
#include "gstvaapivalue.h" #include "gstvaapivalue.h"
#include "gstvaapidisplay.h" #include "gstvaapidisplay.h"
#include "gstvaapitexturemap.h"
#include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_priv.h"
#include "gstvaapiworkarounds.h" #include "gstvaapiworkarounds.h"
#include "gstvaapiversion.h" #include "gstvaapiversion.h"
@ -2149,3 +2150,28 @@ gst_vaapi_display_has_opengl (GstVaapiDisplay * display)
return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX || return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX ||
klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL); 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);
}

View file

@ -257,6 +257,9 @@ gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display);
gboolean gboolean
gst_vaapi_display_has_opengl (GstVaapiDisplay * display); gst_vaapi_display_has_opengl (GstVaapiDisplay * display);
void
gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display);
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_DISPLAY_H */ #endif /* GST_VAAPI_DISPLAY_H */

View file

@ -232,14 +232,49 @@ gst_vaapi_display_egl_create_window (GstVaapiDisplay * display, GstVaapiID id,
return gst_vaapi_window_egl_new (display, width, height); 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 * static GstVaapiTexture *
gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id, gst_vaapi_display_egl_create_texture (GstVaapiDisplay * display, GstVaapiID id,
guint target, guint format, guint width, guint height) guint target, guint format, guint width, guint height)
{ {
if (id != GST_VAAPI_ID_INVALID) GstVaapiDisplayEGL *dpy = GST_VAAPI_DISPLAY_EGL (display);
return gst_vaapi_texture_egl_new_wrapped (display, id, target, format, GstVaapiTexture *texture;
width, height);
if (id == GST_VAAPI_ID_INVALID)
return gst_vaapi_texture_egl_new (display, target, format, width, height); 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 static void
@ -254,6 +289,10 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass)
gst_vaapi_display_class_init (dpy_class); 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); object_class->size = sizeof (GstVaapiDisplayEGL);
dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_EGL; dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_EGL;
dpy_class->bind_display = (GstVaapiDisplayBindFunc) dpy_class->bind_display = (GstVaapiDisplayBindFunc)
@ -280,6 +319,7 @@ gst_vaapi_display_egl_class_init (GstVaapiDisplayEGLClass * klass)
gst_vaapi_display_egl_create_window; gst_vaapi_display_egl_create_window;
dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc) dpy_class->create_texture = (GstVaapiDisplayCreateTextureFunc)
gst_vaapi_display_egl_create_texture; gst_vaapi_display_egl_create_texture;
dpy_class->get_texture_map = gst_vaapi_display_egl_get_texture_map;
} }
static inline const GstVaapiDisplayClass * static inline const GstVaapiDisplayClass *

View file

@ -24,6 +24,7 @@
#define GST_VAAPI_DISPLAY_EGL_PRIV_H #define GST_VAAPI_DISPLAY_EGL_PRIV_H
#include <gst/vaapi/gstvaapiwindow.h> #include <gst/vaapi/gstvaapiwindow.h>
#include <gst/vaapi/gstvaapitexturemap.h>
#include "gstvaapidisplay_egl.h" #include "gstvaapidisplay_egl.h"
#include "gstvaapidisplay_priv.h" #include "gstvaapidisplay_priv.h"
#include "gstvaapiutils_egl.h" #include "gstvaapiutils_egl.h"
@ -79,6 +80,7 @@ struct _GstVaapiDisplayEGL
EglDisplay *egl_display; EglDisplay *egl_display;
EglContext *egl_context; EglContext *egl_context;
guint gles_version; guint gles_version;
GstVaapiTextureMap *texture_map;
}; };
/** /**
@ -90,6 +92,7 @@ struct _GstVaapiDisplayEGLClass
{ {
/*< private >*/ /*< private >*/
GstVaapiDisplayClass parent_class; GstVaapiDisplayClass parent_class;
GDestroyNotify parent_finalize;
}; };
G_GNUC_INTERNAL G_GNUC_INTERNAL

View file

@ -50,13 +50,48 @@ gst_vaapi_display_glx_create_window (GstVaapiDisplay * display, GstVaapiID id,
gst_vaapi_window_glx_new (display, width, height); 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 * static GstVaapiTexture *
gst_vaapi_display_glx_create_texture (GstVaapiDisplay * display, GstVaapiID id, gst_vaapi_display_glx_create_texture (GstVaapiDisplay * display, GstVaapiID id,
guint target, guint format, guint width, guint height) guint target, guint format, guint width, guint height)
{ {
return id != GST_VAAPI_ID_INVALID ? GstVaapiTexture *texture;
gst_vaapi_texture_glx_new_wrapped (display, id, target, format) : GstVaapiDisplayGLX *dpy = GST_VAAPI_DISPLAY_GLX (display);
gst_vaapi_texture_glx_new (display, target, format, width, height);
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 static void
@ -68,10 +103,15 @@ gst_vaapi_display_glx_class_init (GstVaapiDisplayGLXClass * klass)
gst_vaapi_display_x11_class_init (&klass->parent_class); 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); object_class->size = sizeof (GstVaapiDisplayGLX);
dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; dpy_class->display_type = GST_VAAPI_DISPLAY_TYPE_GLX;
dpy_class->create_window = gst_vaapi_display_glx_create_window; dpy_class->create_window = gst_vaapi_display_glx_create_window;
dpy_class->create_texture = gst_vaapi_display_glx_create_texture; 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 * static inline const GstVaapiDisplayClass *

View file

@ -25,6 +25,7 @@
#include <gst/vaapi/gstvaapiutils_glx.h> #include <gst/vaapi/gstvaapiutils_glx.h>
#include <gst/vaapi/gstvaapidisplay_glx.h> #include <gst/vaapi/gstvaapidisplay_glx.h>
#include <gst/vaapi/gstvaapitexturemap.h>
#include "gstvaapidisplay_x11_priv.h" #include "gstvaapidisplay_x11_priv.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -53,6 +54,7 @@ struct _GstVaapiDisplayGLX
{ {
/*< private >*/ /*< private >*/
GstVaapiDisplayX11 parent_instance; GstVaapiDisplayX11 parent_instance;
GstVaapiTextureMap *texture_map;
}; };
/** /**
@ -64,6 +66,7 @@ struct _GstVaapiDisplayGLXClass
{ {
/*< private >*/ /*< private >*/
GstVaapiDisplayX11Class parent_class; GstVaapiDisplayX11Class parent_class;
GDestroyNotify parent_finalize;
}; };
G_END_DECLS G_END_DECLS

View file

@ -29,6 +29,7 @@
#include <gst/vaapi/gstvaapidisplaycache.h> #include <gst/vaapi/gstvaapidisplaycache.h>
#include <gst/vaapi/gstvaapiwindow.h> #include <gst/vaapi/gstvaapiwindow.h>
#include <gst/vaapi/gstvaapitexture.h> #include <gst/vaapi/gstvaapitexture.h>
#include <gst/vaapi/gstvaapitexturemap.h>
#include "gstvaapiminiobject.h" #include "gstvaapiminiobject.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -73,6 +74,8 @@ typedef GstVaapiWindow *(*GstVaapiDisplayCreateWindowFunc) (
typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) ( typedef GstVaapiTexture *(*GstVaapiDisplayCreateTextureFunc) (
GstVaapiDisplay * display, GstVaapiID id, guint target, guint format, GstVaapiDisplay * display, GstVaapiID id, guint target, guint format,
guint width, guint height); guint width, guint height);
typedef GstVaapiTextureMap *(*GstVaapiDisplayGetTextureMapFunc) (
GstVaapiDisplay * display);
typedef guintptr (*GstVaapiDisplayGetVisualIdFunc) (GstVaapiDisplay * display, typedef guintptr (*GstVaapiDisplayGetVisualIdFunc) (GstVaapiDisplay * display,
GstVaapiWindow * window); GstVaapiWindow * window);
@ -226,6 +229,7 @@ struct _GstVaapiDisplayClass
GstVaapiDisplayGetColormapFunc get_colormap; GstVaapiDisplayGetColormapFunc get_colormap;
GstVaapiDisplayCreateWindowFunc create_window; GstVaapiDisplayCreateWindowFunc create_window;
GstVaapiDisplayCreateTextureFunc create_texture; GstVaapiDisplayCreateTextureFunc create_texture;
GstVaapiDisplayGetTextureMapFunc get_texture_map;
}; };
/* Initialization types */ /* Initialization types */

View file

@ -176,25 +176,33 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
gst_vaapi_video_meta_get_surface_proxy (vmeta); gst_vaapi_video_meta_get_surface_proxy (vmeta);
GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy); GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy);
GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface); GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface);
GstVaapiTexture *texture = NULL;
if (!gst_vaapi_display_has_opengl (dpy)) if (!gst_vaapi_display_has_opengl (dpy))
return FALSE; return FALSE;
if (!meta_texture->texture || if (meta_texture->texture
/* Check whether VA display changed */ /* 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 */ /* 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? */ /* FIXME: should we assume target? */
GstVaapiTexture *const texture = texture =
gst_vaapi_texture_new_wrapped (dpy, texture_id[0], gst_vaapi_texture_new_wrapped (dpy, texture_id[0],
GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width, GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width,
meta_texture->height); meta_texture->height);
}
if (meta_texture->texture != texture) {
gst_vaapi_texture_replace (&meta_texture->texture, texture); gst_vaapi_texture_replace (&meta_texture->texture, texture);
}
if (!texture) if (!texture)
return FALSE; return FALSE;
gst_vaapi_texture_unref (texture);
}
gst_vaapi_texture_set_orientation_flags (meta_texture->texture, gst_vaapi_texture_set_orientation_flags (meta_texture->texture,
get_texture_orientation_flags (meta->texture_orientation)); get_texture_orientation_flags (meta->texture_orientation));