[MPlayer-cvslog] CVS: main/libvo gl_common.c, 1.6, 1.7 gl_common.h, 1.5, 1.6 vo_gl.c, 1.74, 1.75
Reimar Döffinger CVS
syncmail at mplayerhq.hu
Tue Jul 26 12:16:21 CEST 2005
CVS change done by Reimar Döffinger CVS
Update of /cvsroot/mplayer/main/libvo
In directory mail:/var2/tmp/cvs-serv11791/libvo
Modified Files:
gl_common.c gl_common.h vo_gl.c
Log Message:
support for rectangular and streaming textures.
Index: gl_common.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/gl_common.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- gl_common.c 29 Dec 2004 14:33:40 -0000 1.6
+++ gl_common.c 26 Jul 2005 10:16:18 -0000 1.7
@@ -1,5 +1,24 @@
#include "gl_common.h"
+void (APIENTRY *BindBuffer)(GLenum, GLuint);
+GLvoid* (APIENTRY *MapBuffer)(GLenum, GLenum);
+GLboolean (APIENTRY *UnmapBuffer)(GLenum);
+void (APIENTRY *BufferData)(GLenum, GLsizeiptr, const GLvoid *, GLenum);
+void (APIENTRY *CombinerParameterfv)(GLenum, const GLfloat *);
+void (APIENTRY *CombinerParameteri)(GLenum, GLint);
+void (APIENTRY *CombinerInput)(GLenum, GLenum, GLenum, GLenum, GLenum,
+ GLenum);
+void (APIENTRY *CombinerOutput)(GLenum, GLenum, GLenum, GLenum, GLenum,
+ GLenum, GLenum, GLboolean, GLboolean,
+ GLboolean);
+void (APIENTRY *ActiveTexture)(GLenum);
+void (APIENTRY *BindTexture)(GLenum, GLuint);
+void (APIENTRY *MultiTexCoord2f)(GLenum, GLfloat, GLfloat);
+void (APIENTRY *BindProgram)(GLenum, GLuint);
+void (APIENTRY *ProgramString)(GLenum, GLenum, GLsizei, const GLvoid *);
+void (APIENTRY *ProgramEnvParameter4f)(GLenum, GLuint, GLfloat, GLfloat,
+ GLfloat, GLfloat);
+
/**
* \brief adjusts the GL_UNPACK_ALGNMENT to fit the stride.
* \param stride number of bytes per line for which alignment should fit.
@@ -178,6 +197,65 @@
return 1;
}
+static void *setNull(const GLubyte *s) {
+ return NULL;
+}
+
+static void *(*getProcAddress)(const GLubyte *procName);
+
+static void getFunctions() {
+ if (!getProcAddress)
+ getProcAddress = setNull;
+ BindBuffer = getProcAddress("glBindBuffer");
+ if (!BindBuffer)
+ BindBuffer = getProcAddress("glBindBufferARB");
+ MapBuffer = getProcAddress("glMapBuffer");
+ if (!MapBuffer)
+ MapBuffer = getProcAddress("glMapBufferARB");
+ UnmapBuffer = getProcAddress("glUnmapBuffer");
+ if (!UnmapBuffer)
+ UnmapBuffer = getProcAddress("glUnmapBufferARB");
+ BufferData = getProcAddress("glBufferData");
+ if (!BufferData)
+ BufferData = getProcAddress("glBufferDataARB");
+ CombinerParameterfv = getProcAddress("glCombinerParameterfv");
+ if (!CombinerParameterfv)
+ CombinerParameterfv = getProcAddress("glCombinerParameterfvNV");
+ CombinerParameteri = getProcAddress("glCombinerParameteri");
+ if (!CombinerParameteri)
+ CombinerParameteri = getProcAddress("glCombinerParameteriNV");
+ CombinerInput = getProcAddress("glCombinerInput");
+ if (!CombinerInput)
+ CombinerInput = getProcAddress("glCombinerInputNV");
+ CombinerOutput = getProcAddress("glCombinerOutput");
+ if (!CombinerOutput)
+ CombinerOutput = getProcAddress("glCombinerOutputNV");
+ ActiveTexture = getProcAddress("glActiveTexture");
+ if (!ActiveTexture)
+ ActiveTexture = getProcAddress("glActiveTextureARB");
+ BindTexture = getProcAddress("glBindTexture");
+ if (!BindTexture)
+ BindTexture = getProcAddress("glBindTextureARB");
+ MultiTexCoord2f = getProcAddress("glMultiTexCoord2f");
+ if (!MultiTexCoord2f)
+ MultiTexCoord2f = getProcAddress("glMultiTexCoord2fARB");
+ BindProgram = getProcAddress("glBindProgram");
+ if (!BindProgram)
+ BindProgram = getProcAddress("glBindProgramARB");
+ if (!BindProgram)
+ BindProgram = getProcAddress("glBindProgramNV");
+ ProgramString = getProcAddress("glProgramString");
+ if (!ProgramString)
+ ProgramString = getProcAddress("glProgramStringARB");
+ if (!ProgramString)
+ ProgramString = getProcAddress("glProgramStringNV");
+ ProgramEnvParameter4f = getProcAddress("glProgramEnvParameter4f");
+ if (!ProgramEnvParameter4f)
+ ProgramEnvParameter4f = getProcAddress("glProgramEnvParameter4fARB");
+ if (!ProgramEnvParameter4f)
+ ProgramEnvParameter4f = getProcAddress("glProgramEnvParameter4fNV");
+}
+
#ifdef GL_WIN32
int setGlWindow(int *vinfo, HGLRC *context, HWND win)
{
@@ -226,6 +304,8 @@
wglDeleteContext(*context);
*context = new_context;
*vinfo = new_vinfo;
+ getProcAddress = wglGetProcAddress;
+ getFunctions();
// and inform that reinit is neccessary
return SET_WINDOW_REINIT;
@@ -319,6 +399,12 @@
if (*vinfo)
XFree(*vinfo);
*vinfo = new_vinfo;
+#ifdef GLX_ARB_get_proc_address
+ getProcAddress = (void *)glXGetProcAddressARB;
+#else
+ getProcAddress = NULL;
+#endif
+ getFunctions();
// and inform that reinit is neccessary
return SET_WINDOW_REINIT;
Index: gl_common.h
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/gl_common.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gl_common.h 11 Dec 2004 16:57:42 -0000 1.5
+++ gl_common.h 26 Jul 2005 10:16:18 -0000 1.6
@@ -17,6 +17,19 @@
#include "x11_common.h"
#endif
+#ifndef GL_TEXTURE_RECTANGLE
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#endif
+#ifndef GL_PIXEL_UNPACK_BUFFER
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#endif
+#ifndef GL_STREAM_DRAW
+#define GL_STREAM_DRAW 0x88E0
+#endif
+#ifndef GL_WRITE_ONLY
+#define GL_WRITE_ONLY 0x88B9
+#endif
+
void glAdjustAlignment(int stride);
const char *glValName(GLint value);
@@ -39,4 +52,23 @@
void releaseGlContext(XVisualInfo **vinfo, GLXContext *context);
#endif
+extern void (APIENTRY *BindBuffer)(GLenum, GLuint);
+extern GLvoid* (APIENTRY *MapBuffer)(GLenum, GLenum);
+extern GLboolean (APIENTRY *UnmapBuffer)(GLenum);
+extern void (APIENTRY *BufferData)(GLenum, GLsizeiptr, const GLvoid *, GLenum);
+extern void (APIENTRY *CombinerParameterfv)(GLenum, const GLfloat *);
+extern void (APIENTRY *CombinerParameteri)(GLenum, GLint);
+extern void (APIENTRY *CombinerInput)(GLenum, GLenum, GLenum, GLenum, GLenum,
+ GLenum);
+extern void (APIENTRY *CombinerOutput)(GLenum, GLenum, GLenum, GLenum, GLenum,
+ GLenum, GLenum, GLboolean, GLboolean,
+ GLboolean);
+extern void (APIENTRY *ActiveTexture)(GLenum);
+extern void (APIENTRY *BindTexture)(GLenum, GLuint);
+extern void (APIENTRY *MultiTexCoord2f)(GLenum, GLfloat, GLfloat);
+extern void (APIENTRY *BindProgram)(GLenum, GLuint);
+extern void (APIENTRY *ProgramString)(GLenum, GLenum, GLsizei, const GLvoid *);
+extern void (APIENTRY *ProgramEnvParameter4f)(GLenum, GLuint, GLfloat, GLfloat,
+ GLfloat, GLfloat);
+
#endif
Index: vo_gl.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_gl.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -r1.74 -r1.75
--- vo_gl.c 25 Jul 2005 19:11:14 -0000 1.74
+++ vo_gl.c 26 Jul 2005 10:16:18 -0000 1.75
@@ -55,13 +55,17 @@
static int osdtexCnt = 0;
static int use_aspect;
+static int use_rectangle;
+static int err_shown;
static uint32_t image_width;
static uint32_t image_height;
static uint32_t image_bytes;
static int many_fmts;
+static GLenum gl_target;
static GLenum gl_texfmt;
static GLenum gl_format;
static GLenum gl_type;
+static int gl_buffersize;
static int int_pause;
@@ -106,33 +110,42 @@
}
}
+static void texSize(int w, int h, int *texw, int *texh) {
+ if (use_rectangle) {
+ *texw = w; *texh = h;
+ } else {
+ *texw = 32;
+ while (*texw < w)
+ *texw *= 2;
+ *texh = 32;
+ while (*texh < h)
+ *texh *= 2;
+ }
+}
+
/**
* \brief Initialize a (new or reused) OpenGL context.
*/
static int initGl(uint32_t d_width, uint32_t d_height) {
unsigned char *ImageData = NULL;
- texture_width = 32;
- while (texture_width < image_width ||
- texture_width < image_height)
- texture_width *= 2;
- texture_height = texture_width;
+ texSize(image_width, image_height, &texture_width, &texture_height);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_2D);
+ glEnable(gl_target);
mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
texture_width, texture_height);
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(gl_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glAdjustAlignment(texture_width * image_bytes);
ImageData = malloc(texture_width * texture_height * image_bytes);
memset(ImageData, 0, texture_width * texture_height * image_bytes);
- glTexImage2D(GL_TEXTURE_2D, 0, gl_texfmt, texture_width, texture_height, 0,
+ glTexImage2D(gl_target, 0, gl_texfmt, texture_width, texture_height, 0,
gl_format, gl_type, ImageData);
free (ImageData);
@@ -143,6 +156,8 @@
glClearColor( 0.0f,0.0f,0.0f,0.0f );
glClear( GL_COLOR_BUFFER_BIT );
+ gl_buffersize = 0;
+ err_shown = 0;
return 1;
}
@@ -285,10 +300,13 @@
GLfloat xcov, ycov;
GLint scale_type = (scaled_osd) ? GL_LINEAR : GL_NEAREST;
char *clearTexture;
- while (sx < w) sx *= 2;
- while (sy < h) sy *= 2;
+ texSize(w, h, &sx, &sy);
xcov = (GLfloat) w / (GLfloat) sx;
ycov = (GLfloat) h / (GLfloat) sy;
+ if (use_rectangle == 1) {
+ xcov = w;
+ ycov = h;
+ }
if (osdtexCnt >= MAX_OSD_PARTS) {
mp_msg(MSGT_VO, MSGL_ERR, "Too many OSD parts, contact the developers!\n");
@@ -301,30 +319,30 @@
glAdjustAlignment(stride);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glGenTextures(1, &osdtex[osdtexCnt]);
- glBindTexture(GL_TEXTURE_2D, osdtex[osdtexCnt]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, sx, sy, 0,
+ BindTexture(gl_target, osdtex[osdtexCnt]);
+ glTexImage2D(gl_target, 0, GL_LUMINANCE, sx, sy, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, clearTexture);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, scale_type);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, scale_type);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_LUMINANCE,
+ glTexParameteri(gl_target, GL_TEXTURE_MIN_FILTER, scale_type);
+ glTexParameteri(gl_target, GL_TEXTURE_MAG_FILTER, scale_type);
+ glTexSubImage2D(gl_target, 0, 0, 0, w, h, GL_LUMINANCE,
GL_UNSIGNED_BYTE, src);
#ifndef FAST_OSD
glGenTextures(1, &osdatex[osdtexCnt]);
- glBindTexture(GL_TEXTURE_2D, osdatex[osdtexCnt]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, sx, sy, 0,
+ BindTexture(gl_target, osdatex[osdtexCnt]);
+ glTexImage2D(gl_target, 0, GL_ALPHA, sx, sy, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, clearTexture);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, scale_type);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, scale_type);
+ glTexParameteri(gl_target, GL_TEXTURE_MIN_FILTER, scale_type);
+ glTexParameteri(gl_target, GL_TEXTURE_MAG_FILTER, scale_type);
for (i = 0; i < h * stride; i++)
clearTexture[i] = ~(-srca[i]);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_ALPHA,
+ glTexSubImage2D(gl_target, 0, 0, 0, w, h, GL_ALPHA,
GL_UNSIGNED_BYTE, clearTexture);
#endif
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glAdjustAlignment(image_width * image_bytes);
- glBindTexture(GL_TEXTURE_2D, 0);
+ BindTexture(gl_target, 0);
free(clearTexture);
// Create a list for rendering this OSD part
@@ -333,7 +351,7 @@
#ifndef FAST_OSD
// render alpha
glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, osdatex[osdtexCnt]);
+ BindTexture(gl_target, osdatex[osdtexCnt]);
glBegin(GL_QUADS);
glTexCoord2f (0, 0);
glVertex2f (x0, y0);
@@ -347,7 +365,7 @@
#endif
// render OSD
glBlendFunc (GL_ONE, GL_ONE);
- glBindTexture(GL_TEXTURE_2D, osdtex[osdtexCnt]);
+ BindTexture(gl_target, osdtex[osdtexCnt]);
glBegin(GL_QUADS);
glTexCoord2f (0, 0);
glVertex2f (x0, y0);
@@ -387,6 +405,11 @@
static void
flip_page(void)
{
+ int tc_x = 1, tc_y = 1;
+ if (use_rectangle == 1) {
+ tc_x = texture_width;
+ tc_y = texture_height;
+ }
// glEnable(GL_TEXTURE_2D);
// glBindTexture(GL_TEXTURE_2D, texture_id);
@@ -394,9 +417,9 @@
glColor3f(1,1,1);
glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex2i(0,0);
- glTexCoord2f(0,1);glVertex2i(0,texture_height);
- glTexCoord2f(1,1);glVertex2i(texture_width,texture_height);
- glTexCoord2f(1,0);glVertex2i(texture_width,0);
+ glTexCoord2f(0,tc_y);glVertex2i(0,texture_height);
+ glTexCoord2f(tc_x,tc_y);glVertex2i(texture_width,texture_height);
+ glTexCoord2f(tc_x,0);glVertex2i(texture_width,0);
glEnd();
if (osdtexCnt > 0) {
@@ -414,7 +437,7 @@
glDisable (GL_BLEND);
if (!scaled_osd)
glPopMatrix();
- glBindTexture(GL_TEXTURE_2D, 0);
+ BindTexture(gl_target, 0);
}
// glFlush();
@@ -431,6 +454,28 @@
return 0;
}
+static uint32_t get_image(mp_image_t *mpi) {
+ if (!BindBuffer || !BufferData || !MapBuffer) {
+ if (!err_shown)
+ mp_msg(MSGT_VO, MSGL_ERR, "[gl] extensions missing for dr\n"
+ "Expect a _major_ speed penalty\n");
+ return VO_FALSE;
+ }
+ if (mpi->flags & MP_IMGFLAG_READABLE) return VO_FALSE;
+ if (mpi->type == MP_IMGTYPE_STATIC) return VO_FALSE;
+ BindBuffer(GL_PIXEL_UNPACK_BUFFER, 1);
+ mpi->stride[0] = mpi->width * mpi->bpp / 8;
+ if (mpi->stride[0] * mpi->h > gl_buffersize) {
+ BufferData(GL_PIXEL_UNPACK_BUFFER, mpi->stride[0] * mpi->h,
+ NULL, GL_STREAM_DRAW);
+ gl_buffersize = mpi->stride[0] * mpi->h;
+ }
+ mpi->planes[0] = MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
+ BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ mpi->flags |= MP_IMGFLAG_DIRECT;
+ return VO_TRUE;
+}
+
static uint32_t draw_image(mp_image_t *mpi) {
char *data = mpi->planes[0];
int x = mpi->x;
@@ -439,19 +484,27 @@
int h = slice_height ? slice_height : mpi->h;
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
return VO_TRUE;
+ if (mpi->flags & MP_IMGFLAG_DIRECT) {
+ data = NULL;
+ BindBuffer(GL_PIXEL_UNPACK_BUFFER, 1);
+ UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+ h = mpi->h; // always "upload" full texture
+ }
// this is not always correct, but should work for MPlayer
glAdjustAlignment(mpi->stride[0]);
glPixelStorei(GL_UNPACK_ROW_LENGTH, mpi->stride[0] / (mpi->bpp / 8));
for (y = mpi->y; y + h <= y_max; y += h) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
+ glTexSubImage2D(gl_target, 0, x, y,
mpi->w, h,
gl_format, gl_type,
data);
data += mpi->stride[0] * h;
}
if (y < y_max)
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, mpi->w, y_max - y,
+ glTexSubImage2D(gl_target, 0, x, y, mpi->w, y_max - y,
gl_format, gl_type, data);
+ if (mpi->flags & MP_IMGFLAG_DIRECT)
+ BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
return VO_TRUE;
}
@@ -491,6 +544,7 @@
{"scaled-osd", OPT_ARG_BOOL, &scaled_osd, NULL},
{"aspect", OPT_ARG_BOOL, &use_aspect, NULL},
{"slice-height", OPT_ARG_INT, &slice_height, (opt_test_f)int_non_neg},
+ {"rectangle", OPT_ARG_INT, &use_rectangle,(opt_test_f)int_non_neg},
{NULL}
};
@@ -501,6 +555,7 @@
use_osd = 1;
scaled_osd = 0;
use_aspect = 1;
+ use_rectangle = 0;
slice_height = 4;
if (subopt_parse(arg, subopts) != 0) {
mp_msg(MSGT_VO, MSGL_FATAL,
@@ -515,9 +570,17 @@
" Do not use OpenGL OSD code\n"
" noaspect\n"
" Do not do aspect scaling\n"
+ " rectangle=<0,1,2>\n"
+ " 0: use power-of-two textures\n"
+ " 1: use texture_rectangle\n"
+ " 2: use texture_non_power_of_two\n"
"\n" );
return -1;
}
+ if (use_rectangle == 1)
+ gl_target = GL_TEXTURE_RECTANGLE;
+ else
+ gl_target = GL_TEXTURE_2D;
if (many_fmts)
mp_msg (MSGT_VO, MSGL_WARN, "[gl] using extended formats.\n"
"Make sure you have OpenGL >= 1.2 and used corresponding "
@@ -536,6 +599,8 @@
case VOCTRL_RESUME: return (int_pause=0);
case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data));
+ case VOCTRL_GET_IMAGE:
+ return get_image(data);
case VOCTRL_DRAW_IMAGE:
return draw_image(data);
case VOCTRL_GUISUPPORT:
More information about the MPlayer-cvslog
mailing list