summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-07-27 17:22:24 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-07-27 17:22:24 +0000
commitf467c975765552fd92aa06cffb26a1311d05cf98 (patch)
tree91894dd521778db91913978b55cae1c848130a38 /libvo
parent14e64d20c214600764f5229144088b2f1e3a5889 (diff)
downloadmpv-f467c975765552fd92aa06cffb26a1311d05cf98.tar.bz2
mpv-f467c975765552fd92aa06cffb26a1311d05cf98.tar.xz
More helper functions/defines and bugfixes
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@16118 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libvo')
-rw-r--r--libvo/gl_common.c110
-rw-r--r--libvo/gl_common.h30
-rw-r--r--libvo/vo_gl.c78
3 files changed, 153 insertions, 65 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c
index 20e39b9af1..e68bc75d69 100644
--- a/libvo/gl_common.c
+++ b/libvo/gl_common.c
@@ -1,3 +1,5 @@
+#include <stdlib.h>
+#include <string.h>
#include "gl_common.h"
void (APIENTRY *BindBuffer)(GLenum, GLuint);
@@ -57,23 +59,19 @@ static const struct gl_name_map_struct gl_name_map[] = {
MAP(GL_ALPHA), MAP(GL_LUMINANCE), MAP(GL_LUMINANCE_ALPHA),
MAP(GL_COLOR_INDEX),
// rest 1.2 only
-#ifdef GL_VERSION_1_2
MAP(GL_BGR), MAP(GL_BGRA),
-#endif
//type
MAP(GL_BYTE), MAP(GL_UNSIGNED_BYTE), MAP(GL_SHORT), MAP(GL_UNSIGNED_SHORT),
MAP(GL_INT), MAP(GL_UNSIGNED_INT), MAP(GL_FLOAT), MAP(GL_DOUBLE),
MAP(GL_2_BYTES), MAP(GL_3_BYTES), MAP(GL_4_BYTES),
// rest 1.2 only
-#ifdef GL_VERSION_1_2
MAP(GL_UNSIGNED_BYTE_3_3_2), MAP(GL_UNSIGNED_BYTE_2_3_3_REV),
MAP(GL_UNSIGNED_SHORT_5_6_5), MAP(GL_UNSIGNED_SHORT_5_6_5_REV),
MAP(GL_UNSIGNED_SHORT_4_4_4_4), MAP(GL_UNSIGNED_SHORT_4_4_4_4_REV),
MAP(GL_UNSIGNED_SHORT_5_5_5_1), MAP(GL_UNSIGNED_SHORT_1_5_5_5_REV),
MAP(GL_UNSIGNED_INT_8_8_8_8), MAP(GL_UNSIGNED_INT_8_8_8_8_REV),
MAP(GL_UNSIGNED_INT_10_10_10_2), MAP(GL_UNSIGNED_INT_2_10_10_10_REV),
-#endif
{0, 0}
};
#undef MAP
@@ -140,7 +138,6 @@ int glFindFormat(uint32_t fmt, uint32_t *bpp, GLenum *gl_texfmt,
*gl_format = GL_LUMINANCE;
*gl_type = GL_UNSIGNED_BYTE;
break;
-#ifdef GL_VERSION_1_2
#if 0
// we do not support palettized formats, although the format the
// swscale produces works
@@ -184,7 +181,6 @@ int glFindFormat(uint32_t fmt, uint32_t *bpp, GLenum *gl_texfmt,
*gl_format = GL_BGRA;
*gl_type = GL_UNSIGNED_BYTE;
break;
-#endif
default:
*gl_texfmt = 4;
*gl_format = GL_RGBA;
@@ -203,6 +199,9 @@ static void *setNull(const GLubyte *s) {
static void *(*getProcAddress)(const GLubyte *procName) = NULL;
+/**
+ * \brief find the function pointers of some useful OpenGL extensions
+ */
static void getFunctions() {
if (!getProcAddress)
getProcAddress = setNull;
@@ -256,6 +255,96 @@ static void getFunctions() {
ProgramEnvParameter4f = getProcAddress("glProgramEnvParameter4fNV");
}
+/**
+ * \brief create a texture and set some defaults
+ * \param target texture taget, usually GL_TEXTURE_2D
+ * \param fmt internal texture format
+ * \param filter filter used for scaling, e.g. GL_LINEAR
+ * \param w texture width
+ * \param h texture height
+ * \param val luminance value to fill texture with
+ */
+void glCreateClearTex(GLenum target, GLenum fmt, GLint filter,
+ int w, int h, char val) {
+ GLenum clrfmt = (fmt == GL_ALPHA) ? GL_ALPHA : GL_LUMINANCE;
+ char *init = (char *)malloc(w * h);
+ memset(init, val, w * h);
+ glAdjustAlignment(w);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
+ glTexImage2D(target, 0, fmt, w, h, 0, clrfmt, GL_UNSIGNED_BYTE, init);
+ glTexParameterf(target, GL_TEXTURE_PRIORITY, 1.0);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ free(init);
+}
+
+/**
+ * \brief return the number of bytes oer pixel for the given format
+ * \param format OpenGL format
+ * \param type OpenGL type
+ * \return bytes per pixel
+ *
+ * Does not handle all possible variants, just those use by MPlayer
+ */
+int glFmt2bpp(GLenum format, GLenum type) {
+ switch (type) {
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ return 1;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return 2;
+ }
+ if (type != GL_UNSIGNED_BYTE)
+ return 0; //not implemented
+ switch (format) {
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ return 1;
+ case GL_RGB:
+ case GL_BGR:
+ return 3;
+ case GL_RGBA:
+ case GL_BGRA:
+ return 4;
+ }
+ return 0; // unkown
+}
+
+/**
+ * \brief upload a texture, handling things like stride and slices
+ * \param target texture target, usually GL_TEXTURE_2D
+ * \param format OpenGL format of data
+ * \param type OpenGL type of data
+ * \param data data to upload
+ * \param stride data stride
+ * \param x x offset in texture
+ * \param y y offset in texture
+ * \param w width of the texture part to upload
+ * \param h height of the texture part to upload
+ * \param slice height of an upload slice, 0 for all at once
+ */
+void glUploadTex(GLenum target, GLenum format, GLenum type,
+ const char *data, int stride,
+ int x, int y, int w, int h, int slice) {
+ int y_max = y + h;
+ if (slice <= 0)
+ slice = h;
+ // this is not always correct, but should work for MPlayer
+ glAdjustAlignment(stride);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
+ for (; y + slice <= y_max; y += slice) {
+ glTexSubImage2D(target, 0, x, y, w, slice, format, type, data);
+ data += stride * slice;
+ }
+ if (y < y_max)
+ glTexSubImage2D(target, 0, x, y, w, y_max - y, format, type, data);
+}
+
#ifdef GL_WIN32
static void *w32gpa(const GLubyte *procName) {
return wglGetProcAddress(procName);
@@ -326,10 +415,9 @@ void releaseGlContext(int *vinfo, HGLRC *context) {
*context = 0;
}
#else
-#if defined(__sun) || defined(__sgi)
-extern void *dlopen(const char *, int);
+#ifdef HAVE_LIBDL
+#include <dlfcn.h>
#endif
-extern void *dlsym(void *, const char *);
/**
* \brief find address of a linked function
* \param s name of function to find
@@ -338,12 +426,16 @@ extern void *dlsym(void *, const char *);
* Copied from xine
*/
static void *getdladdr(const GLubyte *s) {
+#ifdef HAVE_LIBDL
#if defined(__sun) || defined(__sgi)
static void *handle = dlopen(NULL, RTLD_LAZY);
return dlsym(handle, s);
#else
return dlsym(0, s);
#endif
+#else
+ return NULL;
+#endif
}
/**
diff --git a/libvo/gl_common.h b/libvo/gl_common.h
index 62d34ef5fd..e4e442b3c6 100644
--- a/libvo/gl_common.h
+++ b/libvo/gl_common.h
@@ -29,6 +29,30 @@
#ifndef GL_WRITE_ONLY
#define GL_WRITE_ONLY 0x88B9
#endif
+#ifndef GL_BGR
+#define GL_BGR 0x80E0
+#endif
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+#ifndef GL_UNSIGNED_BYTE_3_3_2
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#endif
+#ifndef GL_UNSIGNED_BYTE_2_3_3_REV
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_6_5
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_6_5_REV
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_5_5_1
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#endif
+#ifndef GL_UNSIGNED_SHORT_1_5_5_5_REV
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#endif
void glAdjustAlignment(int stride);
@@ -36,6 +60,12 @@ const char *glValName(GLint value);
int glFindFormat(uint32_t format, uint32_t *bpp, GLenum *gl_texfmt,
GLenum *gl_format, GLenum *gl_type);
+int glFmt2bpp(GLenum format, GLenum type);
+void glCreateClearTex(GLenum target, GLenum fmt, GLint filter,
+ int w, int h, char val);
+void glUploadTex(GLenum target, GLenum format, GLenum type,
+ const char *data, int stride,
+ int x, int y, int w, int h, int slice);
//! could not set new window, will continue drawing into the old one.
#define SET_WINDOW_FAILED -1
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index b7933a6dde..e3a513e60a 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -64,7 +64,6 @@ 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;
@@ -134,7 +133,6 @@ static void texSize(int w, int h, int *texw, int *texh) {
* \brief Initialize a (new or reused) OpenGL context.
*/
static int initGl(uint32_t d_width, uint32_t d_height) {
- unsigned char *ImageData = NULL;
texSize(image_width, image_height, &texture_width, &texture_height);
glDisable(GL_BLEND);
@@ -146,18 +144,8 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
texture_width, texture_height);
- 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_target, 0, gl_texfmt, texture_width, texture_height, 0,
- gl_format, gl_type, ImageData);
- free (ImageData);
-
- // set alignment as default is 4 which will break some files
- glAdjustAlignment(image_width * image_bytes);
+ glCreateClearTex(gl_target, gl_texfmt, GL_LINEAR,
+ texture_width, texture_height, 0);
resize(d_width, d_height);
@@ -174,10 +162,10 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
static uint32_t
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
{
+ int tmp;
image_height = height;
image_width = width;
- glFindFormat(format, &image_bytes, &gl_texfmt, &gl_format, &gl_type);
- image_bytes = (image_bytes + 7) / 8;
+ glFindFormat(format, &tmp, &gl_texfmt, &gl_format, &gl_type);
int_pause = 0;
@@ -321,7 +309,6 @@ static void create_osd_texture(int x0, int y0, int w, int h,
int sx = 8, sy = 8;
GLfloat xcov, ycov;
GLint scale_type = (scaled_osd) ? GL_LINEAR : GL_NEAREST;
- char *clearTexture;
texSize(w, h, &sx, &sy);
xcov = (GLfloat) w / (GLfloat) sx;
ycov = (GLfloat) h / (GLfloat) sy;
@@ -334,38 +321,29 @@ static void create_osd_texture(int x0, int y0, int w, int h,
mp_msg(MSGT_VO, MSGL_ERR, "Too many OSD parts, contact the developers!\n");
return;
}
- clearTexture = malloc(sx * sy);
- memset(clearTexture, 0, sx * sy);
// create Textures for OSD part
- glAdjustAlignment(stride);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
glGenTextures(1, &osdtex[osdtexCnt]);
BindTexture(gl_target, osdtex[osdtexCnt]);
- glTexImage2D(gl_target, 0, GL_LUMINANCE, sx, sy, 0,
- GL_LUMINANCE, GL_UNSIGNED_BYTE, clearTexture);
- 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);
+ glCreateClearTex(gl_target, GL_LUMINANCE, scale_type, sx, sy, 0);
+ glUploadTex(gl_target, GL_LUMINANCE, GL_UNSIGNED_BYTE, src, stride,
+ 0, 0, w, h, 0);
#ifndef FAST_OSD
glGenTextures(1, &osdatex[osdtexCnt]);
BindTexture(gl_target, osdatex[osdtexCnt]);
- glTexImage2D(gl_target, 0, GL_ALPHA, sx, sy, 0,
- GL_LUMINANCE, GL_UNSIGNED_BYTE, clearTexture);
- glTexParameteri(gl_target, GL_TEXTURE_MIN_FILTER, scale_type);
- glTexParameteri(gl_target, GL_TEXTURE_MAG_FILTER, scale_type);
+ glCreateClearTex(gl_target, GL_ALPHA, scale_type, sx, sy, 0);
+ {
+ char *tmp = (char *)malloc(stride * h);
for (i = 0; i < h * stride; i++)
- clearTexture[i] = ~(-srca[i]);
- glTexSubImage2D(gl_target, 0, 0, 0, w, h, GL_ALPHA,
- GL_UNSIGNED_BYTE, clearTexture);
+ tmp[i] = ~(-srca[i]);
+ glUploadTex(gl_target, GL_ALPHA, GL_UNSIGNED_BYTE, tmp, stride,
+ 0, 0, w, h, 0);
+ free(tmp);
+ }
#endif
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glAdjustAlignment(image_width * image_bytes);
BindTexture(gl_target, 0);
- free(clearTexture);
// Create a list for rendering this OSD part
osdDispList[osdtexCnt] = glGenLists(1);
@@ -489,7 +467,8 @@ static uint32_t get_image(mp_image_t *mpi) {
return VO_FALSE;
}
if (mpi->flags & MP_IMGFLAG_READABLE) return VO_FALSE;
- if (mpi->type == MP_IMGTYPE_STATIC) return VO_FALSE;
+ if (mpi->type == MP_IMGTYPE_IP || mpi->type == MP_IMGTYPE_IPB)
+ return VO_FALSE; // we can not provide readable buffers
BindBuffer(GL_PIXEL_UNPACK_BUFFER, 1);
mpi->stride[0] = mpi->width * mpi->bpp / 8;
if (mpi->stride[0] * mpi->h > gl_buffersize) {
@@ -497,6 +476,7 @@ static uint32_t get_image(mp_image_t *mpi) {
NULL, GL_STREAM_DRAW);
gl_buffersize = mpi->stride[0] * mpi->h;
}
+ UnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // HACK, needed for some MPEG4 files??
mpi->planes[0] = MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
if (mpi->planes[0] == NULL) {
@@ -512,31 +492,17 @@ static uint32_t get_image(mp_image_t *mpi) {
static uint32_t draw_image(mp_image_t *mpi) {
char *data = mpi->planes[0];
- int x = mpi->x;
- int y = mpi->y;
- int y_max = mpi->y + mpi->h;
- int h = slice_height ? slice_height : mpi->h;
+ int slice = slice_height;
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_target, 0, x, y,
- mpi->w, h,
- gl_format, gl_type,
- data);
- data += mpi->stride[0] * h;
+ slice = 0; // always "upload" full texture
}
- if (y < y_max)
- glTexSubImage2D(gl_target, 0, x, y, mpi->w, y_max - y,
- gl_format, gl_type, data);
+ glUploadTex(gl_target, gl_format, gl_type, data, mpi->stride[0],
+ mpi->x, mpi->y, mpi->w, mpi->h, slice);
if (mpi->flags & MP_IMGFLAG_DIRECT)
BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
return VO_TRUE;