{
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object);
- if (display_win32->hwnd != NULL)
+ if (display_win32->dummy_context_wgl.hglrc != NULL)
{
- if (display_win32->dummy_context_wgl.hglrc != NULL)
- {
- wglMakeCurrent (NULL, NULL);
- wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
- display_win32->dummy_context_wgl.hglrc = NULL;
- }
+ wglMakeCurrent (NULL, NULL);
+ wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
+ display_win32->dummy_context_wgl.hglrc = NULL;
+ }
+ if (display_win32->hwnd != NULL)
+ {
DestroyWindow (display_win32->hwnd);
display_win32->hwnd = NULL;
}
{
if (GDK_WIN32_SURFACE (surface)->hdc == NULL)
GDK_WIN32_SURFACE (surface)->hdc = GetDC (GDK_SURFACE_HWND (surface));
-
hdc = GDK_WIN32_SURFACE (surface)->hdc;
}
else
HDC init_gl_hdc = NULL;
GdkGLContext *context;
- if (display_win32->dummy_context_wgl.hdc == NULL)
- display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
-
- init_gl_hdc = display_win32->dummy_context_wgl.hdc;
-
/*
* No env vars set, do the regular GL initialization, first WGL and then EGL,
* as WGL is the more tried-and-tested configuration.
*/
if (gdk_display_get_debug_flags (display) & (GDK_DEBUG_GL_EGL|GDK_DEBUG_GL_GLES))
{
+ init_gl_hdc = GetDC (display_win32->hwnd);
+
if (gdk_display_init_egl (display,
EGL_PLATFORM_ANGLE_ANGLE,
init_gl_hdc,
#endif
context = gdk_win32_display_init_wgl (display, error);
+
if (context)
return context;
#ifdef HAVE_EGL
g_clear_error (error);
+ init_gl_hdc = GetDC (display_win32->hwnd);
if (gdk_display_init_egl (display,
EGL_PLATFORM_ANGLE_ANGLE,
init_gl_hdc,
pfd->nSize = sizeof (PIXELFORMATDESCRIPTOR);
- if (display_win32 != NULL && display_win32->hasWglARBPixelFormat)
+ if (display_win32 != NULL &&
+ display_win32->hasWglARBPixelFormat)
{
UINT num_formats;
int colorbits = GetDeviceCaps (hdc, BITSPIXEL);
return best_idx;
}
+/*
+ * Use a dummy HWND to init GL, sadly we can't just use the
+ * HWND that we use for notifications as we may only call
+ * SetPixelFormat() on an HDC once, and that notification HWND
+ * uses the CS_OWNDC style meaning that even if we were to call
+ * DeleteDC() on it, we would get the exact same HDC when we call
+ * GetDC() on it later, meaning SetPixelFormat() cannot be used
+ * again on the HDC that we acquire from the notification HWND.
+ */
+static HWND
+create_dummy_gl_window (void)
+{
+ WNDCLASS wclass = { 0, };
+ ATOM klass;
+ HWND hwnd;
+
+ wclass.lpszClassName = "GdkGLDummyWindow";
+ wclass.lpfnWndProc = DefWindowProc;
+ wclass.hInstance = _gdk_app_hmodule;
+ wclass.style = CS_OWNDC;
+
+ klass = RegisterClass (&wclass);
+ if (klass)
+ {
+ hwnd = CreateWindow (MAKEINTRESOURCE (klass),
+ NULL, WS_POPUP,
+ 0, 0, 0, 0, NULL, NULL,
+ _gdk_app_hmodule, NULL);
+ if (!hwnd)
+ {
+ UnregisterClass (MAKEINTRESOURCE (klass), _gdk_app_hmodule);
+ }
+ }
+
+ return hwnd;
+}
+
GdkGLContext *
gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error)
* dummy GL Context, it is used to query functions
* and used for other stuff as well
*/
+
+ if (display_win32->dummy_context_wgl.hdc == NULL)
+ {
+ display_win32->dummy_context_wgl.hwnd = create_dummy_gl_window ();
+
+ if (display_win32->dummy_context_wgl.hwnd != NULL)
+ display_win32->dummy_context_wgl.hdc = GetDC (display_win32->dummy_context_wgl.hwnd);
+ }
+
best_idx = gdk_init_dummy_wgl_context (display_win32);
hdc = display_win32->dummy_context_wgl.hdc;
}
static gboolean
-set_wgl_pixformat_for_hdc (HDC hdc,
+set_wgl_pixformat_for_hdc (GdkWin32Display *display_win32,
+ HDC *hdc,
int *best_idx,
- GdkWin32Display *display_win32)
+ gboolean *recreate_dummy_context)
{
- gboolean already_checked = TRUE;
- *best_idx = GetPixelFormat (hdc);
+ gboolean skip_acquire = FALSE;
+ gboolean set_pixel_format_result = FALSE;
+ PIXELFORMATDESCRIPTOR pfd;
/* one is only allowed to call SetPixelFormat(), and so ChoosePixelFormat()
* one single time per window HDC
*/
- if (*best_idx == 0)
- {
- PIXELFORMATDESCRIPTOR pfd;
- gboolean set_pixel_format_result = FALSE;
-
- GDK_NOTE (OPENGL, g_print ("requesting pixel format...\n"));
- already_checked = FALSE;
- *best_idx = get_wgl_pfd (hdc, &pfd, display_win32);
+ GDK_NOTE (OPENGL, g_print ("requesting pixel format...\n"));
+ *best_idx = get_wgl_pfd (*hdc, &pfd, display_win32);
- if (*best_idx != 0)
- set_pixel_format_result = SetPixelFormat (hdc, *best_idx, &pfd);
+ if (display_win32->dummy_context_wgl.hwnd != NULL)
+ {
+ /*
+ * Ditch the initial dummy HDC, HGLRC and HWND used to initialize WGL,
+ * we want to ensure that the HDC of the notification HWND that we will
+ * also use for our new dummy HDC will have the correct pixel format set
+ */
+ wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
+ display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
+ *hdc = display_win32->dummy_context_wgl.hdc;
+ *recreate_dummy_context = TRUE;
+
+ DestroyWindow (display_win32->dummy_context_wgl.hwnd);
+ display_win32->dummy_context_wgl.hwnd = NULL;
+ }
- /* ChoosePixelFormat() or SetPixelFormat() failed, bail out */
- if (*best_idx == 0 || !set_pixel_format_result)
- return FALSE;
+ if (GetPixelFormat (*hdc) != 0)
+ {
+ skip_acquire = TRUE;
+ set_pixel_format_result = TRUE;
}
+ else if (*best_idx != 0)
+ set_pixel_format_result = SetPixelFormat (*hdc, *best_idx, &pfd);
- GDK_NOTE (OPENGL, g_print ("%s""requested and set pixel format: %d\n", already_checked ? "already " : "", *best_idx));
+ /* ChoosePixelFormat() or SetPixelFormat() failed, bail out */
+ if (*best_idx == 0 || !set_pixel_format_result)
+ return FALSE;
+
+ GDK_NOTE (OPENGL, g_print ("%s""requested and set pixel format: %d\n", skip_acquire ? "already " : "", *best_idx));
return TRUE;
}
/* request flags and specific versions for core (3.2+) WGL context */
int flags = 0;
HGLRC hglrc;
- int pixel_format;
+ int pixel_format = 0;
HDC hdc;
+ gboolean recreate_dummy_context = FALSE;
GdkSurface *surface = gdk_gl_context_get_surface (context);
GdkDisplay *display = gdk_gl_context_get_display (context);
else
hdc = display_win32->dummy_context_wgl.hdc;
- if (!set_wgl_pixformat_for_hdc (hdc,
+ if (!set_wgl_pixformat_for_hdc (display_win32,
+ &hdc,
&pixel_format,
- display_win32))
+ &recreate_dummy_context))
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
flags,
legacy_bit,
error);
+
+ if (recreate_dummy_context)
+ {
+ display_win32->dummy_context_wgl.hglrc =
+ create_wgl_context (context,
+ display_win32->dummy_context_wgl.hdc,
+ display_win32->hasWglARBCreateContext,
+ NULL,
+ flags,
+ legacy_bit,
+ error);
+
+ if (display_win32->dummy_context_wgl.hglrc == NULL)
+ {
+ if (hglrc != NULL)
+ {
+ wglDeleteContext (hglrc);
+ hglrc = NULL;
+ }
+ }
+ }
+
if (hglrc == NULL)
return 0;