Commit ed9fe3b7 authored by Thomas Guillem's avatar Thomas Guillem

glwin32: use vlc_gl_t from vlc_gl_Create()

This remove code duplication between glwin32 and wgl.

This plugin will now use the wgl gl plugin but it can also works with with any
other gl plugins (EGL for windows ?).
parent b0f05830
......@@ -44,16 +44,11 @@
static int Open (vlc_object_t *);
static void Close(vlc_object_t *);
#define HW_GPU_AFFINITY_TEXT N_("GPU affinity")
vlc_module_begin()
set_category(CAT_VIDEO)
set_subcategory(SUBCAT_VIDEO_VOUT)
set_shortname("OpenGL")
set_description(N_("OpenGL video output for Windows"))
add_integer("gpu-affinity", -1, HW_GPU_AFFINITY_TEXT, HW_GPU_AFFINITY_TEXT, true)
set_capability("vout display", 275)
add_shortcut("glwin32", "opengl")
set_callbacks(Open, Close)
......@@ -67,11 +62,8 @@ struct vout_display_sys_t
{
vout_display_sys_win32_t sys;
HDC hGLDC;
HGLRC hGLRC;
vlc_gl_t *gl;
vout_display_opengl_t *vgl;
HDC affinityHDC; // DC for the selected GPU
};
static picture_pool_t *Pool (vout_display_t *, unsigned);
......@@ -79,88 +71,6 @@ static void Prepare(vout_display_t *, picture_t *, subpicture_t *);
static void Display(vout_display_t *, picture_t *, subpicture_t *);
static void Manage (vout_display_t *);
static void Swap (vlc_gl_t *);
static void *OurGetProcAddress(vlc_gl_t *, const char *);
/* Create an GPU Affinity DC */
static void CreateGPUAffinityDC(vout_display_t *vd, UINT nVidiaAffinity) {
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
/* create a temporary GL context */
HDC winDC = GetDC(vd->sys->sys.hvideownd);
SetPixelFormat(winDC, ChoosePixelFormat(winDC, &pfd), &pfd);
HGLRC hGLRC = wglCreateContext(winDC);
wglMakeCurrent(winDC, hGLRC);
/* Initialize the necessary function pointers */
PFNWGLENUMGPUSNVPROC fncEnumGpusNV = (PFNWGLENUMGPUSNVPROC)wglGetProcAddress("wglEnumGpusNV");
PFNWGLCREATEAFFINITYDCNVPROC fncCreateAffinityDCNV = (PFNWGLCREATEAFFINITYDCNVPROC)wglGetProcAddress("wglCreateAffinityDCNV");
/* delete the temporary GL context */
wglDeleteContext(hGLRC);
/* see if we have the extensions */
if (!fncEnumGpusNV || !fncCreateAffinityDCNV) return;
/* find the graphics card */
HGPUNV GpuMask[2];
GpuMask[0] = NULL;
GpuMask[1] = NULL;
HGPUNV hGPU;
if (!fncEnumGpusNV(nVidiaAffinity, &hGPU)) return;
/* make the affinity DC */
GpuMask[0] = hGPU;
vd->sys->affinityHDC = fncCreateAffinityDCNV(GpuMask);
if (vd->sys->affinityHDC == NULL) return;
SetPixelFormat(vd->sys->affinityHDC,
ChoosePixelFormat(vd->sys->affinityHDC, &pfd), &pfd);
msg_Dbg( vd, "GPU affinity set to adapter: %d",
nVidiaAffinity );
}
/* Destroy an GPU Affinity DC */
static void DestroyGPUAffinityDC(vout_display_t *vd) {
if (vd->sys->affinityHDC == NULL) return;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
/* create a temporary GL context */
HDC winDC = GetDC(vd->sys->sys.hvideownd);
SetPixelFormat(winDC, ChoosePixelFormat(winDC, &pfd), &pfd);
HGLRC hGLRC = wglCreateContext(winDC);
wglMakeCurrent(winDC, hGLRC);
/* Initialize the necessary function pointers */
PFNWGLDELETEDCNVPROC fncDeleteDCNV = (PFNWGLDELETEDCNVPROC)wglGetProcAddress("wglDeleteDCNV");
/* delete the temporary GL context */
wglDeleteContext(hGLRC);
/* see if we have the extensions */
if (!fncDeleteDCNV) return;
/* delete the affinity DC */
fncDeleteDCNV(vd->sys->affinityHDC);
}
static int Control(vout_display_t *vd, int query, va_list args)
{
vout_display_sys_t *sys = vd->sys;
......@@ -172,6 +82,29 @@ static int Control(vout_display_t *vd, int query, va_list args)
return CommonControl(vd, query, args);
}
static int EmbedVideoWindow_Control(vout_window_t *wnd, int query, va_list ap)
{
VLC_UNUSED( ap ); VLC_UNUSED( query );
return VLC_EGENERIC;
}
static vout_window_t *EmbedVideoWindow_Create(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
if (!sys->sys.hvideownd)
return NULL;
vout_window_t *wnd = vlc_object_create(vd, sizeof(vout_window_t));
if (!wnd)
return NULL;
wnd->type = VOUT_WINDOW_TYPE_HWND;
wnd->handle.hwnd = sys->sys.hvideownd;
wnd->control = EmbedVideoWindow_Control;
return wnd;
}
/**
* It creates an OpenGL vout display.
*/
......@@ -191,57 +124,26 @@ static int Open(vlc_object_t *object)
EventThreadUpdateTitle(sys->sys.event, VOUT_TITLE " (OpenGL output)");
/* process selected GPU affinity */
int nVidiaAffinity = var_InheritInteger(vd, "gpu-affinity");
if (nVidiaAffinity >= 0) CreateGPUAffinityDC(vd, nVidiaAffinity);
/* */
sys->hGLDC = GetDC(sys->sys.hvideownd);
/* Set the pixel format for the DC */
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(sys->hGLDC,
ChoosePixelFormat(sys->hGLDC, &pfd), &pfd);
/*
* Create and enable the render context
* For GPU affinity, attach the window DC
* to the GPU affinity DC
*/
sys->hGLRC = wglCreateContext((sys->affinityHDC != NULL) ? sys->affinityHDC : sys->hGLDC);
wglMakeCurrent(sys->hGLDC, sys->hGLRC);
const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
#ifdef WGL_EXT_swap_control
if (HasExtension(extensions, "WGL_EXT_swap_control")) {
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
if (SwapIntervalEXT)
SwapIntervalEXT(1);
}
#endif
/* */
sys->gl = vlc_object_create(object, sizeof(*sys->gl));
vout_window_t *surface = EmbedVideoWindow_Create(vd);
if (!surface)
goto error;
if (unlikely(!sys->gl))
sys->gl = vlc_gl_Create (surface, VLC_OPENGL, "$gl");
if (!sys->gl)
{
vlc_object_release(surface);
goto error;
}
sys->gl->swap = Swap;
sys->gl->getProcAddress = OurGetProcAddress;
sys->gl->sys = vd;
vlc_gl_Resize (sys->gl, vd->cfg->display.width, vd->cfg->display.height);
video_format_t fmt = vd->fmt;
const vlc_fourcc_t *subpicture_chromas;
if (vlc_gl_MakeCurrent (sys->gl))
goto error;
sys->vgl = vout_display_opengl_New(&fmt, &subpicture_chromas, sys->gl,
&vd->cfg->viewpoint);
vlc_gl_ReleaseCurrent (sys->gl);
if (!sys->vgl)
goto error;
......@@ -273,20 +175,20 @@ static void Close(vlc_object_t *object)
{
vout_display_t *vd = (vout_display_t *)object;
vout_display_sys_t *sys = vd->sys;
if (sys->vgl)
vout_display_opengl_Delete(sys->vgl);
if (sys->gl)
vlc_object_release(sys->gl);
if (sys->hGLDC && sys->hGLRC)
wglMakeCurrent(NULL, NULL);
if (sys->hGLRC)
wglDeleteContext(sys->hGLRC);
if (sys->hGLDC)
ReleaseDC(sys->sys.hvideownd, sys->hGLDC);
DestroyGPUAffinityDC(vd);
vlc_gl_t *gl = sys->gl;
if (gl)
{
vout_window_t *surface = gl->surface;
if (sys->vgl)
{
vlc_gl_MakeCurrent (gl);
vout_display_opengl_Delete(sys->vgl);
vlc_gl_ReleaseCurrent (gl);
}
vlc_gl_Release (gl);
vlc_object_release(surface);
}
CommonClean(vd);
......@@ -298,8 +200,11 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
{
vout_display_sys_t *sys = vd->sys;
if (!sys->sys.pool)
if (!sys->sys.pool && vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
{
sys->sys.pool = vout_display_opengl_GetPool(sys->vgl, count);
vlc_gl_ReleaseCurrent (sys->gl);
}
return sys->sys.pool;
}
......@@ -307,14 +212,22 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
{
vout_display_sys_t *sys = vd->sys;
vout_display_opengl_Prepare(sys->vgl, picture, subpicture);
if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
{
vout_display_opengl_Prepare (sys->vgl, picture, subpicture);
vlc_gl_ReleaseCurrent (sys->gl);
}
}
static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
vout_display_opengl_Display(sys->vgl, &vd->source);
if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
{
vout_display_opengl_Display (sys->vgl, &vd->source);
vlc_gl_ReleaseCurrent (sys->gl);
}
picture_Release(picture);
if (subpicture)
......@@ -331,20 +244,10 @@ static void Manage (vout_display_t *vd)
const int width = sys->sys.rect_dest.right - sys->sys.rect_dest.left;
const int height = sys->sys.rect_dest.bottom - sys->sys.rect_dest.top;
vlc_gl_Resize (sys->gl, width, height);
if (vlc_gl_MakeCurrent (sys->gl) != VLC_SUCCESS)
return VLC_EGENERIC;
vout_display_opengl_SetWindowAspectRatio(sys->vgl, (float)width / height);
glViewport(0, 0, width, height);
vlc_gl_ReleaseCurrent (sys->gl);
}
static void Swap(vlc_gl_t *gl)
{
vout_display_t *vd = gl->sys;
SwapBuffers(vd->sys->hGLDC);
}
static void *OurGetProcAddress(vlc_gl_t *gl, const char *name)
{
VLC_UNUSED(gl);
return wglGetProcAddress(name);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment