changeset 28067:7511f7328d93

Add experimental support for glXAllocateMemoryMESA
author reimar
date Fri, 05 Dec 2008 22:16:45 +0000
parents ccffc23bf229
children 279cc24cb5cc
files libvo/gl_common.c libvo/gl_common.h libvo/vo_gl.c
diffstat 3 files changed, 33 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/gl_common.c	Fri Dec 05 21:46:28 2008 +0000
+++ b/libvo/gl_common.c	Fri Dec 05 22:16:45 2008 +0000
@@ -77,6 +77,8 @@
 int (APIENTRY *SwapInterval)(int);
 void (APIENTRY *TexImage3D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei,
                             GLint, GLenum, GLenum, const GLvoid *);
+void* (APIENTRY *AllocateMemoryMESA)(void *, int, size_t, float, float, float);
+void (APIENTRY *FreeMemoryMESA)(void *, int, void *);
 /** \} */ // end of glextfunctions group
 
 //! \defgroup glgeneral OpenGL general helper functions
@@ -312,6 +314,8 @@
   {&ProgramEnvParameter4f, "_program", {"glProgramEnvParameter4fARB", NULL}},
   {&SwapInterval, "_swap_control", {"glXSwapInterval", "glXSwapIntervalEXT", "glXSwapIntervalSGI", "wglSwapInterval", "wglSwapIntervalEXT", "wglSwapIntervalSGI", NULL}},
   {&TexImage3D, NULL, {"glTexImage3D", NULL}},
+  {&AllocateMemoryMESA, "GLX_MESA_allocate_memory", {"glXAllocateMemoryMESA", NULL}},
+  {&FreeMemoryMESA, "GLX_MESA_allocate_memory", {"glXFreeMemoryMESA", NULL}},
   {NULL}
 };
 
--- a/libvo/gl_common.h	Fri Dec 05 21:46:28 2008 +0000
+++ b/libvo/gl_common.h	Fri Dec 05 22:16:45 2008 +0000
@@ -384,5 +384,7 @@
 extern int (APIENTRY *SwapInterval)(int);
 extern void (APIENTRY *TexImage3D)(GLenum, GLint, GLenum, GLsizei, GLsizei,
                              GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+extern void* (APIENTRY *AllocateMemoryMESA)(void *, int, size_t, float, float, float);
+extern void (APIENTRY *FreeMemoryMESA)(void *, int, void *);
 
 #endif /* MPLAYER_GL_COMMON_H */
--- a/libvo/vo_gl.c	Fri Dec 05 21:46:28 2008 +0000
+++ b/libvo/vo_gl.c	Fri Dec 05 22:16:45 2008 +0000
@@ -85,6 +85,7 @@
 static int many_fmts;
 static int ati_hack;
 static int force_pbo;
+static int mesa_buffer;
 static int use_glFinish;
 static int swap_interval;
 static GLenum gl_target;
@@ -97,6 +98,8 @@
 static int gl_buffersize_uv;
 static void *gl_bufferptr;
 static void *gl_bufferptr_uv[2];
+static int mesa_buffersize;
+static void *mesa_bufferptr;
 static GLuint fragprog;
 static GLuint default_texs[22];
 static char *custom_prog;
@@ -389,6 +392,9 @@
     DeleteBuffers(2, gl_buffer_uv);
   gl_buffer_uv[0] = gl_buffer_uv[1] = 0; gl_buffersize_uv = 0;
   gl_bufferptr_uv[0] = gl_bufferptr_uv[1] = 0;
+  if (mesa_bufferptr)
+    FreeMemoryMESA(mDisplay, mScreen, mesa_bufferptr);
+  mesa_bufferptr = NULL;
   err_shown = 0;
 }
 
@@ -694,11 +700,23 @@
     mpi->width = texture_width;
     mpi->height = texture_height;
   }
