diff options
author | wm4 <wm4@mplayer2.org> | 2011-09-25 11:18:07 +0200 |
---|---|---|
committer | Uoti Urpala <uau@mplayer2.org> | 2011-10-24 06:13:17 +0300 |
commit | c852246cdf3e2604d1a3bff1fccd981d7b3b58c9 (patch) | |
tree | 132f089b74befd752483e8c399e432427fe25270 /libvo | |
parent | 821a313ba183b9eed8b280cbfda84a3f95a2ab2e (diff) | |
download | mpv-c852246cdf3e2604d1a3bff1fccd981d7b3b58c9.tar.bz2 mpv-c852246cdf3e2604d1a3bff1fccd981d7b3b58c9.tar.xz |
vo_gl: convert to new API, clean up code
Reformat vo_gl.c, gl_common.c, gl_common.h.
Remove all global variables and move them into a context struct (the
Windows and SDL backends still refer to global_vo though).
Change vo_gl.c to use the "new" VO API.
Diffstat (limited to 'libvo')
-rw-r--r-- | libvo/gl_common.c | 2928 | ||||
-rw-r--r-- | libvo/gl_common.h | 312 | ||||
-rw-r--r-- | libvo/vo_gl.c | 2485 |
3 files changed, 2980 insertions, 2745 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c index eb12d79a74..16e05fb688 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -32,115 +32,19 @@ * \brief OpenGL helper functions used by vo_gl.c and vo_gl2.c */ +#include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <math.h> -#include "old_vo_defines.h" +#include "talloc.h" #include "gl_common.h" +#include "old_vo_wrapper.h" #include "csputils.h" #include "aspect.h" #include "pnm_loader.h" - -void (GLAPIENTRY *mpglBegin)(GLenum); -void (GLAPIENTRY *mpglEnd)(void); -void (GLAPIENTRY *mpglViewport)(GLint, GLint, GLsizei, GLsizei); -void (GLAPIENTRY *mpglMatrixMode)(GLenum); -void (GLAPIENTRY *mpglLoadIdentity)(void); -void (GLAPIENTRY *mpglTranslated)(double, double, double); -void (GLAPIENTRY *mpglScaled)(double, double, double); -void (GLAPIENTRY *mpglOrtho)(double, double, double, double, double, double); -void (GLAPIENTRY *mpglFrustum)(double, double, double, double, double, double); -void (GLAPIENTRY *mpglPushMatrix)(void); -void (GLAPIENTRY *mpglPopMatrix)(void); -void (GLAPIENTRY *mpglClear)(GLbitfield); -GLuint (GLAPIENTRY *mpglGenLists)(GLsizei); -void (GLAPIENTRY *mpglDeleteLists)(GLuint, GLsizei); -void (GLAPIENTRY *mpglNewList)(GLuint, GLenum); -void (GLAPIENTRY *mpglEndList)(void); -void (GLAPIENTRY *mpglCallList)(GLuint); -void (GLAPIENTRY *mpglCallLists)(GLsizei, GLenum, const GLvoid *); -void (GLAPIENTRY *mpglGenTextures)(GLsizei, GLuint *); -void (GLAPIENTRY *mpglDeleteTextures)(GLsizei, const GLuint *); -void (GLAPIENTRY *mpglTexEnvf)(GLenum, GLenum, GLfloat); -void (GLAPIENTRY *mpglTexEnvi)(GLenum, GLenum, GLint); -void (GLAPIENTRY *mpglColor4ub)(GLubyte, GLubyte, GLubyte, GLubyte); -void (GLAPIENTRY *mpglColor3f)(GLfloat, GLfloat, GLfloat); -void (GLAPIENTRY *mpglColor4f)(GLfloat, GLfloat, GLfloat, GLfloat); -void (GLAPIENTRY *mpglClearColor)(GLclampf, GLclampf, GLclampf, GLclampf); -void (GLAPIENTRY *mpglClearDepth)(GLclampd); -void (GLAPIENTRY *mpglDepthFunc)(GLenum); -void (GLAPIENTRY *mpglEnable)(GLenum); -void (GLAPIENTRY *mpglDisable)(GLenum); -const GLubyte *(GLAPIENTRY *mpglGetString)(GLenum); -void (GLAPIENTRY *mpglDrawBuffer)(GLenum); -void (GLAPIENTRY *mpglDepthMask)(GLboolean); -void (GLAPIENTRY *mpglBlendFunc)(GLenum, GLenum); -void (GLAPIENTRY *mpglFlush)(void); -void (GLAPIENTRY *mpglFinish)(void); -void (GLAPIENTRY *mpglPixelStorei)(GLenum, GLint); -void (GLAPIENTRY *mpglTexImage1D)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -void (GLAPIENTRY *mpglTexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -void (GLAPIENTRY *mpglTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -void (GLAPIENTRY *mpglTexParameteri)(GLenum, GLenum, GLint); -void (GLAPIENTRY *mpglTexParameterf)(GLenum, GLenum, GLfloat); -void (GLAPIENTRY *mpglTexParameterfv)(GLenum, GLenum, const GLfloat *); -void (GLAPIENTRY *mpglTexCoord2f)(GLfloat, GLfloat); -void (GLAPIENTRY *mpglVertex2f)(GLfloat, GLfloat); -void (GLAPIENTRY *mpglVertex3f)(GLfloat, GLfloat, GLfloat); -void (GLAPIENTRY *mpglNormal3f)(GLfloat, GLfloat, GLfloat); -void (GLAPIENTRY *mpglLightfv)(GLenum, GLenum, const GLfloat *); -void (GLAPIENTRY *mpglColorMaterial)(GLenum, GLenum); -void (GLAPIENTRY *mpglShadeModel)(GLenum); -void (GLAPIENTRY *mpglGetIntegerv)(GLenum, GLint *); -void (GLAPIENTRY *mpglColorMask)(GLboolean, GLboolean, GLboolean, GLboolean); - -/** - * \defgroup glextfunctions OpenGL extension functions - * - * the pointers to these functions are acquired when the OpenGL - * context is created - * \{ - */ -void (GLAPIENTRY *mpglGenBuffers)(GLsizei, GLuint *); -void (GLAPIENTRY *mpglDeleteBuffers)(GLsizei, const GLuint *); -void (GLAPIENTRY *mpglBindBuffer)(GLenum, GLuint); -GLvoid* (GLAPIENTRY *mpglMapBuffer)(GLenum, GLenum); -GLboolean (GLAPIENTRY *mpglUnmapBuffer)(GLenum); -void (GLAPIENTRY *mpglBufferData)(GLenum, intptr_t, const GLvoid *, GLenum); -void (GLAPIENTRY *mpglCombinerParameterfv)(GLenum, const GLfloat *); -void (GLAPIENTRY *mpglCombinerParameteri)(GLenum, GLint); -void (GLAPIENTRY *mpglCombinerInput)(GLenum, GLenum, GLenum, GLenum, GLenum, - GLenum); -void (GLAPIENTRY *mpglCombinerOutput)(GLenum, GLenum, GLenum, GLenum, GLenum, - GLenum, GLenum, GLboolean, GLboolean, - GLboolean); -void (GLAPIENTRY *mpglBeginFragmentShader)(void); -void (GLAPIENTRY *mpglEndFragmentShader)(void); -void (GLAPIENTRY *mpglSampleMap)(GLuint, GLuint, GLenum); -void (GLAPIENTRY *mpglColorFragmentOp2)(GLenum, GLuint, GLuint, GLuint, GLuint, - GLuint, GLuint, GLuint, GLuint, GLuint); -void (GLAPIENTRY *mpglColorFragmentOp3)(GLenum, GLuint, GLuint, GLuint, GLuint, - GLuint, GLuint, GLuint, GLuint, GLuint, - GLuint, GLuint, GLuint); -void (GLAPIENTRY *mpglSetFragmentShaderConstant)(GLuint, const GLfloat *); -void (GLAPIENTRY *mpglActiveTexture)(GLenum); -void (GLAPIENTRY *mpglBindTexture)(GLenum, GLuint); -void (GLAPIENTRY *mpglMultiTexCoord2f)(GLenum, GLfloat, GLfloat); -void (GLAPIENTRY *mpglGenPrograms)(GLsizei, GLuint *); -void (GLAPIENTRY *mpglDeletePrograms)(GLsizei, const GLuint *); -void (GLAPIENTRY *mpglBindProgram)(GLenum, GLuint); -void (GLAPIENTRY *mpglProgramString)(GLenum, GLenum, GLsizei, const GLvoid *); -void (GLAPIENTRY *mpglGetProgramiv)(GLenum, GLenum, GLint *); -void (GLAPIENTRY *mpglProgramEnvParameter4f)(GLenum, GLuint, GLfloat, GLfloat, - GLfloat, GLfloat); -int (GLAPIENTRY *mpglSwapInterval)(int); -void (GLAPIENTRY *mpglTexImage3D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, - GLint, GLenum, GLenum, const GLvoid *); -void* (GLAPIENTRY *mpglAllocateMemoryMESA)(void *, int, size_t, float, float, float); -void (GLAPIENTRY *mpglFreeMemoryMESA)(void *, int, void *); -/** \} */ // end of glextfunctions group +#include "options.h" //! \defgroup glgeneral OpenGL general helper functions @@ -150,60 +54,59 @@ void (GLAPIENTRY *mpglFreeMemoryMESA)(void *, int, void *); //! \defgroup glconversion OpenGL conversion helper functions -static GLint hqtexfmt; - /** * \brief adjusts the GL_UNPACK_ALIGNMENT to fit the stride. * \param stride number of bytes per line for which alignment should fit. * \ingroup glgeneral */ -void glAdjustAlignment(int stride) { - GLint gl_alignment; - if (stride % 8 == 0) - gl_alignment=8; - else if (stride % 4 == 0) - gl_alignment=4; - else if (stride % 2 == 0) - gl_alignment=2; - else - gl_alignment=1; - mpglPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment); +void glAdjustAlignment(GL *gl, int stride) +{ + GLint gl_alignment; + if (stride % 8 == 0) + gl_alignment = 8; + else if (stride % 4 == 0) + gl_alignment = 4; + else if (stride % 2 == 0) + gl_alignment = 2; + else + gl_alignment = 1; + gl->PixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment); } struct gl_name_map_struct { - GLint value; - const char *name; + GLint value; + const char *name; }; #undef MAP -#define MAP(a) {a, #a} +#define MAP(a) {a, # a} //! mapping table for the glValName function static const struct gl_name_map_struct gl_name_map[] = { - // internal format - MAP(GL_R3_G3_B2), MAP(GL_RGB4), MAP(GL_RGB5), MAP(GL_RGB8), - MAP(GL_RGB10), MAP(GL_RGB12), MAP(GL_RGB16), MAP(GL_RGBA2), - MAP(GL_RGBA4), MAP(GL_RGB5_A1), MAP(GL_RGBA8), MAP(GL_RGB10_A2), - MAP(GL_RGBA12), MAP(GL_RGBA16), MAP(GL_LUMINANCE8), MAP(GL_LUMINANCE16), - - // format - MAP(GL_RGB), MAP(GL_RGBA), MAP(GL_RED), MAP(GL_GREEN), MAP(GL_BLUE), - MAP(GL_ALPHA), MAP(GL_LUMINANCE), MAP(GL_LUMINANCE_ALPHA), - MAP(GL_COLOR_INDEX), - // rest 1.2 only - MAP(GL_BGR), MAP(GL_BGRA), - - //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 - 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), - {0, 0} + // internal format + MAP(GL_R3_G3_B2), MAP(GL_RGB4), MAP(GL_RGB5), MAP(GL_RGB8), + MAP(GL_RGB10), MAP(GL_RGB12), MAP(GL_RGB16), MAP(GL_RGBA2), + MAP(GL_RGBA4), MAP(GL_RGB5_A1), MAP(GL_RGBA8), MAP(GL_RGB10_A2), + MAP(GL_RGBA12), MAP(GL_RGBA16), MAP(GL_LUMINANCE8), MAP(GL_LUMINANCE16), + + // format + MAP(GL_RGB), MAP(GL_RGBA), MAP(GL_RED), MAP(GL_GREEN), MAP(GL_BLUE), + MAP(GL_ALPHA), MAP(GL_LUMINANCE), MAP(GL_LUMINANCE_ALPHA), + MAP(GL_COLOR_INDEX), + // rest 1.2 only + MAP(GL_BGR), MAP(GL_BGRA), + + //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 + 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), + {0, 0} }; #undef MAP @@ -215,14 +118,14 @@ static const struct gl_name_map_struct gl_name_map[] = { */ const char *glValName(GLint value) { - int i = 0; - - while (gl_name_map[i].name) { - if (gl_name_map[i].value == value) - return gl_name_map[i].name; - i++; - } - return "Unknown format!"; + int i = 0; + + while (gl_name_map[i].name) { + if (gl_name_map[i].value == value) + return gl_name_map[i].name; + i++; + } + return "Unknown format!"; } //! always return this format as internal texture format in glFindFormat @@ -243,121 +146,125 @@ const char *glValName(GLint value) * \ingroup gltexture */ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt, - GLenum *gl_format, GLenum *gl_type) + GLenum *gl_format, GLenum *gl_type) { - int supported = 1; - int dummy1; - GLenum dummy2; - GLint dummy3; - if (!bpp) bpp = &dummy1; - if (!gl_texfmt) gl_texfmt = &dummy3; - if (!gl_format) gl_format = &dummy2; - if (!gl_type) gl_type = &dummy2; - - if (mp_get_chroma_shift(fmt, NULL, NULL, NULL)) { - // reduce the possible cases a bit - if (IMGFMT_IS_YUVP16_LE(fmt)) - fmt = IMGFMT_420P16_LE; - else if (IMGFMT_IS_YUVP16_BE(fmt)) - fmt = IMGFMT_420P16_BE; - else - fmt = IMGFMT_YV12; - } + int supported = 1; + int dummy1; + GLenum dummy2; + GLint dummy3; + if (!bpp) + bpp = &dummy1; + if (!gl_texfmt) + gl_texfmt = &dummy3; + if (!gl_format) + gl_format = &dummy2; + if (!gl_type) + gl_type = &dummy2; + + if (mp_get_chroma_shift(fmt, NULL, NULL, NULL)) { + // reduce the possible cases a bit + if (IMGFMT_IS_YUVP16_LE(fmt)) + fmt = IMGFMT_420P16_LE; + else if (IMGFMT_IS_YUVP16_BE(fmt)) + fmt = IMGFMT_420P16_BE; + else + fmt = IMGFMT_YV12; + } - *bpp = IMGFMT_IS_BGR(fmt)?IMGFMT_BGR_DEPTH(fmt):IMGFMT_RGB_DEPTH(fmt); - *gl_texfmt = 3; - switch (fmt) { + *bpp = IMGFMT_IS_BGR(fmt) ? IMGFMT_BGR_DEPTH(fmt) : IMGFMT_RGB_DEPTH(fmt); + *gl_texfmt = 3; + switch (fmt) { case IMGFMT_RGB48NE: - *gl_format = GL_RGB; - *gl_type = GL_UNSIGNED_SHORT; - break; + *gl_format = GL_RGB; + *gl_type = GL_UNSIGNED_SHORT; + break; case IMGFMT_RGB24: - *gl_format = GL_RGB; - *gl_type = GL_UNSIGNED_BYTE; - break; + *gl_format = GL_RGB; + *gl_type = GL_UNSIGNED_BYTE; + break; case IMGFMT_RGBA: - *gl_texfmt = 4; - *gl_format = GL_RGBA; - *gl_type = GL_UNSIGNED_BYTE; - break; + *gl_texfmt = 4; + *gl_format = GL_RGBA; + *gl_type = GL_UNSIGNED_BYTE; + break; case IMGFMT_420P16: - supported = 0; // no native YUV support - *gl_texfmt = GL_LUMINANCE16; - *bpp = 16; - *gl_format = GL_LUMINANCE; - *gl_type = GL_UNSIGNED_SHORT; - break; + supported = 0; // no native YUV support + *gl_texfmt = GL_LUMINANCE16; + *bpp = 16; + *gl_format = GL_LUMINANCE; + *gl_type = GL_UNSIGNED_SHORT; + break; case IMGFMT_YV12: - supported = 0; // no native YV12 support + supported = 0; // no native YV12 support case IMGFMT_Y800: case IMGFMT_Y8: - *gl_texfmt = 1; - *bpp = 8; - *gl_format = GL_LUMINANCE; - *gl_type = GL_UNSIGNED_BYTE; - break; + *gl_texfmt = 1; + *bpp = 8; + *gl_format = GL_LUMINANCE; + *gl_type = GL_UNSIGNED_BYTE; + break; case IMGFMT_UYVY: // IMGFMT_YUY2 would be more logical for the _REV format, // but gives clearly swapped colors. case IMGFMT_YVYU: - *gl_texfmt = GL_YCBCR_MESA; - *bpp = 16; - *gl_format = GL_YCBCR_MESA; - *gl_type = fmt == IMGFMT_UYVY ? GL_UNSIGNED_SHORT_8_8 : GL_UNSIGNED_SHORT_8_8_REV; - break; + *gl_texfmt = GL_YCBCR_MESA; + *bpp = 16; + *gl_format = GL_YCBCR_MESA; + *gl_type = fmt == IMGFMT_UYVY ? GL_UNSIGNED_SHORT_8_8 : GL_UNSIGNED_SHORT_8_8_REV; + break; #if 0 // we do not support palettized formats, although the format the // swscale produces works case IMGFMT_RGB8: - gl_format = GL_RGB; - gl_type = GL_UNSIGNED_BYTE_2_3_3_REV; - break; + gl_format = GL_RGB; + gl_type = GL_UNSIGNED_BYTE_2_3_3_REV; + break; #endif case IMGFMT_RGB15: - *gl_format = GL_RGBA; - *gl_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - break; + *gl_format = GL_RGBA; + *gl_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; case IMGFMT_RGB16: - *gl_format = GL_RGB; - *gl_type = GL_UNSIGNED_SHORT_5_6_5_REV; - break; + *gl_format = GL_RGB; + *gl_type = GL_UNSIGNED_SHORT_5_6_5_REV; + break; #if 0 case IMGFMT_BGR8: - // special case as red and blue have a differen number of bits. - // GL_BGR and GL_UNSIGNED_BYTE_3_3_2 isn't supported at least - // by nVidia drivers, and in addition would give more bits to - // blue than to red, which isn't wanted - gl_format = GL_RGB; - gl_type = GL_UNSIGNED_BYTE_3_3_2; - break; + // special case as red and blue have a differen number of bits. + // GL_BGR and GL_UNSIGNED_BYTE_3_3_2 isn't supported at least + // by nVidia drivers, and in addition would give more bits to + // blue than to red, which isn't wanted + gl_format = GL_RGB; + gl_type = GL_UNSIGNED_BYTE_3_3_2; + break; #endif case IMGFMT_BGR15: - *gl_format = GL_BGRA; - *gl_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - break; + *gl_format = GL_BGRA; + *gl_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; case IMGFMT_BGR16: - *gl_format = GL_RGB; - *gl_type = GL_UNSIGNED_SHORT_5_6_5; - break; + *gl_format = GL_RGB; + *gl_type = GL_UNSIGNED_SHORT_5_6_5; + break; case IMGFMT_BGR24: - *gl_format = GL_BGR; - *gl_type = GL_UNSIGNED_BYTE; - break; + *gl_format = GL_BGR; + *gl_type = GL_UNSIGNED_BYTE; + break; case IMGFMT_BGRA: - *gl_texfmt = 4; - *gl_format = GL_BGRA; - *gl_type = GL_UNSIGNED_BYTE; - break; + *gl_texfmt = 4; + *gl_format = GL_BGRA; + *gl_type = GL_UNSIGNED_BYTE; + break; default: - *gl_texfmt = 4; - *gl_format = GL_RGBA; - *gl_type = GL_UNSIGNED_BYTE; - supported = 0; - } + *gl_texfmt = 4; + *gl_format = GL_RGBA; + *gl_type = GL_UNSIGNED_BYTE; + supported = 0; + } #ifdef TEXTUREFORMAT_ALWAYS - *gl_texfmt = TEXTUREFORMAT_ALWAYS; + *gl_texfmt = TEXTUREFORMAT_ALWAYS; #endif - return supported; + return supported; } #ifdef HAVE_LIBDL @@ -368,112 +275,150 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt, * \param s name of function to find * \return address of function or NULL if not found */ -static void *getdladdr(const char *s) { - void *ret = NULL; +static void *getdladdr(const char *s) +{ + void *ret = NULL; #ifdef HAVE_LIBDL - void *handle = dlopen(NULL, RTLD_LAZY); - if (!handle) - return NULL; - ret = dlsym(handle, s); - dlclose(handle); + void *handle = dlopen(NULL, RTLD_LAZY); + if (!handle) + return NULL; + ret = dlsym(handle, s); + dlclose(handle); #endif - return ret; + return ret; } typedef struct { - void *funcptr; - const char *extstr; - const char *funcnames[7]; - void *fallback; + ptrdiff_t offset; // offset to the function pointer in struct GL + const char *extstr; + const char *funcnames[7]; + void *fallback; } extfunc_desc_t; -#define DEF_FUNC_DESC(name) {&mpgl##name, NULL, {"gl"#name, NULL}, gl ##name} +#define DEF_FUNC_DESC(name) \ + {offsetof(GL, name), NULL, {"gl" # name, NULL}, gl ## name} +#define DEF_EXT_FUNCS(...) __VA_ARGS__ +#define DEF_EXT_DESC(name, ext, funcnames) \ + {offsetof(GL, name), ext, {DEF_EXT_FUNCS funcnames}} + static const extfunc_desc_t extfuncs[] = { - // these aren't extension functions but we query them anyway to allow - // different "backends" with one binary - DEF_FUNC_DESC(Begin), - DEF_FUNC_DESC(End), - DEF_FUNC_DESC(Viewport), - DEF_FUNC_DESC(MatrixMode), - DEF_FUNC_DESC(LoadIdentity), - DEF_FUNC_DESC(Translated), - DEF_FUNC_DESC(Scaled), - DEF_FUNC_DESC(Ortho), - DEF_FUNC_DESC(Frustum), - DEF_FUNC_DESC(PushMatrix), - DEF_FUNC_DESC(PopMatrix), - DEF_FUNC_DESC(Clear), - DEF_FUNC_DESC(GenLists), - DEF_FUNC_DESC(DeleteLists), - DEF_FUNC_DESC(NewList), - DEF_FUNC_DESC(EndList), - DEF_FUNC_DESC(CallList), - DEF_FUNC_DESC(CallLists), - DEF_FUNC_DESC(GenTextures), - DEF_FUNC_DESC(DeleteTextures), - DEF_FUNC_DESC(TexEnvf), - DEF_FUNC_DESC(TexEnvi), - DEF_FUNC_DESC(Color4ub), - DEF_FUNC_DESC(Color3f), - DEF_FUNC_DESC(Color4f), - DEF_FUNC_DESC(ClearColor), - DEF_FUNC_DESC(ClearDepth), - DEF_FUNC_DESC(DepthFunc), - DEF_FUNC_DESC(Enable), - DEF_FUNC_DESC(Disable), - DEF_FUNC_DESC(DrawBuffer), - DEF_FUNC_DESC(DepthMask), - DEF_FUNC_DESC(BlendFunc), - DEF_FUNC_DESC(Flush), - DEF_FUNC_DESC(Finish), - DEF_FUNC_DESC(PixelStorei), - DEF_FUNC_DESC(TexImage1D), - DEF_FUNC_DESC(TexImage2D), - DEF_FUNC_DESC(TexSubImage2D), - DEF_FUNC_DESC(TexParameteri), - DEF_FUNC_DESC(TexParameterf), - DEF_FUNC_DESC(TexParameterfv), - DEF_FUNC_DESC(TexCoord2f), - DEF_FUNC_DESC(Vertex2f), - DEF_FUNC_DESC(Vertex3f), - DEF_FUNC_DESC(Normal3f), - DEF_FUNC_DESC(Lightfv), - DEF_FUNC_DESC(ColorMaterial), - DEF_FUNC_DESC(ShadeModel), - DEF_FUNC_DESC(GetIntegerv), - DEF_FUNC_DESC(ColorMask), - - // here start the real extensions - {&mpglGenBuffers, NULL, {"glGenBuffers", "glGenBuffersARB", NULL}}, - {&mpglDeleteBuffers, NULL, {"glDeleteBuffers", "glDeleteBuffersARB", NULL}}, - {&mpglBindBuffer, NULL, {"glBindBuffer", "glBindBufferARB", NULL}}, - {&mpglMapBuffer, NULL, {"glMapBuffer", "glMapBufferARB", NULL}}, - {&mpglUnmapBuffer, NULL, {"glUnmapBuffer", "glUnmapBufferARB", NULL}}, - {&mpglBufferData, NULL, {"glBufferData", "glBufferDataARB", NULL}}, - {&mpglCombinerParameterfv, "NV_register_combiners", {"glCombinerParameterfv", "glCombinerParameterfvNV", NULL}}, - {&mpglCombinerParameteri, "NV_register_combiners", {"glCombinerParameteri", "glCombinerParameteriNV", NULL}}, - {&mpglCombinerInput, "NV_register_combiners", {"glCombinerInput", "glCombinerInputNV", NULL}}, - {&mpglCombinerOutput, "NV_register_combiners", {"glCombinerOutput", "glCombinerOutputNV", NULL}}, - {&mpglBeginFragmentShader, "ATI_fragment_shader", {"glBeginFragmentShaderATI", NULL}}, - {&mpglEndFragmentShader, "ATI_fragment_shader", {"glEndFragmentShaderATI", NULL}}, - {&mpglSampleMap, "ATI_fragment_shader", {"glSampleMapATI", NULL}}, - {&mpglColorFragmentOp2, "ATI_fragment_shader", {"glColorFragmentOp2ATI", NULL}}, - {&mpglColorFragmentOp3, "ATI_fragment_shader", {"glColorFragmentOp3ATI", NULL}}, - {&mpglSetFragmentShaderConstant, "ATI_fragment_shader", {"glSetFragmentShaderConstantATI", NULL}}, - {&mpglActiveTexture, NULL, {"glActiveTexture", "glActiveTextureARB", NULL}}, - {&mpglBindTexture, NULL, {"glBindTexture", "glBindTextureARB", "glBindTextureEXT", NULL}}, - {&mpglMultiTexCoord2f, NULL, {"glMultiTexCoord2f", "glMultiTexCoord2fARB", NULL}}, - {&mpglGenPrograms, "_program", {"glGenProgramsARB", NULL}}, - {&mpglDeletePrograms, "_program", {"glDeleteProgramsARB", NULL}}, - {&mpglBindProgram, "_program", {"glBindProgramARB", NULL}}, - {&mpglProgramString, "_program", {"glProgramStringARB", NULL}}, - {&mpglGetProgramiv, "_program", {"glGetProgramivARB", NULL}}, - {&mpglProgramEnvParameter4f, "_program", {"glProgramEnvParameter4fARB", NULL}}, - {&mpglSwapInterval, "_swap_control", {"glXSwapIntervalSGI", "glXSwapInterval", "wglSwapIntervalSGI", "wglSwapInterval", "wglSwapIntervalEXT", NULL}}, - {&mpglTexImage3D, NULL, {"glTexImage3D", NULL}}, - {&mpglAllocateMemoryMESA, "GLX_MESA_allocate_memory", {"glXAllocateMemoryMESA", NULL}}, - {&mpglFreeMemoryMESA, "GLX_MESA_allocate_memory", {"glXFreeMemoryMESA", NULL}}, - {NULL} + // these aren't extension functions but we query them anyway to allow + // different "backends" with one binary + DEF_FUNC_DESC(Begin), + DEF_FUNC_DESC(End), + DEF_FUNC_DESC(Viewport), + DEF_FUNC_DESC(MatrixMode), + DEF_FUNC_DESC(LoadIdentity), + DEF_FUNC_DESC(Translated), + DEF_FUNC_DESC(Scaled), + DEF_FUNC_DESC(Ortho), + DEF_FUNC_DESC(Frustum), + DEF_FUNC_DESC(PushMatrix), + DEF_FUNC_DESC(PopMatrix), + DEF_FUNC_DESC(Clear), + DEF_FUNC_DESC(GenLists), + DEF_FUNC_DESC(DeleteLists), + DEF_FUNC_DESC(NewList), + DEF_FUNC_DESC(EndList), + DEF_FUNC_DESC(CallList), + DEF_FUNC_DESC(CallLists), + DEF_FUNC_DESC(GenTextures), + DEF_FUNC_DESC(DeleteTextures), + DEF_FUNC_DESC(TexEnvf), + DEF_FUNC_DESC(TexEnvi), + DEF_FUNC_DESC(Color4ub), + DEF_FUNC_DESC(Color3f), + DEF_FUNC_DESC(Color4f), + DEF_FUNC_DESC(ClearColor), + DEF_FUNC_DESC(ClearDepth), + DEF_FUNC_DESC(DepthFunc), + DEF_FUNC_DESC(Enable), + DEF_FUNC_DESC(Disable), + DEF_FUNC_DESC(DrawBuffer), + DEF_FUNC_DESC(DepthMask), + DEF_FUNC_DESC(BlendFunc), + DEF_FUNC_DESC(Flush), + DEF_FUNC_DESC(Finish), + DEF_FUNC_DESC(PixelStorei), + DEF_FUNC_DESC(TexImage1D), + DEF_FUNC_DESC(TexImage2D), + DEF_FUNC_DESC(TexSubImage2D), + DEF_FUNC_DESC(GetTexImage), + DEF_FUNC_DESC(TexParameteri), + DEF_FUNC_DESC(TexParameterf), + DEF_FUNC_DESC(TexParameterfv), + DEF_FUNC_DESC(TexCoord2f), + DEF_FUNC_DESC(Vertex2f), + DEF_FUNC_DESC(Vertex3f), + DEF_FUNC_DESC(Normal3f), + DEF_FUNC_DESC(Lightfv), + DEF_FUNC_DESC(ColorMaterial), + DEF_FUNC_DESC(ShadeModel), + DEF_FUNC_DESC(GetIntegerv), + DEF_FUNC_DESC(ColorMask), + DEF_FUNC_DESC(ReadPixels), + DEF_FUNC_DESC(ReadBuffer), + + DEF_EXT_DESC(GenBuffers, NULL, + ("glGenBuffers", "glGenBuffersARB")), + DEF_EXT_DESC(DeleteBuffers, NULL, + ("glDeleteBuffers", "glDeleteBuffersARB")), + DEF_EXT_DESC(BindBuffer, NULL, + ("glBindBuffer", "glBindBufferARB")), + DEF_EXT_DESC(MapBuffer, NULL, + ("glMapBuffer", "glMapBufferARB")), + DEF_EXT_DESC(UnmapBuffer, NULL, + ("glUnmapBuffer", "glUnmapBufferARB")), + DEF_EXT_DESC(BufferData, NULL, + ("glBufferData", "glBufferDataARB")), + DEF_EXT_DESC(CombinerParameterfv, "NV_register_combiners", + ("glCombinerParameterfv", "glCombinerParameterfvNV")), + DEF_EXT_DESC(CombinerParameteri, "NV_register_combiners", + ("glCombinerParameteri", "glCombinerParameteriNV")), + DEF_EXT_DESC(CombinerInput, "NV_register_combiners", + ("glCombinerInput", "glCombinerInputNV")), + DEF_EXT_DESC(CombinerOutput, "NV_register_combiners", + ("glCombinerOutput", "glCombinerOutputNV")), + DEF_EXT_DESC(BeginFragmentShader, "ATI_fragment_shader", + ("glBeginFragmentShaderATI")), + DEF_EXT_DESC(EndFragmentShader, "ATI_fragment_shader", + ("glEndFragmentShaderATI")), + DEF_EXT_DESC(SampleMap, "ATI_fragment_shader", + ("glSampleMapATI")), + DEF_EXT_DESC(ColorFragmentOp2, "ATI_fragment_shader", + ("glColorFragmentOp2ATI")), + DEF_EXT_DESC(ColorFragmentOp3, "ATI_fragment_shader", + ("glColorFragmentOp3ATI")), + DEF_EXT_DESC(SetFragmentShaderConstant, "ATI_fragment_shader", + ("glSetFragmentShaderConstantATI")), + DEF_EXT_DESC(ActiveTexture, NULL, + ("glActiveTexture", "glActiveTextureARB")), + DEF_EXT_DESC(BindTexture, NULL, + ("glBindTexture", "glBindTextureARB", "glBindTextureEXT")), + DEF_EXT_DESC(MultiTexCoord2f, NULL, + ("glMultiTexCoord2f", "glMultiTexCoord2fARB")), + DEF_EXT_DESC(GenPrograms, "_program", + ("glGenProgramsARB")), + DEF_EXT_DESC(DeletePrograms, "_program", + ("glDeleteProgramsARB")), + DEF_EXT_DESC(BindProgram, "_program", + ("glBindProgramARB")), + DEF_EXT_DESC(ProgramString, "_program", + ("glProgramStringARB")), + DEF_EXT_DESC(GetProgramiv, "_program", + ("glGetProgramivARB")), + DEF_EXT_DESC(ProgramEnvParameter4f, "_program", + ("glProgramEnvParameter4fARB")), + DEF_EXT_DESC(SwapInterval, "_swap_control", + ("glXSwapIntervalSGI", "glXSwapInterval", "wglSwapIntervalSGI", + "wglSwapInterval", "wglSwapIntervalEXT")), + DEF_EXT_DESC(TexImage3D, NULL, + ("glTexImage3D")), + DEF_EXT_DESC(AllocateMemoryMESA, "GLX_MESA_allocate_memory", + ("glXAllocateMemoryMESA")), + DEF_EXT_DESC(FreeMemoryMESA, "GLX_MESA_allocate_memory", + ("glXFreeMemoryMESA")), + {-1} }; /** @@ -481,46 +426,44 @@ static const extfunc_desc_t extfuncs[] = { * \param getProcAddress function to resolve function names, may be NULL * \param ext2 an extra extension string */ -static void getFunctions(void *(*getProcAddress)(const GLubyte *), - const char *ext2) { - const extfunc_desc_t *dsc; - const char *extensions; - char *allexts; - - if (!getProcAddress) - getProcAddress = (void *)getdladdr; - - // special case, we need glGetString before starting to find the other functions - mpglGetString = getProcAddress("glGetString"); - if (!mpglGetString) - mpglGetString = glGetString; - - extensions = (const char *)mpglGetString(GL_EXTENSIONS); - if (!extensions) extensions = ""; - if (!ext2) ext2 = ""; - allexts = malloc(strlen(extensions) + strlen(ext2) + 2); - strcpy(allexts, extensions); - strcat(allexts, " "); - strcat(allexts, ext2); - mp_msg(MSGT_VO, MSGL_DBG2, "OpenGL extensions string:\n%s\n", allexts); - for (dsc = extfuncs; dsc->funcptr; dsc++) { - void *ptr = NULL; - int i; - if (!dsc->extstr || strstr(allexts, dsc->extstr)) { - for (i = 0; !ptr && dsc->funcnames[i]; i++) - ptr = getProcAddress((const GLubyte *)dsc->funcnames[i]); +static void getFunctions(GL *gl, void *(*getProcAddress)(const GLubyte *), + const char *ext2) +{ + const extfunc_desc_t *dsc; + const char *extensions; + char *allexts; + + if (!getProcAddress) + getProcAddress = (void *)getdladdr; + + // special case, we need glGetString before starting to find the other functions + gl->GetString = getProcAddress("glGetString"); + if (!gl->GetString) + gl->GetString = glGetString; + + extensions = (const char *)gl->GetString(GL_EXTENSIONS); + if (!extensions) + extensions = ""; + if (!ext2) + ext2 = ""; + allexts = malloc(strlen(extensions) + strlen(ext2) + 2); + strcpy(allexts, extensions); + strcat(allexts, " "); + strcat(allexts, ext2); + mp_msg(MSGT_VO, MSGL_DBG2, "OpenGL extensions string:\n%s\n", allexts); + for (dsc = extfuncs; dsc->offset >= 0; dsc++) { + void *ptr = NULL; + int i; + if (!dsc->extstr || strstr(allexts, dsc->extstr)) { + for (i = 0; !ptr && dsc->funcnames[i]; i++) + ptr = getProcAddress((const GLubyte *)dsc->funcnames[i]); + } + if (!ptr) + ptr = dsc->fallback; + void **funcptr = (void**)(((char*)gl) + dsc->offset); + *funcptr = ptr; } - if (!ptr) - ptr = dsc->fallback; - *(void **)dsc->funcptr = ptr; - } - if (strstr(allexts, "_texture_float")) - hqtexfmt = GL_RGB32F; - else if (strstr(allexts, "NV_float_buffer")) - hqtexfmt = GL_FLOAT_RGB32_NV; - else - hqtexfmt = GL_RGB16; - free(allexts); + free(allexts); } /** @@ -535,30 +478,47 @@ static void getFunctions(void *(*getProcAddress)(const GLubyte *), * \param val luminance value to fill texture with * \ingroup gltexture */ -void glCreateClearTex(GLenum target, GLenum fmt, GLenum format, GLenum type, GLint filter, - int w, int h, unsigned char val) { - GLfloat fval = (GLfloat)val / 255.0; - GLfloat border[4] = {fval, fval, fval, fval}; - int stride; - char *init; - if (w == 0) w = 1; - if (h == 0) h = 1; - stride = w * glFmt2bpp(format, type); - if (!stride) return; - init = malloc(stride * h); - memset(init, val, stride * h); - glAdjustAlignment(stride); - mpglPixelStorei(GL_UNPACK_ROW_LENGTH, w); - mpglTexImage2D(target, 0, fmt, w, h, 0, format, type, init); - mpglTexParameterf(target, GL_TEXTURE_PRIORITY, 1.0); - mpglTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter); - mpglTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter); - mpglTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - mpglTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // Border texels should not be used with CLAMP_TO_EDGE - // We set a sane default anyway. - mpglTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border); - free(init); +void glCreateClearTex(GL *gl, GLenum target, GLenum fmt, GLenum format, + GLenum type, GLint filter, int w, int h, + unsigned char val) +{ + GLfloat fval = (GLfloat)val / 255.0; + GLfloat border[4] = { + fval, fval, fval, fval + }; + int stride; + char *init; + if (w == 0) + w = 1; + if (h == 0) + h = 1; + stride = w * glFmt2bpp(format, type); + if (!stride) + return; + init = malloc(stride * h); + memset(init, val, stride * h); + glAdjustAlignment(gl, stride); + gl->PixelStorei(GL_UNPACK_ROW_LENGTH, w); + gl->TexImage2D(target, 0, fmt, w, h, 0, format, type, init); + gl->TexParameterf(target, GL_TEXTURE_PRIORITY, 1.0); + gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter); + gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter); + gl->TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl->TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // Border texels should not be used with CLAMP_TO_EDGE + // We set a sane default anyway. + gl->TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border); + free(init); +} + +static GLint detect_hqtexfmt(GL *gl) +{ + const char *extensions = (const char *)gl->GetString(GL_EXTENSIONS); + if (strstr(extensions, "_texture_float")) + return GL_RGB32F; + else if (strstr(extensions, "NV_float_buffer")) + return GL_FLOAT_RGB32_NV; + return GL_RGB16; } /** @@ -573,29 +533,34 @@ void glCreateClearTex(GLenum target, GLenum fmt, GLenum format, GLenum type, GLi * \return 0 on error, 1 otherwise * \ingroup gltexture */ -int glCreatePPMTex(GLenum target, GLenum fmt, GLint filter, - FILE *f, int *width, int *height, int *maxval) { - int w, h, m, bpp; - GLenum type; - uint8_t *data = read_pnm(f, &w, &h, &bpp, &m); - if (!data || (bpp != 3 && bpp != 6)) { +int glCreatePPMTex(GL *gl, GLenum target, GLenum fmt, GLint filter, + FILE *f, int *width, int *height, int *maxval) +{ + int w, h, m, bpp; + GLenum type; + uint8_t *data = read_pnm(f, &w, &h, &bpp, &m); + GLint hqtexfmt = detect_hqtexfmt(gl); + if (!data || (bpp != 3 && bpp != 6)) { + free(data); + return 0; + } + if (!fmt) { + fmt = bpp == 6 ? hqtexfmt : 3; + if (fmt == GL_FLOAT_RGB32_NV && target != GL_TEXTURE_RECTANGLE) + fmt = GL_RGB16; + } + type = bpp == 6 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; + glCreateClearTex(gl, target, fmt, GL_RGB, type, filter, w, h, 0); + glUploadTex(gl, target, GL_RGB, type, + data, w * bpp, 0, 0, w, h, 0); free(data); - return 0; - } - if (!fmt) { - fmt = bpp == 6 ? hqtexfmt : 3; - if (fmt == GL_FLOAT_RGB32_NV && target != GL_TEXTURE_RECTANGLE) - fmt = GL_RGB16; - } - type = bpp == 6 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; - glCreateClearTex(target, fmt, GL_RGB, type, filter, w, h, 0); - glUploadTex(target, GL_RGB, type, - data, w * bpp, 0, 0, w, h, 0); - free(data); - if (width) *width = w; - if (height) *height = h; - if (maxval) *maxval = m; - return 1; + if (width) + *width = w; + if (height) + *height = h; + if (maxval) + *maxval = m; + return 1; } /** @@ -607,38 +572,39 @@ int glCreatePPMTex(GLenum target, GLenum fmt, GLint filter, * * Does not handle all possible variants, just those used by MPlayer */ -int glFmt2bpp(GLenum format, GLenum type) { - int component_size = 0; - switch (type) { +int glFmt2bpp(GLenum format, GLenum type) +{ + int component_size = 0; + switch (type) { case GL_UNSIGNED_BYTE_3_3_2: case GL_UNSIGNED_BYTE_2_3_3_REV: - return 1; + 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_R |