2008-09-07 16:09:51 +02:00
|
|
|
/*
|
|
|
|
* common OpenGL routines
|
2005-09-25 18:41:28 +02:00
|
|
|
*
|
2010-04-25 08:52:13 +02:00
|
|
|
* copyleft (C) 2005-2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
|
2005-09-15 00:08:04 +02:00
|
|
|
* Special thanks go to the xine team and Matthias Hopf, whose video_out_opengl.c
|
|
|
|
* gave me lots of good ideas.
|
2008-09-07 16:09:51 +02:00
|
|
|
*
|
|
|
|
* This file is part of MPlayer.
|
|
|
|
*
|
|
|
|
* MPlayer is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* MPlayer is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2010-06-13 12:42:32 +02:00
|
|
|
*
|
|
|
|
* You can alternatively redistribute this file and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2005-09-15 00:08:04 +02:00
|
|
|
*/
|
2008-09-07 16:09:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \file gl_common.c
|
|
|
|
* \brief OpenGL helper functions used by vo_gl.c and vo_gl2.c
|
|
|
|
*/
|
|
|
|
|
2011-09-25 11:18:07 +02:00
|
|
|
#include <stddef.h>
|
2005-07-27 19:22:24 +02:00
|
|
|
#include <stdlib.h>
|
2005-09-15 00:08:04 +02:00
|
|
|
#include <stdio.h>
|
2005-07-27 19:22:24 +02:00
|
|
|
#include <string.h>
|
2012-03-31 00:33:53 +02:00
|
|
|
#include <stdbool.h>
|
2005-09-15 00:08:04 +02:00
|
|
|
#include <math.h>
|
2012-10-03 01:54:13 +02:00
|
|
|
#include <assert.h>
|
2011-09-25 11:18:07 +02:00
|
|
|
#include "talloc.h"
|
2004-10-17 15:28:22 +02:00
|
|
|
#include "gl_common.h"
|
2014-07-13 20:12:13 +02:00
|
|
|
#include "common/common.h"
|
2013-12-17 02:02:25 +01:00
|
|
|
#include "options/options.h"
|
|
|
|
#include "options/m_option.h"
|
2005-09-25 18:41:28 +02:00
|
|
|
|
|
|
|
//! \defgroup glgeneral OpenGL general helper functions
|
|
|
|
|
2012-03-31 00:33:53 +02:00
|
|
|
// GLU has this as gluErrorString (we don't use GLU, as it is legacy-OpenGL)
|
|
|
|
static const char *gl_error_to_string(GLenum error)
|
|
|
|
{
|
|
|
|
switch (error) {
|
|
|
|
case GL_INVALID_ENUM: return "INVALID_ENUM";
|
|
|
|
case GL_INVALID_VALUE: return "INVALID_VALUE";
|
|
|
|
case GL_INVALID_OPERATION: return "INVALID_OPERATION";
|
|
|
|
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
|
|
|
return "INVALID_FRAMEBUFFER_OPERATION";
|
|
|
|
case GL_OUT_OF_MEMORY: return "OUT_OF_MEMORY";
|
|
|
|
default: return "unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-12 00:57:32 +02:00
|
|
|
void glCheckError(GL *gl, struct mp_log *log, const char *info)
|
2012-03-31 00:33:53 +02:00
|
|
|
{
|
|
|
|
for (;;) {
|
|
|
|
GLenum error = gl->GetError();
|
|
|
|
if (error == GL_NO_ERROR)
|
|
|
|
break;
|
2013-12-21 21:49:13 +01:00
|
|
|
mp_msg(log, MSGL_ERR, "%s: OpenGL error %s.\n", info,
|
|
|
|
gl_error_to_string(error));
|
2012-03-31 00:33:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-25 18:41:28 +02:00
|
|
|
//! \defgroup glcontext OpenGL context management helper functions
|
|
|
|
|
|
|
|
//! \defgroup gltexture OpenGL texture handling helper functions
|
|
|
|
|
|
|
|
//! \defgroup glconversion OpenGL conversion helper functions
|
2005-07-26 12:16:18 +02:00
|
|
|
|
2004-10-17 15:28:22 +02:00
|
|
|
/**
|
2005-09-25 18:41:28 +02:00
|
|
|
* \brief adjusts the GL_UNPACK_ALIGNMENT to fit the stride.
|
2004-10-17 15:28:22 +02:00
|
|
|
* \param stride number of bytes per line for which alignment should fit.
|
2005-09-25 18:41:28 +02:00
|
|
|
* \ingroup glgeneral
|
2004-10-17 15:28:22 +02:00
|
|
|
*/
|
2011-09-25 11:18:07 +02:00
|
|
|
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);
|
2011-10-06 20:46:01 +02:00
|
|
|
gl->PixelStorei(GL_PACK_ALIGNMENT, gl_alignment);
|
2004-10-17 15:28:22 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 01:54:13 +02:00
|
|
|
struct feature {
|
|
|
|
int id;
|
|
|
|
const char *name;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct feature features[] = {
|
|
|
|
{MPGL_CAP_GL, "Basic OpenGL"},
|
|
|
|
{MPGL_CAP_GL_LEGACY, "Legacy OpenGL"},
|
|
|
|
{MPGL_CAP_GL2, "OpenGL 2.0"},
|
|
|
|
{MPGL_CAP_GL21, "OpenGL 2.1"},
|
|
|
|
{MPGL_CAP_GL3, "OpenGL 3.0"},
|
|
|
|
{MPGL_CAP_FB, "Framebuffers"},
|
|
|
|
{MPGL_CAP_VAO, "VAOs"},
|
|
|
|
{MPGL_CAP_SRGB_TEX, "sRGB textures"},
|
|
|
|
{MPGL_CAP_SRGB_FB, "sRGB framebuffers"},
|
|
|
|
{MPGL_CAP_FLOAT_TEX, "Float textures"},
|
|
|
|
{MPGL_CAP_TEX_RG, "RG textures"},
|
|
|
|
{MPGL_CAP_NO_SW, "NO_SW"},
|
|
|
|
{0},
|
|
|
|
};
|
|
|
|
|
2013-09-12 00:57:32 +02:00
|
|
|
static void list_features(int set, struct mp_log *log, int msgl, bool invert)
|
2012-10-03 01:54:13 +02:00
|
|
|
{
|
2014-08-24 19:14:36 +02:00
|
|
|
char b[1024] = {0};
|
2012-10-03 01:54:13 +02:00
|
|
|
for (const struct feature *f = &features[0]; f->id; f++) {
|
|
|
|
if (invert == !(f->id & set))
|
2014-07-13 20:12:13 +02:00
|
|
|
mp_snprintf_cat(b, sizeof(b), " [%s]", f->name);
|
2012-10-03 01:54:13 +02:00
|
|
|
}
|
2014-07-13 20:12:13 +02:00
|
|
|
mp_msg(log, msgl, "%s\n", b);
|
2012-10-03 01:54:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// This guesses if the current GL context is a suspected software renderer.
|
|
|
|
static bool is_software_gl(GL *gl)
|
|
|
|
{
|
|
|
|
const char *renderer = gl->GetString(GL_RENDERER);
|
|
|
|
const char *vendor = gl->GetString(GL_VENDOR);
|
|
|
|
return !(renderer && vendor) ||
|
|
|
|
strcmp(renderer, "Software Rasterizer") == 0 ||
|
|
|
|
strstr(renderer, "llvmpipe") ||
|
|
|
|
strcmp(vendor, "Microsoft Corporation") == 0 ||
|
|
|
|
strcmp(renderer, "Mesa X11") == 0;
|
|
|
|
}
|
|
|
|
|
2014-12-09 22:36:28 +01:00
|
|
|
static void GLAPIENTRY dummy_glBindFramebuffer(GLenum target, GLuint framebuffer)
|
2014-12-09 22:28:16 +01:00
|
|
|
{
|
|
|
|
assert(framebuffer == 0);
|
|
|
|
}
|
|
|
|
|
2012-10-03 01:54:13 +02:00
|
|
|
#define FN_OFFS(name) offsetof(GL, name)
|
|
|
|
|
|
|
|
#define DEF_FN(name) {FN_OFFS(name), {"gl" # name}}
|
|
|
|
#define DEF_FN_NAMES(name, ...) {FN_OFFS(name), {__VA_ARGS__}}
|
|
|
|
|
|
|
|
struct gl_function {
|
|
|
|
ptrdiff_t offset;
|
|
|
|
char *funcnames[7];
|
2006-01-07 20:53:51 +01:00
|
|
|
};
|
|
|
|
|
2012-10-03 01:54:13 +02:00
|
|
|
struct gl_functions {
|
|
|
|
const char *extension; // introduced with this extension in any version
|
|
|
|
int provides; // bitfield of MPGL_CAP_* constants
|
|
|
|
int ver_core; // introduced as required function
|
|
|
|
int ver_removed; // removed as required function (no replacement)
|
|
|
|
bool partial_ok; // loading only some functions is ok
|
2014-06-10 23:56:05 +02:00
|
|
|
const struct gl_function *functions;
|
2012-10-03 01:54:13 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#define MAX_FN_COUNT 50 // max functions per gl_functions section
|
|
|
|
|
2014-06-10 23:56:05 +02:00
|
|
|
static const struct gl_functions gl_functions[] = {
|
2012-10-03 01:54:13 +02:00
|
|
|
// GL functions which are always available anywhere at least since 1.1
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(1, 1),
|
|
|
|
.provides = MPGL_CAP_GL,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2014-05-26 22:56:13 +02:00
|
|
|
DEF_FN(Viewport),
|
|
|
|
DEF_FN(Clear),
|
|
|
|
DEF_FN(GenTextures),
|
|
|
|
DEF_FN(DeleteTextures),
|
|
|
|
DEF_FN(TexEnvi),
|
|
|
|
DEF_FN(ClearColor),
|
|
|
|
DEF_FN(Enable),
|
|
|
|
DEF_FN(Disable),
|
|
|
|
DEF_FN(DrawBuffer),
|
|
|
|
DEF_FN(DepthMask),
|
|
|
|
DEF_FN(BlendFunc),
|
|
|
|
DEF_FN(Flush),
|
|
|
|
DEF_FN(Finish),
|
|
|
|
DEF_FN(PixelStorei),
|
|
|
|
DEF_FN(TexImage1D),
|
|
|
|
DEF_FN(TexImage2D),
|
|
|
|
DEF_FN(TexSubImage2D),
|
|
|
|
DEF_FN(GetTexImage),
|
|
|
|
DEF_FN(TexParameteri),
|
|
|
|
DEF_FN(TexParameterf),
|
|
|
|
DEF_FN(TexParameterfv),
|
|
|
|
DEF_FN(GetIntegerv),
|
|
|
|
DEF_FN(GetBooleanv),
|
|
|
|
DEF_FN(ColorMask),
|
|
|
|
DEF_FN(ReadPixels),
|
|
|
|
DEF_FN(ReadBuffer),
|
|
|
|
DEF_FN(DrawArrays),
|
|
|
|
DEF_FN(GetString),
|
|
|
|
DEF_FN(GetError),
|
|
|
|
DEF_FN(GetTexLevelParameteriv),
|
2012-10-03 01:54:13 +02:00
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// GL 2.0-3.x functions
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(2, 0),
|
|
|
|
.provides = MPGL_CAP_GL2,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN(GenBuffers),
|
|
|
|
DEF_FN(DeleteBuffers),
|
|
|
|
DEF_FN(BindBuffer),
|
|
|
|
DEF_FN(MapBuffer),
|
|
|
|
DEF_FN(UnmapBuffer),
|
|
|
|
DEF_FN(BufferData),
|
|
|
|
DEF_FN(ActiveTexture),
|
|
|
|
DEF_FN(BindTexture),
|
|
|
|
DEF_FN(GetAttribLocation),
|
|
|
|
DEF_FN(EnableVertexAttribArray),
|
|
|
|
DEF_FN(DisableVertexAttribArray),
|
|
|
|
DEF_FN(VertexAttribPointer),
|
|
|
|
DEF_FN(UseProgram),
|
|
|
|
DEF_FN(GetUniformLocation),
|
|
|
|
DEF_FN(CompileShader),
|
|
|
|
DEF_FN(CreateProgram),
|
|
|
|
DEF_FN(CreateShader),
|
|
|
|
DEF_FN(ShaderSource),
|
|
|
|
DEF_FN(LinkProgram),
|
|
|
|
DEF_FN(AttachShader),
|
|
|
|
DEF_FN(DeleteShader),
|
|
|
|
DEF_FN(DeleteProgram),
|
|
|
|
DEF_FN(GetShaderInfoLog),
|
|
|
|
DEF_FN(GetShaderiv),
|
|
|
|
DEF_FN(GetProgramInfoLog),
|
|
|
|
DEF_FN(GetProgramiv),
|
|
|
|
DEF_FN(BindAttribLocation),
|
|
|
|
DEF_FN(Uniform1f),
|
|
|
|
DEF_FN(Uniform2f),
|
|
|
|
DEF_FN(Uniform3f),
|
|
|
|
DEF_FN(Uniform1i),
|
2013-05-26 01:48:39 +02:00
|
|
|
DEF_FN(UniformMatrix2fv),
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN(UniformMatrix3fv),
|
|
|
|
DEF_FN(TexImage3D),
|
vo_opengl: fix alpha values written to the framebuffer
When blending OSD and subtitles onto the video, we write bogus alpha
values. This doesn't normally matter, because these values are normally
unused and discarded. But at least on Wayland, the alpha values are used
by the compositor and leads to transparent windows even with opaque
video on places where the OSD happens to use transparency.
(Also see github issue #338.)
Until now, the alpha basically contained garbage. The source factor
GL_SRC_ALPHA meant that alpha was multiplied with itself. Use GL_ONE
instead (which is why we have to use glBlendFuncSeparate()). This should
give correct results, even with video that has alpha. (Or at least it's
something close to correct, I haven't thought too hard how the
compositor will blend it, and in fact I couldn't manage to test it.)
If glBlendFuncSeparate() is not available, fall back to glBlendFunc(),
which does the same as the code did before this commit. Technically, we
support GL 1.1, but glBlendFuncSeparate is 1.4, and I guess we should
try not to crash if vo_opengl_old runs on a system with GL 1.1 drivers
only.
2013-11-10 03:14:13 +01:00
|
|
|
// Added in OpenGL 1.4, but vo_opengl_old doesn't need it
|
|
|
|
DEF_FN(BlendFuncSeparate),
|
2012-10-03 01:54:13 +02:00
|
|
|
{0},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// GL 2.1-3.x functions (also: GLSL 120 shaders)
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(2, 1),
|
|
|
|
.provides = MPGL_CAP_GL21,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN(UniformMatrix4x3fv),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// GL 3.x core only functions.
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(3, 0),
|
|
|
|
.provides = MPGL_CAP_GL3 | MPGL_CAP_SRGB_TEX | MPGL_CAP_SRGB_FB,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN(GetStringi),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// Framebuffers, extension in GL 2.x, core in GL 3.x core.
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(3, 0),
|
|
|
|
.extension = "GL_ARB_framebuffer_object",
|
|
|
|
.provides = MPGL_CAP_FB,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN(BindFramebuffer),
|
|
|
|
DEF_FN(GenFramebuffers),
|
|
|
|
DEF_FN(DeleteFramebuffers),
|
|
|
|
DEF_FN(CheckFramebufferStatus),
|
|
|
|
DEF_FN(FramebufferTexture2D),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// Framebuffers, alternative extension name.
|
|
|
|
{
|
|
|
|
.ver_removed = MPGL_VER(3, 0), // don't touch these fn names in 3.x
|
|
|
|
.extension = "GL_EXT_framebuffer_object",
|
|
|
|
.provides = MPGL_CAP_FB,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN_NAMES(BindFramebuffer, "glBindFramebufferEXT"),
|
|
|
|
DEF_FN_NAMES(GenFramebuffers, "glGenFramebuffersEXT"),
|
|
|
|
DEF_FN_NAMES(DeleteFramebuffers, "glDeleteFramebuffersEXT"),
|
|
|
|
DEF_FN_NAMES(CheckFramebufferStatus, "glCheckFramebufferStatusEXT"),
|
|
|
|
DEF_FN_NAMES(FramebufferTexture2D, "glFramebufferTexture2DEXT"),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// VAOs, extension in GL 2.x, core in GL 3.x core.
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(3, 0),
|
|
|
|
.extension = "GL_ARB_vertex_array_object",
|
|
|
|
.provides = MPGL_CAP_VAO,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN(GenVertexArrays),
|
|
|
|
DEF_FN(BindVertexArray),
|
|
|
|
DEF_FN(DeleteVertexArrays),
|
|
|
|
{0}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// sRGB textures, extension in GL 2.x, core in GL 3.x core.
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(3, 0),
|
|
|
|
.extension = "GL_EXT_texture_sRGB",
|
|
|
|
.provides = MPGL_CAP_SRGB_TEX,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {{0}},
|
2012-10-03 01:54:13 +02:00
|
|
|
},
|
|
|
|
// sRGB framebuffers, extension in GL 2.x, core in GL 3.x core.
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(3, 0),
|
|
|
|
.extension = "GL_EXT_framebuffer_sRGB",
|
|
|
|
.provides = MPGL_CAP_SRGB_FB,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {{0}},
|
2012-10-03 01:54:13 +02:00
|
|
|
},
|
|
|
|
// Float textures, extension in GL 2.x, core in GL 3.x core.
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(3, 0),
|
|
|
|
.extension = "GL_ARB_texture_float",
|
|
|
|
.provides = MPGL_CAP_FLOAT_TEX,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {{0}},
|
2012-10-03 01:54:13 +02:00
|
|
|
},
|
|
|
|
// GL_RED / GL_RG textures, extension in GL 2.x, core in GL 3.x core.
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(3, 0),
|
|
|
|
.extension = "GL_ARB_texture_rg",
|
|
|
|
.provides = MPGL_CAP_TEX_RG,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {{0}},
|
2012-10-03 01:54:13 +02:00
|
|
|
},
|
|
|
|
// Swap control, always an OS specific extension
|
|
|
|
{
|
|
|
|
.extension = "_swap_control",
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN_NAMES(SwapInterval, "glXSwapIntervalSGI", "glXSwapInterval",
|
|
|
|
"wglSwapIntervalSGI", "wglSwapInterval",
|
|
|
|
"wglSwapIntervalEXT"),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
2014-08-15 23:36:10 +02:00
|
|
|
{
|
|
|
|
.extension = "GLX_SGI_video_sync",
|
2014-10-10 13:44:08 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2014-08-15 23:36:10 +02:00
|
|
|
DEF_FN_NAMES(GetVideoSync, "glXGetVideoSyncSGI"),
|
|
|
|
DEF_FN_NAMES(WaitVideoSync, "glXWaitVideoSyncSGI"),
|
|
|
|
{0},
|
|
|
|
},
|
|
|
|
},
|
2012-10-03 01:54:13 +02:00
|
|
|
// GL legacy functions in GL 1.x - 2.x, removed from GL 3.x
|
|
|
|
{
|
|
|
|
.ver_core = MPGL_VER(1, 1),
|
|
|
|
.ver_removed = MPGL_VER(3, 0),
|
|
|
|
.provides = MPGL_CAP_GL_LEGACY,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2014-05-26 22:56:13 +02:00
|
|
|
DEF_FN(Begin),
|
|
|
|
DEF_FN(End),
|
|
|
|
DEF_FN(MatrixMode),
|
|
|
|
DEF_FN(LoadIdentity),
|
|
|
|
DEF_FN(Translated),
|
|
|
|
DEF_FN(Scaled),
|
|
|
|
DEF_FN(Ortho),
|
|
|
|
DEF_FN(PushMatrix),
|
|
|
|
DEF_FN(PopMatrix),
|
|
|
|
DEF_FN(GenLists),
|
|
|
|
DEF_FN(DeleteLists),
|
|
|
|
DEF_FN(NewList),
|
|
|
|
DEF_FN(EndList),
|
|
|
|
DEF_FN(CallList),
|
|
|
|
DEF_FN(CallLists),
|
|
|
|
DEF_FN(Color4ub),
|
|
|
|
DEF_FN(Color4f),
|
|
|
|
DEF_FN(TexCoord2f),
|
|
|
|
DEF_FN(TexCoord2fv),
|
|
|
|
DEF_FN(Vertex2f),
|
|
|
|
DEF_FN(VertexPointer),
|
|
|
|
DEF_FN(ColorPointer),
|
|
|
|
DEF_FN(TexCoordPointer),
|
|
|
|
DEF_FN(EnableClientState),
|
|
|
|
DEF_FN(DisableClientState),
|
2012-10-03 01:54:13 +02:00
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// Loading of old extensions, which are later added to GL 2.0.
|
|
|
|
// NOTE: actually we should be checking the extension strings: the OpenGL
|
|
|
|
// library could provide an entry point, but not implement it.
|
|
|
|
// But the previous code didn't do that, and nobody ever complained.
|
|
|
|
{
|
|
|
|
.ver_removed = MPGL_VER(2, 1),
|
|
|
|
.partial_ok = true,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN_NAMES(GenBuffers, "glGenBuffers", "glGenBuffersARB"),
|
|
|
|
DEF_FN_NAMES(DeleteBuffers, "glDeleteBuffers", "glDeleteBuffersARB"),
|
|
|
|
DEF_FN_NAMES(BindBuffer, "glBindBuffer", "glBindBufferARB"),
|
|
|
|
DEF_FN_NAMES(MapBuffer, "glMapBuffer", "glMapBufferARB"),
|
|
|
|
DEF_FN_NAMES(UnmapBuffer, "glUnmapBuffer", "glUnmapBufferARB"),
|
|
|
|
DEF_FN_NAMES(BufferData, "glBufferData", "glBufferDataARB"),
|
|
|
|
DEF_FN_NAMES(ActiveTexture, "glActiveTexture", "glActiveTextureARB"),
|
|
|
|
DEF_FN_NAMES(BindTexture, "glBindTexture", "glBindTextureARB", "glBindTextureEXT"),
|
|
|
|
DEF_FN_NAMES(MultiTexCoord2f, "glMultiTexCoord2f", "glMultiTexCoord2fARB"),
|
|
|
|
DEF_FN_NAMES(TexImage3D, "glTexImage3D"),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// Ancient ARB shaders.
|
|
|
|
{
|
|
|
|
.extension = "_program",
|
|
|
|
.ver_removed = MPGL_VER(3, 0),
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN_NAMES(GenPrograms, "glGenProgramsARB"),
|
|
|
|
DEF_FN_NAMES(DeletePrograms, "glDeleteProgramsARB"),
|
|
|
|
DEF_FN_NAMES(BindProgram, "glBindProgramARB"),
|
|
|
|
DEF_FN_NAMES(ProgramString, "glProgramStringARB"),
|
|
|
|
DEF_FN_NAMES(GetProgramivARB, "glGetProgramivARB"),
|
|
|
|
DEF_FN_NAMES(ProgramEnvParameter4f, "glProgramEnvParameter4fARB"),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// Ancient ATI extensions.
|
|
|
|
{
|
|
|
|
.extension = "ATI_fragment_shader",
|
|
|
|
.ver_removed = MPGL_VER(3, 0),
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2012-10-03 01:54:13 +02:00
|
|
|
DEF_FN_NAMES(BeginFragmentShader, "glBeginFragmentShaderATI"),
|
|
|
|
DEF_FN_NAMES(EndFragmentShader, "glEndFragmentShaderATI"),
|
|
|
|
DEF_FN_NAMES(SampleMap, "glSampleMapATI"),
|
|
|
|
DEF_FN_NAMES(ColorFragmentOp2, "glColorFragmentOp2ATI"),
|
|
|
|
DEF_FN_NAMES(ColorFragmentOp3, "glColorFragmentOp3ATI"),
|
|
|
|
DEF_FN_NAMES(SetFragmentShaderConstant, "glSetFragmentShaderConstantATI"),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
2013-11-05 22:06:48 +01:00
|
|
|
// For gl_hwdec_vdpau.c
|
|
|
|
// http://www.opengl.org/registry/specs/NV/vdpau_interop.txt
|
|
|
|
{
|
|
|
|
.extension = "GL_NV_vdpau_interop",
|
|
|
|
.provides = MPGL_CAP_VDPAU,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2013-11-05 22:06:48 +01:00
|
|
|
// (only functions needed by us)
|
|
|
|
DEF_FN(VDPAUInitNV),
|
|
|
|
DEF_FN(VDPAUFiniNV),
|
|
|
|
DEF_FN(VDPAURegisterOutputSurfaceNV),
|
|
|
|
DEF_FN(VDPAUUnregisterSurfaceNV),
|
|
|
|
DEF_FN(VDPAUSurfaceAccessNV),
|
|
|
|
DEF_FN(VDPAUMapSurfacesNV),
|
|
|
|
DEF_FN(VDPAUUnmapSurfacesNV),
|
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
2013-11-13 21:52:34 +01:00
|
|
|
// Apple Packed YUV Formats
|
|
|
|
// For gl_hwdec_vda.c
|
|
|
|
// http://www.opengl.org/registry/specs/APPLE/rgb_422.txt
|
|
|
|
{
|
|
|
|
.extension = "GL_APPLE_rgb_422",
|
|
|
|
.provides = MPGL_CAP_APPLE_RGB_422,
|
2014-06-10 23:56:05 +02:00
|
|
|
.functions = (const struct gl_function[]) {
|
2013-11-13 21:52:34 +01:00
|
|
|
{0}
|
|
|
|
},
|
|
|
|
},
|
2012-10-03 01:54:13 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#undef FN_OFFS
|
|
|
|
#undef DEF_FN_HARD
|
|
|
|
#undef DEF_FN
|
|
|
|
#undef DEF_FN_NAMES
|
|
|
|
|
|
|
|
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
// Fill the GL struct with function pointers and extensions from the current
|
2013-03-01 15:55:08 +01:00
|
|
|
// GL context. Called by the backend.
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
// getProcAddress: function to resolve function names, may be NULL
|
|
|
|
// ext2: an extra extension string
|
2013-09-12 00:57:32 +02:00
|
|
|
// log: used to output messages
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
// Note: if you create a CONTEXT_FORWARD_COMPATIBLE_BIT_ARB with OpenGL 3.0,
|
|
|
|
// you must append "GL_ARB_compatibility" to ext2.
|
2014-12-09 17:47:02 +01:00
|
|
|
void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
|
|
|
|
void *fn_ctx, const char *ext2, struct mp_log *log)
|
2011-09-25 11:18:07 +02:00
|
|
|
{
|
2012-10-03 01:54:13 +02:00
|
|
|
talloc_free_children(gl);
|
|
|
|
*gl = (GL) {
|
|
|
|
.extensions = talloc_strdup(gl, ext2 ? ext2 : ""),
|
|
|
|
};
|
2011-09-25 11:18:07 +02:00
|
|
|
|
2014-12-09 17:47:02 +01:00
|
|
|
gl->GetString = get_fn(fn_ctx, "glGetString");
|
2014-05-26 22:56:13 +02:00
|
|
|
if (!gl->GetString) {
|
|
|
|
mp_err(log, "Can't load OpenGL functions.\n");
|
|
|
|
return;
|
|
|
|
}
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
|
2014-05-26 23:05:22 +02:00
|
|
|
int major = 0, minor = 0;
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
const char *version = gl->GetString(GL_VERSION);
|
2014-12-17 21:48:23 +01:00
|
|
|
if (strncmp(version, "OpenGL ES ", 10) == 0) {
|
|
|
|
version += 10;
|
|
|
|
gl->es = true;
|
|
|
|
}
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
sscanf(version, "%d.%d", &major, &minor);
|
|
|
|
gl->version = MPGL_VER(major, minor);
|
2014-12-17 21:48:23 +01:00
|
|
|
mp_verbose(log, "Detected OpenGL %d.%d (%s).\n", major, minor,
|
|
|
|
gl->es ? "GLES" : "desktop");
|
|
|
|
|
|
|
|
if (gl->es && gl->version < MPGL_VER(3, 0)) {
|
|
|
|
mp_warn(log, "At least GLESv3 required.\n");
|
|
|
|
gl->version = 0;
|
|
|
|
return;
|
|
|
|
}
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
|
2014-05-26 23:08:07 +02:00
|
|
|
mp_verbose(log, "GL_VENDOR='%s'\n", gl->GetString(GL_VENDOR));
|
|
|
|
mp_verbose(log, "GL_RENDERER='%s'\n", gl->GetString(GL_RENDERER));
|
|
|
|
mp_verbose(log, "GL_VERSION='%s'\n", gl->GetString(GL_VERSION));
|
2014-08-28 01:32:22 +02:00
|
|
|
const char *shader = gl->GetString(GL_SHADING_LANGUAGE_VERSION);
|
|
|
|
if (shader)
|
|
|
|
mp_verbose(log, "GL_SHADING_LANGUAGE_VERSION='%s'\n", shader);
|
2013-03-01 21:19:20 +01:00
|
|
|
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
// Note: This code doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
|
|
|
|
// on OpenGL 3.0 correctly. Apparently there's no way to detect this
|
|
|
|
// situation, because GL_ARB_compatibility is specified only for 3.1
|
|
|
|
// and above.
|
|
|
|
|
|
|
|
bool has_legacy = false;
|
|
|
|
if (gl->version >= MPGL_VER(3, 0)) {
|
2014-12-09 17:47:02 +01:00
|
|
|
gl->GetStringi = get_fn(fn_ctx, "glGetStringi");
|
|
|
|
gl->GetIntegerv = get_fn(fn_ctx, "glGetIntegerv");
|
2012-03-31 00:33:53 +02:00
|
|
|
|
|
|
|
if (!(gl->GetStringi && gl->GetIntegerv))
|
|
|
|
return;
|
|
|
|
|
|
|
|
GLint exts;
|
|
|
|
gl->GetIntegerv(GL_NUM_EXTENSIONS, &exts);
|
|
|
|
for (int n = 0; n < exts; n++) {
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
const char *ext = gl->GetStringi(GL_EXTENSIONS, n);
|
|
|
|
gl->extensions = talloc_asprintf_append(gl->extensions, " %s", ext);
|
|
|
|
if (strcmp(ext, "GL_ARB_compatibility") == 0)
|
|
|
|
has_legacy = true;
|
2012-03-31 00:33:53 +02:00
|
|
|
}
|
2012-10-03 01:54:13 +02:00
|
|
|
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
// This version doesn't have GL_ARB_compatibility yet, and always
|
|
|
|
// includes legacy (except with CONTEXT_FORWARD_COMPATIBLE_BIT_ARB).
|
|
|
|
if (gl->version == MPGL_VER(3, 0))
|
|
|
|
has_legacy = true;
|
|
|
|
} else {
|
2012-03-31 00:33:53 +02:00
|
|
|
const char *ext = (char*)gl->GetString(GL_EXTENSIONS);
|
2012-10-03 01:54:13 +02:00
|
|
|
gl->extensions = talloc_asprintf_append(gl->extensions, " %s", ext);
|
|
|
|
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
has_legacy = true;
|
2012-03-31 00:33:53 +02:00
|
|
|
}
|
2012-10-03 01:54:13 +02:00
|
|
|
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
if (has_legacy)
|
2014-05-26 23:08:07 +02:00
|
|
|
mp_verbose(log, "OpenGL legacy compat. found.\n");
|
|
|
|
mp_dbg(log, "Combined OpenGL extensions string:\n%s\n", gl->extensions);
|
2012-10-03 01:54:13 +02:00
|
|
|
|
|
|
|
for (int n = 0; n < sizeof(gl_functions) / sizeof(gl_functions[0]); n++) {
|
2014-06-10 23:56:05 +02:00
|
|
|
const struct gl_functions *section = &gl_functions[n];
|
2012-10-03 01:54:13 +02:00
|
|
|
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
// With has_legacy, the legacy functions are still available, and
|
|
|
|
// functions are never actually removed. (E.g. the context could be at
|
|
|
|
// version >= 3.0, but functions like glBegin still exist and work.)
|
|
|
|
if (!has_legacy && section->ver_removed &&
|
|
|
|
gl->version >= section->ver_removed)
|
2012-10-03 01:54:13 +02:00
|
|
|
continue;
|
|
|
|
|
2012-12-27 17:08:17 +01:00
|
|
|
// NOTE: Function entrypoints can exist, even if they do not work.
|
|
|
|
// We must always check extension strings and versions.
|
2012-03-31 00:33:53 +02:00
|
|
|
|
2012-12-27 17:08:17 +01:00
|
|
|
bool exists = false;
|
|
|
|
if (section->ver_core)
|
|
|
|
exists = gl->version >= section->ver_core;
|
|
|
|
|
|
|
|
if (section->extension && strstr(gl->extensions, section->extension))
|
|
|
|
exists = true;
|
|
|
|
|
|
|
|
if (section->partial_ok)
|
|
|
|
exists = true; // possibly
|
|
|
|
|
|
|
|
if (!exists)
|
2012-10-03 01:54:13 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
void *loaded[MAX_FN_COUNT] = {0};
|
|
|
|
bool all_loaded = true;
|
|
|
|
|
|
|
|
for (int i = 0; section->functions[i].funcnames[0]; i++) {
|
2014-06-10 23:56:05 +02:00
|
|
|
const struct gl_function *fn = §ion->functions[i];
|
2012-10-03 01:54:13 +02:00
|
|
|
void *ptr = NULL;
|
|
|
|
for (int x = 0; fn->funcnames[x]; x++) {
|
2014-12-09 17:47:02 +01:00
|
|
|
ptr = get_fn(fn_ctx, fn->funcnames[x]);
|
2012-10-03 01:54:13 +02:00
|
|
|
if (ptr)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!ptr) {
|
|
|
|
all_loaded = false;
|
2012-12-27 17:08:17 +01:00
|
|
|
if (!section->partial_ok) {
|
2013-12-21 21:49:13 +01:00
|
|
|
mp_msg(log, MSGL_V, "Required function '%s' not "
|
|
|
|
"found for %s/%d.%d.\n", fn->funcnames[0],
|
|
|
|
section->extension ? section->extension : "native",
|
|
|
|
MPGL_VER_GET_MAJOR(section->ver_core),
|
|
|
|
MPGL_VER_GET_MINOR(section->ver_core));
|
2012-12-27 17:08:17 +01:00
|
|
|
break;
|
2012-10-03 01:54:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(i < MAX_FN_COUNT);
|
|
|
|
loaded[i] = ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (all_loaded || section->partial_ok) {
|
|
|
|
gl->mpgl_caps |= section->provides;
|
|
|
|
for (int i = 0; section->functions[i].funcnames[0]; i++) {
|
2014-06-10 23:56:05 +02:00
|
|
|
const struct gl_function *fn = §ion->functions[i];
|
2012-10-03 01:54:13 +02:00
|
|
|
void **funcptr = (void**)(((char*)gl) + fn->offset);
|
|
|
|
if (loaded[i])
|
|
|
|
*funcptr = loaded[i];
|
|
|
|
}
|
2011-09-25 11:18:07 +02:00
|
|
|
}
|
2012-10-03 01:54:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gl->glsl_version = 0;
|
2014-12-17 21:48:23 +01:00
|
|
|
if (gl->es) {
|
|
|
|
if (gl->version >= MPGL_VER(3, 0))
|
|
|
|
gl->glsl_version = 300;
|
|
|
|
} else {
|
|
|
|
if (gl->version >= MPGL_VER(2, 0))
|
|
|
|
gl->glsl_version = 110;
|
|
|
|
if (gl->version >= MPGL_VER(2, 1))
|
|
|
|
gl->glsl_version = 120;
|
|
|
|
if (gl->version >= MPGL_VER(3, 0))
|
|
|
|
gl->glsl_version = 130;
|
|
|
|
// Specifically needed for OSX (normally we request 3.0 contexts only, but
|
|
|
|
// OSX always creates 3.2 contexts when requesting a core context).
|
|
|
|
if (gl->version >= MPGL_VER(3, 2))
|
|
|
|
gl->glsl_version = 150;
|
|
|
|
}
|
2012-10-03 01:54:13 +02:00
|
|
|
|
|
|
|
if (!is_software_gl(gl))
|
|
|
|
gl->mpgl_caps |= MPGL_CAP_NO_SW;
|
|
|
|
|
2014-05-26 23:08:07 +02:00
|
|
|
mp_verbose(log, "Detected OpenGL features:");
|
2013-09-12 00:57:32 +02:00
|
|
|
list_features(gl->mpgl_caps, log, MSGL_V, false);
|
2014-12-09 22:28:16 +01:00
|
|
|
|
|
|
|
// Provided for simpler handling if no framebuffer support is available.
|
|
|
|
if (!gl->BindFramebuffer)
|
|
|
|
gl->BindFramebuffer = &dummy_glBindFramebuffer;
|
2005-07-26 12:16:18 +02:00
|
|
|
}
|
|
|
|
|
2014-12-09 17:47:02 +01:00
|
|
|
static void *get_procaddr_wrapper(void *ctx, const char *name)
|
|
|
|
{
|
|
|
|
void *(*getProcAddress)(const GLubyte *) = ctx;
|
|
|
|
return getProcAddress ? getProcAddress((const GLubyte*)name) : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
|
|
|
|
const char *ext2, struct mp_log *log)
|
|
|
|
{
|
|
|
|
mpgl_load_functions2(gl, get_procaddr_wrapper, getProcAddress, ext2, log);
|
|
|
|
}
|
|
|
|
|
2005-07-27 19:22:24 +02:00
|
|
|
/**
|
2005-09-25 18:41:28 +02:00
|
|
|
* \brief return the number of bytes per pixel for the given format
|
2005-07-27 19:22:24 +02:00
|
|
|
* \param format OpenGL format
|
|
|
|
* \param type OpenGL type
|
|
|
|
* \return bytes per pixel
|
2005-09-25 18:41:28 +02:00
|
|
|
* \ingroup glgeneral
|
2005-07-27 19:22:24 +02:00
|
|
|
*
|
2005-09-09 17:54:09 +02:00
|
|
|
* Does not handle all possible variants, just those used by MPlayer
|
2005-07-27 19:22:24 +02:00
|
|
|
*/
|
2011-09-25 11:18:07 +02:00
|
|
|
int glFmt2bpp(GLenum format, GLenum type)
|
|
|
|
{
|
|
|
|
int component_size = 0;
|
|
|
|
switch (type) {
|
2005-07-27 19:22:24 +02:00
|
|
|
case GL_UNSIGNED_BYTE_3_3_2:
|
|
|
|
case GL_UNSIGNED_BYTE_2_3_3_REV:
|
2011-09-25 11:18:07 +02:00
|
|
|
return 1;
|
2005-07-27 19:22:24 +02:00
|
|
|
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:
|
2011-09-25 11:18:07 +02:00
|
|
|
return 2;
|
2006-07-08 21:23:26 +02:00
|
|
|
case GL_UNSIGNED_BYTE:
|
2011-09-25 11:18:07 +02:00
|
|
|
component_size = 1;
|
|
|
|
break;
|
2006-07-08 21:23:26 +02:00
|
|
|
case GL_UNSIGNED_SHORT:
|
2011-09-25 11:18:07 +02:00
|
|
|
component_size = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (format) {
|
2005-07-27 19:22:24 +02:00
|
|
|
case GL_LUMINANCE:
|
|
|
|
case GL_ALPHA:
|
2011-09-25 11:18:07 +02:00
|
|
|
return component_size;
|
2008-12-05 16:36:54 +01:00
|
|
|
case GL_YCBCR_MESA:
|
2013-11-13 21:52:34 +01:00
|
|
|
case GL_RGB_422_APPLE:
|
2011-09-25 11:18:07 +02:00
|
|
|
return 2;
|
2005-07-27 19:22:24 +02:00
|
|
|
case GL_RGB:
|
|
|
|
case GL_BGR:
|
2014-12-17 21:48:23 +01:00
|
|
|
case GL_RGB_INTEGER:
|
2011-09-25 11:18:07 +02:00
|
|
|
return 3 * component_size;
|
2005-07-27 19:22:24 +02:00
|
|
|
case GL_RGBA:
|
|
|
|
case GL_BGRA:
|
2014-12-17 21:48:23 +01:00
|
|
|
case GL_RGBA_INTEGER:
|
2011-09-25 11:18:07 +02:00
|
|
|
return 4 * component_size;
|
2011-11-08 20:21:00 +01:00
|
|
|
case GL_RED:
|
2014-12-17 21:48:23 +01:00
|
|
|
case GL_RED_INTEGER:
|
2011-11-08 20:21:00 +01:00
|
|
|
return component_size;
|
2012-03-31 00:33:53 +02:00
|
|
|
case GL_RG:
|
|
|
|
case GL_LUMINANCE_ALPHA:
|
2014-12-17 21:48:23 +01:00
|
|
|
case GL_RG_INTEGER:
|
2012-03-31 00:33:53 +02:00
|
|
|
return 2 * component_size;
|
2011-09-25 11:18:07 +02:00
|
|
|
}
|
2012-11-01 01:05:17 +01:00
|
|
|
abort(); // unknown
|
2005-07-27 19:22:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \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
|
2006-11-25 14:34:55 +01:00
|
|
|
* \param dataptr data to upload
|
2005-07-27 19:22:24 +02:00
|
|
|
* \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
|
2005-09-25 18:41:28 +02:00
|
|
|
* \ingroup gltexture
|
2005-07-27 19:22:24 +02:00
|
|
|
*/
|
2011-09-25 11:18:07 +02:00
|
|
|
void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
|
2006-11-25 14:34:55 +01:00
|
|
|
const void *dataptr, int stride,
|
2011-09-25 11:18:07 +02:00
|
|
|
int x, int y, int w, int h, int slice)
|
|
|
|
{
|
|
|
|
const uint8_t *data = dataptr;
|
|
|
|
int y_max = y + h;
|
|
|
|
if (w <= 0 || h <= 0)
|
|
|
|
return;
|
|
|
|
if (slice <= 0)
|
|
|
|
slice = h;
|
|
|
|
if (stride < 0) {
|
|
|
|
data += (h - 1) * stride;
|
|
|
|
stride = -stride;
|
|
|
|
}
|
|
|
|
// this is not always correct, but should work for MPlayer
|
|
|
|
glAdjustAlignment(gl, stride);
|
|
|
|
gl->PixelStorei(GL_UNPACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
|
|
|
|
for (; y + slice <= y_max; y += slice) {
|
|
|
|
gl->TexSubImage2D(target, 0, x, y, w, slice, format, type, data);
|
|
|
|
data += stride * slice;
|
|
|
|
}
|
|
|
|
if (y < y_max)
|
|
|
|
gl->TexSubImage2D(target, 0, x, y, w, y_max - y, format, type, data);
|
2005-07-27 19:22:24 +02:00
|
|
|
}
|
|
|
|
|
2012-09-28 21:25:26 +02:00
|
|
|
// Like glUploadTex, but upload a byte array with all elements set to val.
|
|
|
|
// If scratch is not NULL, points to a resizeable talloc memory block than can
|
|
|
|
// be freely used by the function (for avoiding temporary memory allocations).
|
|
|
|
void glClearTex(GL *gl, GLenum target, GLenum format, GLenum type,
|
|
|
|
int x, int y, int w, int h, uint8_t val, void **scratch)
|
|
|
|
{
|
|
|
|
int bpp = glFmt2bpp(format, type);
|
|
|
|
int stride = w * bpp;
|
|
|
|
int size = h * stride;
|
|
|
|
if (size < 1)
|
|
|
|
return;
|
|
|
|
void *data = scratch ? *scratch : NULL;
|
|
|
|
if (talloc_get_size(data) < size)
|
|
|
|
data = talloc_realloc(NULL, data, char *, size);
|
|
|
|
memset(data, val, size);
|
|
|
|
glAdjustAlignment(gl, stride);
|
|
|
|
gl->PixelStorei(GL_UNPACK_ROW_LENGTH, w);
|
|
|
|
gl->TexSubImage2D(target, 0, x, y, w, h, format, type, data);
|
|
|
|
if (scratch) {
|
|
|
|
*scratch = data;
|
|
|
|
} else {
|
|
|
|
talloc_free(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-06 20:46:01 +02:00
|
|
|
/**
|
|
|
|
* \brief download 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 dataptr destination memory for download
|
|
|
|
* \param stride data stride (must be positive)
|
|
|
|
* \ingroup gltexture
|
|
|
|
*/
|
|
|
|
void glDownloadTex(GL *gl, GLenum target, GLenum format, GLenum type,
|
|
|
|
void *dataptr, int stride)
|
|
|
|
{
|
|
|
|
// this is not always correct, but should work for MPlayer
|
|
|
|
glAdjustAlignment(gl, stride);
|
|
|
|
gl->PixelStorei(GL_PACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
|
|
|
|
gl->GetTexImage(target, 0, format, type, dataptr);
|
|
|
|
}
|
|
|
|
|
2012-10-21 16:25:42 +02:00
|
|
|
mp_image_t *glGetWindowScreenshot(GL *gl)
|
|
|
|
{
|
|
|
|
GLint vp[4]; //x, y, w, h
|
|
|
|
gl->GetIntegerv(GL_VIEWPORT, vp);
|
2012-12-22 21:46:22 +01:00
|
|
|
mp_image_t *image = mp_image_alloc(IMGFMT_RGB24, vp[2], vp[3]);
|
video: introduce failure path for image allocations
Until now, failure to allocate image data resulted in a crash (i.e.
abort() was called). This was intentional, because it's pretty silly to
degrade playback, and in almost all situations, the OOM will probably
kill you anyway. (And then there's the standard Linux overcommit
behavior, which also will kill you at some point.)
But I changed my opinion, so here we go. This change does not affect
_all_ memory allocations, just image data. Now in most failure cases,
the output will just be skipped. For video filters, this coincidentally
means that failure is treated as EOF (because the playback core assumes
EOF if nothing comes out of the video filter chain). In other
situations, output might be in some way degraded, like skipping frames,
not scaling OSD, and such.
Functions whose return values changed semantics:
mp_image_alloc
mp_image_new_copy
mp_image_new_ref
mp_image_make_writeable
mp_image_setrefp
mp_image_to_av_frame_and_unref
mp_image_from_av_frame
mp_image_new_external_ref
mp_image_new_custom_ref
mp_image_pool_make_writeable
mp_image_pool_get
mp_image_pool_new_copy
mp_vdpau_mixed_frame_create
vf_alloc_out_image
vf_make_out_image_writeable
glGetWindowScreenshot
2014-06-17 22:43:43 +02:00
|
|
|
if (!image)
|
|
|
|
return NULL;
|
2012-10-21 16:25:42 +02:00
|
|
|
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
2013-05-30 15:41:01 +02:00
|
|
|
gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
|
2012-10-21 16:25:42 +02:00
|
|
|
gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
|
|
|
|
gl->ReadBuffer(GL_FRONT);
|
2013-05-30 15:41:01 +02:00
|
|
|
//flip image while reading (and also avoid stride-related trouble)
|
2012-10-21 16:25:42 +02:00
|
|
|
for (int y = 0; y < vp[3]; y++) {
|
|
|
|
gl->ReadPixels(vp[0], vp[1] + vp[3] - y - 1, vp[2], 1,
|
|
|
|
GL_RGB, GL_UNSIGNED_BYTE,
|
|
|
|
image->planes[0] + y * image->stride[0]);
|
|
|
|
}
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2013-03-01 15:55:08 +01:00
|
|
|
typedef void (*MPGLSetBackendFn)(MPGLContext *ctx);
|
2012-10-03 01:54:13 +02:00
|
|
|
|
2013-03-01 15:55:08 +01:00
|
|
|
struct backend {
|
|
|
|
const char *name;
|
|
|
|
MPGLSetBackendFn init;
|
|
|
|
};
|
2011-10-15 18:44:00 +02:00
|
|
|
|
2014-06-10 23:56:05 +02:00
|
|
|
static const struct backend backends[] = {
|
2013-07-16 13:28:28 +02:00
|
|
|
#if HAVE_GL_COCOA
|
2013-03-01 15:55:08 +01:00
|
|
|
{"cocoa", mpgl_set_backend_cocoa},
|
2011-10-15 18:44:00 +02:00
|
|
|
#endif
|
2013-07-16 13:28:28 +02:00
|
|
|
#if HAVE_GL_WIN32
|
2013-03-01 15:55:08 +01:00
|
|
|
{"win", mpgl_set_backend_w32},
|
2009-12-08 07:42:46 +01:00
|
|
|
#endif
|
2013-09-14 16:30:03 +02:00
|
|
|
|
|
|
|
//Add the wayland backend before x11, in order to probe for a wayland-server before a x11-server and avoid using xwayland
|
2013-07-16 13:28:28 +02:00
|
|
|
#if HAVE_GL_WAYLAND
|
2013-03-01 15:55:08 +01:00
|
|
|
{"wayland", mpgl_set_backend_wayland},
|
2013-09-14 16:30:03 +02:00
|
|
|
#endif
|
2013-07-16 13:28:28 +02:00
|
|
|
#if HAVE_GL_X11
|
2013-09-14 16:30:03 +02:00
|
|
|
{"x11", mpgl_set_backend_x11},
|
2014-11-04 00:12:04 +01:00
|
|
|
#endif
|
|
|
|
#if HAVE_EGL_X11
|
|
|
|
{"x11egl", mpgl_set_backend_x11egl},
|
2014-12-17 21:48:23 +01:00
|
|
|
{"x11egles", mpgl_set_backend_x11egles},
|
2013-02-28 19:55:02 +01:00
|
|
|
#endif
|
2011-12-18 20:02:31 +01:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
|
|
|
int mpgl_find_backend(const char *name)
|
|
|
|
{
|
2013-03-01 15:55:08 +01:00
|
|
|
if (name == NULL || strcmp(name, "auto") == 0)
|
|
|
|
return -1;
|
2011-12-18 20:02:31 +01:00
|
|
|
for (const struct backend *entry = backends; entry->name; entry++) {
|
|
|
|
if (strcmp(entry->name, name) == 0)
|
2013-03-01 15:55:08 +01:00
|
|
|
return entry - backends;
|
2011-12-18 20:02:31 +01:00
|
|
|
}
|
2013-03-01 15:55:08 +01:00
|
|
|
return -2;
|
2011-12-18 20:02:31 +01:00
|
|
|
}
|
|
|
|
|
2013-12-21 20:03:36 +01:00
|
|
|
int mpgl_validate_backend_opt(struct mp_log *log, const struct m_option *opt,
|
|
|
|
struct bstr name, struct bstr param)
|
2013-07-22 01:21:39 +02:00
|
|
|
{
|
2013-07-22 02:14:15 +02:00
|
|
|
if (bstr_equals0(param, "help")) {
|
2013-12-21 20:03:36 +01:00
|
|
|
mp_info(log, "OpenGL windowing backends:\n");
|
|
|
|
mp_info(log, " auto (autodetect)\n");
|
2013-07-22 02:14:15 +02:00
|
|
|
for (const struct backend *entry = backends; entry->name; entry++)
|
2013-12-21 20:03:36 +01:00
|
|
|
mp_info(log, " %s\n", entry->name);
|
2013-07-22 02:14:15 +02:00
|
|
|
return M_OPT_EXIT - 1;
|
|
|
|
}
|
2013-07-22 01:21:39 +02:00
|
|
|
char s[20];
|
|
|
|
snprintf(s, sizeof(s), "%.*s", BSTR_P(param));
|
|
|
|
return mpgl_find_backend(s) >= -1 ? 1 : M_OPT_INVALID;
|
|
|
|
}
|
|
|
|
|
2013-09-10 18:33:43 +02:00
|
|
|
static MPGLContext *init_backend(struct vo *vo, MPGLSetBackendFn set_backend,
|
|
|
|
bool probing)
|
2011-09-25 11:18:07 +02:00
|
|
|
{
|
2013-03-01 15:55:08 +01:00
|
|
|
MPGLContext *ctx = talloc_ptrtype(NULL, ctx);
|
2012-10-03 01:54:13 +02:00
|
|
|
*ctx = (MPGLContext) {
|
|
|
|
.gl = talloc_zero(ctx, GL),
|
|
|
|
.vo = vo,
|
|
|
|
};
|
2013-09-10 18:33:43 +02:00
|
|
|
vo->probing = probing;
|
2013-03-01 15:55:08 +01:00
|
|
|
set_backend(ctx);
|
|
|
|
if (!ctx->vo_init(vo)) {
|
|
|
|
talloc_free(ctx);
|
|
|
|
ctx = NULL;
|
|
|
|
}
|
2013-09-10 18:33:43 +02:00
|
|
|
vo->probing = false;
|
2013-03-01 15:55:08 +01:00
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
2014-11-26 20:48:11 +01:00
|
|
|
static MPGLContext *mpgl_create(struct vo *vo, const char *backend_name)
|
2013-03-01 15:55:08 +01:00
|
|
|
{
|
|
|
|
MPGLContext *ctx = NULL;
|
|
|
|
int index = mpgl_find_backend(backend_name);
|
|
|
|
if (index == -1) {
|
|
|
|
for (const struct backend *entry = backends; entry->name; entry++) {
|
2013-09-10 18:33:43 +02:00
|
|
|
ctx = init_backend(vo, entry->init, true);
|
2013-03-01 15:55:08 +01:00
|
|
|
if (ctx)
|
2013-09-10 18:33:43 +02:00
|
|
|
break;
|
2013-03-01 15:55:08 +01:00
|
|
|
}
|
|
|
|
} else if (index >= 0) {
|
2013-09-10 18:33:43 +02:00
|
|
|
ctx = init_backend(vo, backends[index].init, false);
|
2011-09-25 11:18:07 +02:00
|
|
|
}
|
2013-03-01 15:55:08 +01:00
|
|
|
return ctx;
|
2009-12-08 07:42:46 +01:00
|
|
|
}
|
|
|
|
|
2014-11-26 20:48:11 +01:00
|
|
|
MPGLContext *mpgl_init(struct vo *vo, const char *backend_name,
|
|
|
|
int gl_caps, int vo_flags)
|
2012-10-03 01:54:13 +02:00
|
|
|
{
|
2014-11-26 20:48:11 +01:00
|
|
|
MPGLContext *ctx = mpgl_create(vo, backend_name);
|
|
|
|
if (!ctx)
|
|
|
|
return NULL;
|
|
|
|
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
gl_caps |= MPGL_CAP_GL;
|
|
|
|
|
|
|
|
ctx->requested_gl_version = (gl_caps & MPGL_CAP_GL_LEGACY)
|
|
|
|
? MPGL_VER(2, 1) : MPGL_VER(3, 0);
|
|
|
|
|
2014-11-26 20:48:11 +01:00
|
|
|
if (ctx->config_window(ctx, vo_flags | VOFLAG_HIDDEN)) {
|
2012-10-03 01:54:13 +02:00
|
|
|
int missing = (ctx->gl->mpgl_caps & gl_caps) ^ gl_caps;
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
if (!missing)
|
2014-11-26 20:48:11 +01:00
|
|
|
return ctx;
|
gl_common: simplify window/context creation
Allow the backend code to create a GL context on best effort basis,
instead of having to implement separate functions for each variation.
This means there's only a single create_window callback now. Also,
getFunctions() doesn't have the gl3 parameter anymore, which was
confusing and hard to explain.
create_window() tries to create a GL context of any version. The field
MPGLContext.requested_gl_version is taken as a hint whether a GL3 or a
legacy context is preferred. (This should be easy on all platforms.)
The cocoa part always assumes that GL 3 is always available on
OSX 10.7.0 and higher, and miserably fails if it's not. One could try
to put more effort into probing the context, but apparently this
situation never happens, so don't bother. (And even if, mpv should be
able to fall back to vo_corevideo.)
The X11 part doesn't change much, but moving these functions around
makes the diff bigger.
Note about some corner cases:
This doesn't handle CONTEXT_FORWARD_COMPATIBLE_BIT_ARB on OpenGL 3.0
correctly. This was the one thing getFunctions() actually needed the
gl3 parameter, and we just make sure we never use forward compatible
contexts on 3.0. It should work with any version above (e.g. 3.1, 3.2
and 3.3 should be fine). This is because the GL_ARB_compatibility
extension is specified for 3.1 and up only. There doesn't seem to be
any way to detect presence of legacy GL on 3.0 with a forward
compatible context. As a counter measure, remove the FORWARD_COMPATIBLE
flags from the win32 code. Maybe this will go wrong. (Should this
happen, the flag has the be added back, and the win32 will have to
explicitly check for GL 3.0 and add "GL_ARB_compatibility" to the extra
extension string.)
Note about GLX:
Probing GL versions by trying to create a context on an existing window
was (probably) not always possible. Old code used GLX 1.2 to create
legacy contexts, and it required code different from GLX 1.3 even before
creation of the X window (the problem was selections of the X Visual).
That's why there were two functions for window creation (create_window_old
and create_window_gl3). However, the legacy context creation code was
updated to GLX 1.3 in commit b3b20cc, so having different functions for
window creation is not needed anymore.
2013-02-24 23:31:57 +01:00
|
|
|
|
2013-09-12 00:57:32 +02:00
|
|
|
MP_WARN(ctx->vo, "Missing OpenGL features:");
|
|
|
|
list_features(missing, ctx->vo->log, MSGL_WARN, false);
|
2013-11-14 19:33:57 +01:00
|
|
|
if (missing == MPGL_CAP_NO_SW) {
|
2013-09-12 00:57:32 +02:00
|
|
|
MP_WARN(ctx->vo, "Rejecting suspected software OpenGL renderer.\n");
|
2013-10-26 14:13:55 +02:00
|
|
|
} else if ((missing & MPGL_CAP_GL21) &&
|
|
|
|
(ctx->gl->mpgl_caps & MPGL_CAP_GL_LEGACY))
|
|
|
|
{
|
|
|
|
MP_WARN(ctx->vo, "OpenGL version too old. Try: --vo=opengl-old\n");
|
|
|
|
}
|
2012-03-31 00:33:53 +02:00
|
|
|
}
|
2012-10-03 01:54:13 +02:00
|
|
|
|
2013-09-12 00:57:32 +02:00
|
|
|
MP_ERR(ctx->vo, "OpenGL context creation failed!\n");
|
2014-11-26 20:48:11 +01:00
|
|
|
mpgl_uninit(ctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool mpgl_reconfig_window(struct MPGLContext *ctx, int flags)
|
|
|
|
{
|
|
|
|
return ctx->config_window(ctx, flags);
|
2012-10-03 01:54:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void mpgl_uninit(MPGLContext *ctx)
|
2011-09-25 11:18:07 +02:00
|
|
|
{
|
2013-03-02 17:08:05 +01:00
|
|
|
if (ctx) {
|
2012-10-03 01:54:13 +02:00
|
|
|
ctx->releaseGlContext(ctx);
|
|
|
|
ctx->vo_uninit(ctx->vo);
|
|
|
|
}
|
2011-09-25 11:18:07 +02:00
|
|
|
talloc_free(ctx);
|
2009-12-08 07:42:46 +01:00
|
|
|
}
|
2012-03-31 01:13:38 +02:00
|
|
|
|
2013-03-04 00:38:04 +01:00
|
|
|
void mpgl_set_context(MPGLContext *ctx)
|
|
|
|
{
|
|
|
|
if (ctx->set_current)
|
|
|
|
ctx->set_current(ctx, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mpgl_unset_context(MPGLContext *ctx)
|
|
|
|
{
|
|
|
|
if (ctx->set_current)
|
|
|
|
ctx->set_current(ctx, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mpgl_lock(MPGLContext *ctx)
|
|
|
|
{
|
|
|
|
mpgl_set_context(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mpgl_unlock(MPGLContext *ctx)
|
|
|
|
{
|
|
|
|
mpgl_unset_context(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool mpgl_is_thread_safe(MPGLContext *ctx)
|
|
|
|
{
|
|
|
|
return !!ctx->set_current;
|
|
|
|
}
|
|
|
|
|
2013-07-31 21:44:21 +02:00
|
|
|
void mp_log_source(struct mp_log *log, int lev, const char *src)
|
2012-03-31 01:13:38 +02:00
|
|
|
{
|
|
|
|
int line = 1;
|
|
|
|
if (!src)
|
|
|
|
return;
|
|
|
|
while (*src) {
|
|
|
|
const char *end = strchr(src, '\n');
|
|
|
|
const char *next = end + 1;
|
|
|
|
if (!end)
|
|
|
|
next = end = src + strlen(src);
|
2013-12-21 21:49:13 +01:00
|
|
|
mp_msg(log, lev, "[%3d] %.*s\n", line, (int)(end - src), src);
|
2012-03-31 01:13:38 +02:00
|
|
|
line++;
|
|
|
|
src = next;
|
|
|
|
}
|
|
|
|
}
|