mirror of https://github.com/mpv-player/mpv
118 lines
3.3 KiB
C
118 lines
3.3 KiB
C
#include "gl_common.h"
|
|
|
|
/**
|
|
* \brief adjusts the GL_UNPACK_ALGNMENT to fit the stride.
|
|
* \param stride number of bytes per line for which alignment should fit.
|
|
*/
|
|
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;
|
|
glPixelStorei (GL_UNPACK_ALIGNMENT, gl_alignment);
|
|
}
|
|
|
|
#ifndef GL_WIN32
|
|
/**
|
|
* Returns the XVisualInfo associated with Window win.
|
|
* \param win Window whose XVisualInfo is returne.
|
|
* \return XVisualInfo of the window. Caller must use XFree to free it.
|
|
*/
|
|
static XVisualInfo *getWindowVisualInfo(Window win) {
|
|
XWindowAttributes xw_attr;
|
|
XVisualInfo vinfo_template;
|
|
int tmp;
|
|
XGetWindowAttributes(mDisplay, win, &xw_attr);
|
|
vinfo_template.visualid = XVisualIDFromVisual(xw_attr.visual);
|
|
return XGetVisualInfo(mDisplay, VisualIDMask, &vinfo_template, &tmp);
|
|
}
|
|
|
|
/**
|
|
* \brief Changes the window in which video is displayed.
|
|
* If possible only transfers the context to the new window, otherwise
|
|
* creates a new one, which must be initialized by the caller.
|
|
* \param vinfo Currently used visual.
|
|
* \param context Currently used context.
|
|
* \param win window that should be used for drawing.
|
|
* \return one of SET_WINDOW_FAILED, SET_WINDOW_OK or SET_WINDOW_REINIT.
|
|
* In case of SET_WINDOW_REINIT the context could not be transfered
|
|
* and the caller must initialize it correctly.
|
|
*/
|
|
int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win)
|
|
{
|
|
XVisualInfo *new_vinfo;
|
|
GLXContext new_context = NULL;
|
|
int keep_context = 0;
|
|
|
|
// should only be needed when keeping context, but not doing glFinish
|
|
// can cause flickering even when we do not keep it.
|
|
glFinish();
|
|
new_vinfo = getWindowVisualInfo(win);
|
|
if (*context && *vinfo && new_vinfo &&
|
|
(*vinfo)->visualid == new_vinfo->visualid) {
|
|
// we can keep the GLXContext
|
|
new_context = *context;
|
|
XFree(new_vinfo);
|
|
new_vinfo = *vinfo;
|
|
keep_context = 1;
|
|
} else {
|
|
// create a context
|
|
new_context = glXCreateContext(mDisplay, new_vinfo, NULL, True);
|
|
if (!new_context) {
|
|
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GLX context!\n");
|
|
XFree(new_vinfo);
|
|
return SET_WINDOW_FAILED;
|
|
}
|
|
}
|
|
|
|
// set context
|
|
if (!glXMakeCurrent(mDisplay, vo_window, new_context)) {
|
|
mp_msg (MSGT_VO, MSGL_FATAL, "[gl] Could not set GLX context!\n");
|
|
if (!keep_context) {
|
|
glXDestroyContext (mDisplay, new_context);
|
|
XFree(new_vinfo);
|
|
}
|
|
return SET_WINDOW_FAILED;
|
|
}
|
|
|
|
// set new values
|
|
vo_window = win;
|
|
{
|
|
Window root;
|
|
int tmp;
|
|
XGetGeometry(mDisplay, vo_window, &root, &tmp, &tmp,
|
|
&vo_dwidth, &vo_dheight, &tmp, &tmp);
|
|
}
|
|
if (!keep_context) {
|
|
if (*context)
|
|
glXDestroyContext(mDisplay, *context);
|
|
*context = new_context;
|
|
if (*vinfo)
|
|
XFree(*vinfo);
|
|
*vinfo = new_vinfo;
|
|
|
|
// and inform that reinit is neccessary
|
|
return SET_WINDOW_REINIT;
|
|
}
|
|
return SET_WINDOW_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief free the VisualInfo and GLXContext of an OpenGL context.
|
|
*/
|
|
void releaseGlContext(XVisualInfo **vinfo, GLXContext *context) {
|
|
if (*vinfo)
|
|
XFree(*vinfo);
|
|
*vinfo = NULL;
|
|
if (*context)
|
|
glXDestroyContext(mDisplay, *context);
|
|
*context = 0;
|
|
}
|
|
#endif
|
|
|