+  mpi->stride[0] = mpi->width * mpi->bpp / 8;
+  needed_size = mpi->stride[0] * mpi->height;
+  if (mesa_buffer) {
+#ifndef GL_WIN32
+    if (mesa_bufferptr && needed_size > mesa_buffersize) {
+      FreeMemoryMESA(mDisplay, mScreen, mesa_bufferptr);
+      mesa_bufferptr = NULL;
+    }
+    if (!mesa_bufferptr)
+      mesa_bufferptr = AllocateMemoryMESA(mDisplay, mScreen, needed_size, 0, 0, 0);
+    mesa_buffersize = needed_size;
+#endif
+    mpi->planes[0] = mesa_bufferptr;
+  } else {
   if (!gl_buffer)
     GenBuffers(1, &gl_buffer);
   BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer);
-  mpi->stride[0] = mpi->width * mpi->bpp / 8;
-  needed_size = mpi->stride[0] * mpi->height;
   if (needed_size > gl_buffersize) {
     gl_buffersize = needed_size;
     BufferData(GL_PIXEL_UNPACK_BUFFER, gl_buffersize,
@@ -708,6 +726,7 @@
     gl_bufferptr = MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
   mpi->planes[0] = gl_bufferptr;
   BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+  }
   if (!mpi->planes[0]) {
     if (!err_shown)
       mp_msg(MSGT_VO, MSGL_ERR, "[gl] could not acquire buffer for dr\n"
@@ -772,7 +791,7 @@
   stride[0] = mpi->stride[0]; stride[1] = mpi->stride[1]; stride[2] = mpi->stride[2];
   planes[0] = mpi->planes[0]; planes[1] = mpi->planes[1]; planes[2] = mpi->planes[2];
   mpi_flipped = stride[0] < 0;
-  if (mpi->flags & MP_IMGFLAG_DIRECT) {
+  if (!mesa_buffer && mpi->flags & MP_IMGFLAG_DIRECT) {
     intptr_t base = (intptr_t)planes[0];
     if (mpi_flipped)
       base += (mpi->h - 1) * stride[0];
@@ -782,10 +801,11 @@
     BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer);
     UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
     gl_bufferptr = NULL;
-    slice = 0; // always "upload" full texture
     if (!(mpi->flags & MP_IMGFLAG_COMMON_PLANE))
       planes[0] = planes[1] = planes[2] = NULL;
   }
+  if (mpi->flags & MP_IMGFLAG_DIRECT)
+    slice = 0; // always "upload" full texture
   glUploadTex(gl_target, gl_format, gl_type, planes[0], stride[0],
               mpi->x, mpi->y, w, h, slice);
   if (mpi->imgfmt == IMGFMT_YV12) {
@@ -807,7 +827,7 @@
                 mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice);
     ActiveTexture(GL_TEXTURE0);
   }
-  if (mpi->flags & MP_IMGFLAG_DIRECT)
+  if (!mesa_buffer && mpi->flags & MP_IMGFLAG_DIRECT)
     BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 skip_upload:
   if (vo_doublebuffering) do_render();
@@ -872,6 +892,7 @@
   {"filter-strength", OPT_ARG_FLOAT, &filter_strength, NULL},
   {"ati-hack",     OPT_ARG_BOOL, &ati_hack,     NULL},
   {"force-pbo",    OPT_ARG_BOOL, &force_pbo,    NULL},
+  {"mesa-buffer",  OPT_ARG_BOOL, &mesa_buffer,  NULL},
   {"glfinish",     OPT_ARG_BOOL, &use_glFinish, NULL},
   {"swapinterval", OPT_ARG_INT,  &swap_interval,NULL},
   {"customprog",   OPT_ARG_MSTRZ,&custom_prog,  NULL},
@@ -898,6 +919,7 @@
     use_glFinish = 0;
     ati_hack = 0;
     force_pbo = 0;
+    mesa_buffer = 0;
     swap_interval = 1;
     slice_height = 0;
     custom_prog = NULL;