[MPlayer-dev-eng] [PATCH] reworked win32 support for vo_gl2, please test

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Fri Dec 3 01:22:19 CET 2004


Hi,
I reworked the win32 part of vo_gl2 to make it share more code with the
X code and remove some #ifdefs.
In addition, switching to and from fullscreen is much faster.
But I'm quite sure that there a still a few bugs in there, so everyone
who can please test!

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: libvo/gl_common.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/gl_common.c,v
retrieving revision 1.4
diff -u -r1.4 gl_common.c
--- libvo/gl_common.c	2 Dec 2004 23:55:08 -0000	1.4
+++ libvo/gl_common.c	3 Dec 2004 00:13:21 -0000
@@ -178,7 +178,70 @@
   return 1;
 }
 
-#ifndef GL_WIN32
+#ifdef GL_WIN32
+int setGlWindow(int *vinfo, HGLRC *context, HWND win)
+{
+  int new_vinfo;
+  HDC windc = GetDC(win);
+  HGLRC new_context = 0;
+  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 = GetPixelFormat(windc);
+  if (*context && *vinfo && new_vinfo && *vinfo == new_vinfo) {
+      // we can keep the wglContext
+      new_context = *context;
+      keep_context = 1;
+  } else {
+    // create a context
+    new_context = wglCreateContext(windc);
+    if (!new_context) {
+      mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Could not create GL context!\n");
+      return SET_WINDOW_FAILED;
+    }
+  }
+
+  // set context
+  if (!wglMakeCurrent(windc, new_context)) {
+    mp_msg (MSGT_VO, MSGL_FATAL, "[gl] Could not set GL context!\n");
+    if (!keep_context) {
+      wglDeleteContext(new_context);
+    }
+    return SET_WINDOW_FAILED;
+  }
+
+  // set new values
+  vo_window = win;
+  vo_hdc = windc;
+  {
+    RECT rect;
+    GetClientRect(win, &rect);
+    vo_dwidth = rect.right;
+    vo_dheight = rect.bottom;
+  }
+  if (!keep_context) {
+    if (*context)
+      wglDeleteContext(*context);
+    *context = new_context;
+    *vinfo = new_vinfo;
+
+    // and inform that reinit is neccessary
+    return SET_WINDOW_REINIT;
+  }
+  return SET_WINDOW_OK;
+}
+
+void releaseGlContext(int *vinfo, HGLRC *context) {
+  *vinfo = 0;
+  if (*context) {
+    wglMakeCurrent(0, 0);
+    wglDeleteContext(*context);
+  }
+  *context = 0;
+}
+#else
 /**
  * Returns the XVisualInfo associated with Window win.
  * \param win Window whose XVisualInfo is returne.
Index: libvo/gl_common.h
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/gl_common.h,v
retrieving revision 1.4
diff -u -r1.4 gl_common.h
--- libvo/gl_common.h	1 Dec 2004 17:05:58 -0000	1.4
+++ libvo/gl_common.h	3 Dec 2004 00:13:21 -0000
@@ -7,7 +7,11 @@
 #include <GL/gl.h>
 #include "video_out.h"
 
-#ifndef GL_WIN32
+#ifdef GL_WIN32
+#include <windows.h>
+#include <GL/glext.h>
+#include "w32_common.h"
+#else
 #include <X11/Xlib.h>
 #include <GL/glx.h>
 #include "x11_common.h"
@@ -27,7 +31,10 @@
 //! new window is set, but the OpenGL context needs to be reinitialized.
 #define SET_WINDOW_REINIT 1
 
-#ifndef GL_WIN32
+#ifdef GL_WIN32
+int setGlWindow(int *vinfo, HGLRC *context, HWND win);
+void releaseGlContext(int *vinfo, HGLRC *context);
+#else
 int setGlWindow(XVisualInfo **vinfo, GLXContext *context, Window win);
 void releaseGlContext(XVisualInfo **vinfo, GLXContext *context);
 #endif
Index: libvo/vo_gl2.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_gl2.c,v
retrieving revision 1.60
diff -u -r1.60 vo_gl2.c
--- libvo/vo_gl2.c	3 Dec 2004 00:11:28 -0000	1.60
+++ libvo/vo_gl2.c	3 Dec 2004 00:13:24 -0000
@@ -70,7 +70,10 @@
 
 //static int texture_id=1;
 
-#ifndef GL_WIN32
+#ifdef GL_WIN32
+    static int gl_vinfo = 0;
+    static HGLRC gl_context = 0;
+#else
     static XVisualInfo *gl_vinfo = NULL;
     static GLXContext gl_context = 0;
 #endif
@@ -766,7 +769,6 @@
   if (vo_fs ^ (flags & VOFLAG_FULLSCREEN))
     vo_x11_fullscreen();
 
-  setGlWindow(&gl_vinfo, &gl_context, vo_window);
         return 0;
 }
 
@@ -775,7 +777,6 @@
   vo_dwidth = d_width;
   vo_dheight = d_height;
   guiGetEvent( guiSetShVideo,0 ); // the GUI will set up / resize the window
-  setGlWindow(&gl_vinfo, &gl_context, vo_window);
   return 0;
 }
 #endif
@@ -862,6 +863,8 @@
 #endif
 	    return -1;
 	
+  setGlWindow(&gl_vinfo, &gl_context, vo_window);
+
   glVersion = glGetString(GL_VERSION);
 
   mp_msg(MSGT_VO, MSGL_V, "[gl2] OpenGL Driver Information:\n");
@@ -1058,9 +1061,7 @@
 uninit(void)
 {
   if ( !vo_config_count ) return;
-#ifndef GL_WIN32
   releaseGlContext(&gl_vinfo, &gl_context);
-#endif
   if (texgrid) {
     free(texgrid);
     texgrid = NULL;
@@ -1102,10 +1103,12 @@
   case VOCTRL_FULLSCREEN:
 #ifdef GL_WIN32
     vo_w32_fullscreen();
-    initGl(vo_dwidth, vo_dheight);
 #else
     vo_x11_fullscreen();
 #endif 
+    if (setGlWindow(&gl_vinfo, &gl_context, vo_window) == SET_WINDOW_REINIT)
+      initGl(vo_dwidth, vo_dheight);
+    resize(&vo_dwidth, &vo_dheight);
     return VO_TRUE;
 #ifndef GL_WIN32
   case VOCTRL_SET_EQUALIZER:
Index: libvo/w32_common.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/w32_common.c,v
retrieving revision 1.7
diff -u -r1.7 w32_common.c
--- libvo/w32_common.c	28 Oct 2004 01:15:52 -0000	1.7
+++ libvo/w32_common.c	3 Dec 2004 00:13:25 -0000
@@ -19,8 +19,7 @@
 uint32_t o_dheight;
 
 static HINSTANCE hInstance;
-static HWND vo_hwnd = 0;
-static HGLRC wglContext = 0;
+HWND vo_window = 0;
 static int cursor = 1;
 
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
@@ -143,10 +142,12 @@
     vo_dwidth = vo_screenwidth;
     vo_dheight = vo_screenheight;
 
+    if (vo_vm)
     ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
 }
 
 static void resetMode(void) {
+    if (vo_vm)
     ChangeDisplaySettings(0, 0);
 
     DEVMODE dm;
@@ -169,19 +170,18 @@
 
 int createRenderingContext(void) {
     HWND layer = HWND_NOTOPMOST;
-    if (wglContext) return 1;
 
     if (vo_fs || vo_ontop) layer = HWND_TOPMOST;
     if (vo_fs) {
 	changeMode();
-	SetWindowPos(vo_hwnd, layer, 0, 0, vo_screenwidth, vo_screenheight, SWP_SHOWWINDOW);
+	SetWindowPos(vo_window, layer, 0, 0, vo_screenwidth, vo_screenheight, SWP_SHOWWINDOW);
 	if (cursor) {
 	    ShowCursor(0);
 	    cursor = 0;
 	}
     } else {
 	resetMode();
-	SetWindowPos(vo_hwnd, layer, (vo_screenwidth - vo_dwidth) / 2, (vo_screenheight - vo_dheight) / 2, vo_dwidth, vo_dheight, SWP_SHOWWINDOW);
+	SetWindowPos(vo_window, layer, (vo_screenwidth - vo_dwidth) / 2, (vo_screenheight - vo_dheight) / 2, vo_dwidth, vo_dheight, SWP_SHOWWINDOW);
 	if (!cursor) {
 	    ShowCursor(1);
 	    cursor = 1;
@@ -204,29 +204,13 @@
 
     SetPixelFormat(vo_hdc, pf, &pfd);
     
-    wglContext = wglCreateContext(vo_hdc);
-    if (!wglContext) {
-	mp_msg(MSGT_VO, MSGL_ERR, "vo: win32: unable to create wgl rendering context!\n");
-	return 0;
-    }
-
-    if (!wglMakeCurrent(vo_hdc, wglContext)) {
-	mp_msg(MSGT_VO, MSGL_ERR, "vo: win32: unable to make wgl rendering context current!\n");
-	return 0;
-    }	
-
     mp_msg(MSGT_VO, MSGL_V, "vo: win32: running at %dx%d with depth %d\n", vo_screenwidth, vo_screenheight, vo_depthonscreen);
 
     return 1;
 }
 
 void destroyRenderingContext(void) {
-    if (wglContext) {
-	wglMakeCurrent(0, 0);
-	wglDeleteContext(wglContext);
-	wglContext = 0;
 	resetMode();
-    }
 }
 
 int vo_init(void) {
@@ -234,7 +218,7 @@
     char 	exedir[MAX_PATH];
     DEVMODE	dm;
 
-    if (vo_hwnd)
+    if (vo_window)
 	return 1;
 
     hInstance = GetModuleHandle(0);
@@ -251,13 +235,13 @@
 	return 0;
     }
 
-    vo_hwnd = CreateWindowEx(0, classname, classname, WS_POPUP, CW_USEDEFAULT, 0, 100, 100, 0, 0, hInstance, 0);
-    if (!vo_hwnd) {
+    vo_window = CreateWindowEx(0, classname, classname, WS_POPUP, CW_USEDEFAULT, 0, 100, 100, 0, 0, hInstance, 0);
+    if (!vo_window) {
 	mp_msg(MSGT_VO, MSGL_ERR, "vo: win32: unable to create window!\n");
 	return 0;
     }
 
-    vo_hdc = GetDC(vo_hwnd);
+    vo_hdc = GetDC(vo_window);
 
     dm.dmSize = sizeof dm;
     dm.dmDriverExtra = 0;
@@ -286,7 +270,7 @@
     if (!vo_fs) {
 	HWND layer = HWND_NOTOPMOST;
 	if (vo_ontop) layer = HWND_TOPMOST;
-	SetWindowPos(vo_hwnd, layer, (vo_screenwidth - vo_dwidth) / 2, (vo_screenheight - vo_dheight) / 2, vo_dwidth, vo_dheight, SWP_SHOWWINDOW);
+	SetWindowPos(vo_window, layer, (vo_screenwidth - vo_dwidth) / 2, (vo_screenheight - vo_dheight) / 2, vo_dwidth, vo_dheight, SWP_SHOWWINDOW);
     }
 }
 
@@ -296,7 +280,7 @@
     ShowCursor(1);
     vo_depthonscreen = 0;
     destroyRenderingContext();
-    DestroyWindow(vo_hwnd);
-    vo_hwnd = 0;
+    DestroyWindow(vo_window);
+    vo_window = 0;
     UnregisterClass(classname, 0);
 }
Index: libvo/w32_common.h
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/w32_common.h,v
retrieving revision 1.2
diff -u -r1.2 w32_common.h
--- libvo/w32_common.h	30 Nov 2003 16:36:10 -0000	1.2
+++ libvo/w32_common.h	3 Dec 2004 00:13:25 -0000
@@ -3,6 +3,7 @@
 extern int vo_screenheight;
 extern uint32_t o_dwidth;
 extern uint32_t o_dheight;
+extern HWND vo_window;
 extern HDC vo_hdc;
 extern int vo_fs;
 extern int vo_vm;


More information about the MPlayer-dev-eng mailing list