X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fmsw%2Fglwin32.c;h=489581bfd29279bf876f99f0c59cdd6b4ca454cb;hb=1ce3c5d673ba7a71f3db5cf7f1d11ee906f92d39;hp=28be49eddc9d48790baccf9c6efc8995aa186dd9;hpb=32792812022dd2c4e40f85d1811276489351ff92;p=vlc diff --git a/modules/video_output/msw/glwin32.c b/modules/video_output/msw/glwin32.c index 28be49eddc..489581bfd2 100644 --- a/modules/video_output/msw/glwin32.c +++ b/modules/video_output/msw/glwin32.c @@ -1,24 +1,24 @@ /***************************************************************************** * glwin32.c: Windows OpenGL provider ***************************************************************************** - * Copyright (C) 2001-2009 the VideoLAN team + * Copyright (C) 2001-2009 VLC authors and VideoLAN * $Id$ * * Authors: Gildas Bazin * - * This program 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 + * This program is free software; you can redistribute it 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. * * This program 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. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" @@ -29,16 +29,11 @@ #include #include -#include -#include - -#undef GetSystemMetrics - -#ifndef MONITOR_DEFAULTTONEAREST -# define MONITOR_DEFAULTTONEAREST 2 -#endif +#define GLEW_STATIC #include "../opengl.h" +#include + #include "common.h" /***************************************************************************** @@ -47,11 +42,16 @@ 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")) + + add_integer("gpu-affinity", -1, HW_GPU_AFFINITY_TEXT, HW_GPU_AFFINITY_TEXT, true) + set_capability("vout display", 160) add_shortcut("glwin32", "opengl") set_callbacks(Open, Close) @@ -69,6 +69,85 @@ 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->hvideownd); + SetPixelFormat(winDC, ChoosePixelFormat(winDC, &pfd), &pfd); + HGLRC hGLRC = wglCreateContext(winDC); + wglMakeCurrent(winDC, hGLRC); + + /* Initialize the neccessary 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->hvideownd); + SetPixelFormat(winDC, ChoosePixelFormat(winDC, &pfd), &pfd); + HGLRC hGLRC = wglCreateContext(winDC); + wglMakeCurrent(winDC, hGLRC); + + /* Initialize the neccessary 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); +} + /** * It creates an OpenGL vout display. */ @@ -88,6 +167,10 @@ static int Open(vlc_object_t *object) EventThreadUpdateTitle(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->hvideownd); @@ -104,10 +187,23 @@ static int Open(vlc_object_t *object) SetPixelFormat(sys->hGLDC, ChoosePixelFormat(sys->hGLDC, &pfd), &pfd); - /* Create and enable the render context */ - sys->hGLRC = wglCreateContext(sys->hGLDC); + /* + * 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.lock = NULL; sys->gl.unlock = NULL; @@ -116,15 +212,16 @@ static int Open(vlc_object_t *object) sys->gl.sys = vd; video_format_t fmt = vd->fmt; - sys->vgl = vout_display_opengl_New(&fmt, &sys->gl); + const vlc_fourcc_t *subpicture_chromas; + sys->vgl = vout_display_opengl_New(&fmt, &subpicture_chromas, &sys->gl); if (!sys->vgl) goto error; vout_display_info_t info = vd->info; info.has_double_click = true; info.has_hide_mouse = false; - info.has_pictures_invalid = true; info.has_event_thread = true; + info.subpicture_chromas = subpicture_chromas; /* Setup vout_display now that everything is fine */ vd->fmt = fmt; @@ -160,6 +257,7 @@ static void Close(vlc_object_t *object) wglDeleteContext(sys->hGLRC); if (sys->hGLDC) ReleaseDC(sys->hvideownd, sys->hGLDC); + DestroyGPUAffinityDC(vd); CommonClean(vd); @@ -170,10 +268,9 @@ static void Close(vlc_object_t *object) static picture_pool_t *Pool(vout_display_t *vd, unsigned count) { vout_display_sys_t *sys = vd->sys; - VLC_UNUSED(count); if (!sys->pool) - sys->pool = vout_display_opengl_GetPool(sys->vgl); + sys->pool = vout_display_opengl_GetPool(sys->vgl, count); return sys->pool; } @@ -181,8 +278,7 @@ 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); - VLC_UNUSED(subpicture); + vout_display_opengl_Prepare(sys->vgl, picture, subpicture); } static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) @@ -192,7 +288,8 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic vout_display_opengl_Display(sys->vgl, &vd->source); picture_Release(picture); - VLC_UNUSED(subpicture); + if (subpicture) + subpicture_Delete(subpicture); CommonDisplay(vd); } @@ -232,6 +329,7 @@ static void Swap(vlc_gl_t *gl) static void *OurGetProcAddress(vlc_gl_t *gl, const char *name) { + VLC_UNUSED(gl); return wglGetProcAddress(name); }