[Libva] [RFC] OpenGL API extension (v3)

Gwenole Beauchesne gbeauchesne at splitted-desktop.com
Fri Aug 28 02:05:07 PDT 2009


On Fri, 28 Aug 2009, Gwenole Beauchesne wrote:

> The current implementation for NVIDIA shows the API is not very convenient
> and probably inhibits some performance. MPlayer CPU usage for VO (video
> output) now jumps to ~20% whereas it's under 1% in normal 2D display. Note
> that a VA driver for another chipset can make this below 5% for both
> cases. That is, 2D or GL rendering perform as well.

In order to address this problem, and try to make implementations work 
more with their asynchronous functions, I will likely move this v2 API:

vaCopySurfaceToTextureGLX()
vaBindSurfaceToTextureGLX()
vaReleaseSurfaceFromTextureGLX()

to v3 API:

vaCreateSurfaceGLX()
vaDestroySurfaceGLX()
vaAssociateSurfaceGLX()    (if TFP: vaPutSurface(Pixmap,...))
vaDeassociateSurfaceGLX()
vaSyncSurfaceGLX()
vaBeginRenderSurfaceGLX()  (if TFP: glXBindTexImage())
vaEndRenderSurfaceGLX()    (if TFP: glXReleaseTexImage())
vaCopySurfaceGLX()         (if TFP and no direct impl. use FBO)

This also makes it possible to implement TFP + FBO fallbacks effeciently 
since the problem of VA/GLX surface creation/destruction is delegated to 
specific functions. i.e. no lookup table or other trickery is required.

I have inlined the new <va/va_glx.h> header hereunder.

TODO:
- Cosmetics: right function names?
- Add a VA/GLX specific function table?
- Probably make vaCreateSurfaceGLX() take a pointer to a GLXContext?

/**
  * Return a suitable VADisplay for VA API
  *
  * @param[in] dpy the X11 display
  * @return a VADisplay
  */
VADisplay vaGetDisplayGLX(
     Display *dpy
);

/**
  * Create a surface used for display to OpenGL
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  target     the GL target to which the texture needs to be bound
  * @param[in]  texture    the GL texture
  * @param[out] gl_surface the VA surface
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaCreateSurfaceGLX(
     VADisplay dpy,
     GLenum    target,
     GLuint    texture,
     void    **gl_surface
);

/**
  * Destroy a VA/GLX surface
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  gl_surface the VA surface
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaDestroySurfaceGLX(
     VADisplay dpy,
     void     *gl_surface
);

/**
  * Associate a VA surface to a VA/GLX surface
  *
  * The association is live until vaDeassociateSurfaceGLX(),
  * vaCopySurfaceGLX() or the next call to vaBeginPicture() with the
  * specificed VA surface.
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  gl_surface the VA API surface
  * @param[in]  surface    the VA API surface
  * @param[in]  flags      the PutSurface flags
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaAssociateSurfaceGLX(
     VADisplay    dpy,
     void        *gl_surface,
     VASurfaceID  surface,
     unsigned int flags
);

/**
  * Deassociate a VA surface from a VA/GLX surface
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  gl_surface the VA surface
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaDeassociateSurfaceGLX(
     VADisplay dpy,
     void     *gl_surface
);

/**
  * Synchronize a VA/GLX surface
  *
  * This function blocks until all pending operations on the VA/GLX
  * surface have been completed.
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  gl_surface the VA surface
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaSyncSurfaceGLX(
     VADisplay dpy,
     void     *gl_surface
);

/**
  * Prepare VA/GLX surface for rendering
  *
  * This function performs an implicit vaSyncSurfaceGLX().
  *
  * Implementations using the GLX texture-from-pixmap extension will
  * generally call glXBindTexImage() here.
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  gl_surface the VA surface
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaBeginRenderSurfaceGLX(
     VADisplay dpy,
     void     *gl_surface
);

/**
  * Notify the server that the VA/GLX surface is no longer used for
  * rendering
  *
  * Implementations using the GLX texture-from-pixmap extension will
  * generally call glXReleaseTexImage() here.
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  gl_surface the VA surface
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaEndRenderSurfaceGLX(
     VADisplay dpy,
     void     *gl_surface
);

/**
  * Copy a VA surface to a VA/GLX surface
  *
  * This function kills any association that was previously made with
  * vaAssociateSurfaceGLX() and will not return until the copy is
  * completed.
  *
  * Upon successful return, the underlying GL texture will contain the
  * complete pixels and no call to vaBeginRenderSurfaceGLX() or
  * vaEndRenderSurfaceGLX() is required.
  *
  * The application shall maintain the live GLX context itself.
  * Implementations are free to use glXGetCurrentContext() and
  * glXGetCurrentDrawable() functions for internal purposes.
  *
  * @param[in]  dpy        the VA display
  * @param[in]  gl_surface the VA API surface
  * @param[in]  surface    the VA API surface
  * @param[in]  flags      the PutSurface flags
  * @return VA_STATUS_SUCCESS if successful
  */
VAStatus vaCopySurfaceGLX(
     VADisplay    dpy,
     void        *gl_surface,
     VASurfaceID  surface,
     unsigned int flags
);


More information about the Libva mailing list