GDK-Win32: Clean up HiDPI support and WGL a bit

Make _gdk_win32_display_get_monitor_scale_factor() less complex, by:

*  Drop the preceding underscore.

*  Dropping an unused parameter.

*  Using a GdkSurface instead of a HWND, as the HWND that we pass into
   this function might have been taken from a GdkSurface, which are now
   always created with CS_OWNDC.  This means if a GdkSurface was passed
   in, we ensure that we only acquire the DC from the HWND once, and do
   not attempt to call ReleaseDC() on it.

*  Store the HDC that we acquire from the GdkSurface's HWND into the
   surface, and use that as the HDC we need for our GdkGLContext.

*  Drop the gl_hwnd from GdkWin32Display, as that is really should be
   stored in the GdkSurface.

*  For functions that were updated, name GdkWin32Display variables as
   display_win32 and GdkSurface variables as surface, to unify things.

*  Stop calling ReleaseDC() on the HDC that we use for OpenGL, since
   they were acquired from HWND's created with CS_OWNDC.
This commit is contained in:
Chun-wei Fan 2021-07-19 18:20:09 +08:00
parent 49a76257cd
commit ac64d2d910
8 changed files with 83 additions and 109 deletions

View File

@ -982,31 +982,32 @@ _gdk_win32_check_on_arm64 (GdkWin32Display *display)
} }
static void static void
gdk_win32_display_init (GdkWin32Display *display) gdk_win32_display_init (GdkWin32Display *display_win32)
{ {
const char *scale_str = g_getenv ("GDK_SCALE"); const char *scale_str = g_getenv ("GDK_SCALE");
display->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR)); display_win32->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR));
_gdk_win32_enable_hidpi (display); _gdk_win32_enable_hidpi (display_win32);
_gdk_win32_check_on_arm64 (display); _gdk_win32_check_on_arm64 (display_win32);
/* if we have DPI awareness, set up fixed scale if set */ /* if we have DPI awareness, set up fixed scale if set */
if (display->dpi_aware_type != PROCESS_DPI_UNAWARE && if (display_win32->dpi_aware_type != PROCESS_DPI_UNAWARE &&
scale_str != NULL) scale_str != NULL)
{ {
display->surface_scale = atol (scale_str); display_win32->surface_scale = atol (scale_str);
if (display->surface_scale <= 0) if (display_win32->surface_scale <= 0)
display->surface_scale = 1; display_win32->surface_scale = 1;
display->has_fixed_scale = TRUE; display_win32->has_fixed_scale = TRUE;
} }
else else
display->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display, NULL, NULL, NULL); display_win32->surface_scale =
gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
_gdk_win32_display_init_cursors (display); _gdk_win32_display_init_cursors (display_win32);
gdk_win32_display_check_composited (display); gdk_win32_display_check_composited (display_win32);
} }
void void
@ -1057,64 +1058,64 @@ gdk_win32_display_get_monitors (GdkDisplay *display)
} }
guint guint
_gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display, gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
HMONITOR hmonitor, GdkSurface *surface,
HWND hwnd, HMONITOR hmonitor)
int *dpi)
{ {
gboolean is_scale_acquired = FALSE; gboolean is_scale_acquired = FALSE;
gboolean use_dpi_for_monitor = FALSE; gboolean use_dpi_for_monitor = FALSE;
guint dpix, dpiy; guint dpix, dpiy;
if (win32_display->have_at_least_win81) if (display_win32->have_at_least_win81)
{ {
if (hmonitor != NULL) if (surface != NULL && hmonitor == NULL)
hmonitor = MonitorFromWindow (GDK_SURFACE_HWND (surface),
MONITOR_DEFAULTTONEAREST);
if (hmonitor != NULL &&
display_win32->shcore_funcs.hshcore != NULL &&
display_win32->shcore_funcs.getDpiForMonitorFunc != NULL)
use_dpi_for_monitor = TRUE; use_dpi_for_monitor = TRUE;
else
{
if (hwnd != NULL)
{
hmonitor = MonitorFromWindow (hwnd, MONITOR_DEFAULTTONEAREST);
use_dpi_for_monitor = TRUE;
}
}
} }
if (use_dpi_for_monitor) if (use_dpi_for_monitor)
{ {
/* Use GetDpiForMonitor() for Windows 8.1+, when we have a HMONITOR */ /* Use GetDpiForMonitor() for Windows 8.1+, when we have a HMONITOR */
if (win32_display->shcore_funcs.hshcore != NULL && if (display_win32->shcore_funcs.getDpiForMonitorFunc (hmonitor,
win32_display->shcore_funcs.getDpiForMonitorFunc != NULL) MDT_EFFECTIVE_DPI,
{ &dpix,
if (win32_display->shcore_funcs.getDpiForMonitorFunc (hmonitor, &dpiy) == S_OK)
MDT_EFFECTIVE_DPI, is_scale_acquired = TRUE;
&dpix,
&dpiy) == S_OK)
{
is_scale_acquired = TRUE;
}
}
} }
else else
{ {
/* Go back to GetDeviceCaps() for Windows 8 and earlier, or when we don't /* Go back to GetDeviceCaps() for Windows 8 and earlier, or when we don't
* have a HMONITOR nor a HWND * have a HMONITOR nor a HWND
*/ */
HDC hdc = GetDC (hwnd); HDC hdc;
if (surface != 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 = GetDC (NULL);
/* in case we can't get the DC for the window, return 1 for the scale */ /* in case we can't get the DC for the window, return 1 for the scale */
if (hdc == NULL) if (hdc == NULL)
{ return 1;
if (dpi != NULL)
*dpi = USER_DEFAULT_SCREEN_DPI;
return 1;
}
dpix = GetDeviceCaps (hdc, LOGPIXELSX); dpix = GetDeviceCaps (hdc, LOGPIXELSX);
dpiy = GetDeviceCaps (hdc, LOGPIXELSY); dpiy = GetDeviceCaps (hdc, LOGPIXELSY);
ReleaseDC (hwnd, hdc);
/*
* If surface is not NULL, the HDC should not be released, since surfaces have
* Win32 windows created with CS_OWNDC
*/
if (surface == NULL)
ReleaseDC (NULL, hdc);
is_scale_acquired = TRUE; is_scale_acquired = TRUE;
} }
@ -1122,21 +1123,13 @@ _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
if (is_scale_acquired) if (is_scale_acquired)
/* USER_DEFAULT_SCREEN_DPI = 96, in winuser.h */ /* USER_DEFAULT_SCREEN_DPI = 96, in winuser.h */
{ {
if (dpi != NULL) if (display_win32->has_fixed_scale)
*dpi = dpix; return display_win32->surface_scale;
if (win32_display->has_fixed_scale)
return win32_display->surface_scale;
else else
return dpix / USER_DEFAULT_SCREEN_DPI > 1 ? dpix / USER_DEFAULT_SCREEN_DPI : 1; return dpix / USER_DEFAULT_SCREEN_DPI > 1 ? dpix / USER_DEFAULT_SCREEN_DPI : 1;
} }
else else
{ return 1;
if (dpi != NULL)
*dpi = USER_DEFAULT_SCREEN_DPI;
return 1;
}
} }
static gboolean static gboolean

View File

@ -121,7 +121,6 @@ struct _GdkWin32Display
/* WGL/OpenGL Items */ /* WGL/OpenGL Items */
guint have_wgl : 1; guint have_wgl : 1;
guint gl_version; guint gl_version;
HWND gl_hwnd;
#ifdef GDK_WIN32_ENABLE_EGL #ifdef GDK_WIN32_ENABLE_EGL
/* EGL (Angle) Items */ /* EGL (Angle) Items */
@ -185,10 +184,9 @@ GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
void gdk_win32_display_check_composited (GdkWin32Display *display); void gdk_win32_display_check_composited (GdkWin32Display *display);
guint _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display, guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
HMONITOR hmonitor, GdkSurface *surface,
HWND hwnd, HMONITOR hmonitor);
int *dpi);
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter; typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;

View File

@ -793,7 +793,7 @@ gdk_drag_new (GdkDisplay *display,
GdkDragProtocol protocol) GdkDragProtocol protocol)
{ {
GdkWin32Drag *drag_win32; GdkWin32Drag *drag_win32;
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display); GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
GdkDrag *drag; GdkDrag *drag;
drag_win32 = g_object_new (GDK_TYPE_WIN32_DRAG, drag_win32 = g_object_new (GDK_TYPE_WIN32_DRAG,
@ -805,10 +805,10 @@ gdk_drag_new (GdkDisplay *display,
drag = GDK_DRAG (drag_win32); drag = GDK_DRAG (drag_win32);
if (win32_display->has_fixed_scale) if (display_win32->has_fixed_scale)
drag_win32->scale = win32_display->surface_scale; drag_win32->scale = display_win32->surface_scale;
else else
drag_win32->scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, NULL, NULL, NULL); drag_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
drag_win32->protocol = protocol; drag_win32->protocol = protocol;

View File

@ -177,7 +177,7 @@ gdk_drop_new (GdkDisplay *display,
GdkDragProtocol protocol) GdkDragProtocol protocol)
{ {
GdkWin32Drop *drop_win32; GdkWin32Drop *drop_win32;
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display); GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
drop_win32 = g_object_new (GDK_TYPE_WIN32_DROP, drop_win32 = g_object_new (GDK_TYPE_WIN32_DROP,
"device", device, "device", device,
@ -186,10 +186,10 @@ gdk_drop_new (GdkDisplay *display,
"surface", surface, "surface", surface,
NULL); NULL);
if (win32_display->has_fixed_scale) if (display_win32->has_fixed_scale)
drop_win32->scale = win32_display->surface_scale; drop_win32->scale = display_win32->surface_scale;
else else
drop_win32->scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, NULL, NULL, NULL); drop_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
drop_win32->protocol = protocol; drop_win32->protocol = protocol;

View File

@ -66,8 +66,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
wglDeleteContext (context_win32->hglrc); wglDeleteContext (context_win32->hglrc);
context_win32->hglrc = NULL; context_win32->hglrc = NULL;
ReleaseDC (display_win32->gl_hwnd, context_win32->gl_hdc);
} }
#ifdef GDK_WIN32_ENABLE_EGL #ifdef GDK_WIN32_ENABLE_EGL
@ -82,8 +80,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
eglDestroyContext (display_win32->egl_disp, eglDestroyContext (display_win32->egl_disp,
context_win32->egl_context); context_win32->egl_context);
context_win32->egl_context = EGL_NO_CONTEXT; context_win32->egl_context = EGL_NO_CONTEXT;
ReleaseDC (display_win32->gl_hwnd, context_win32->gl_hdc);
} }
#endif #endif
} }
@ -1076,29 +1072,25 @@ gdk_win32_gl_context_init (GdkWin32GLContext *self)
GdkGLContext * GdkGLContext *
_gdk_win32_surface_create_gl_context (GdkSurface *surface, _gdk_win32_surface_create_gl_context (GdkSurface *surface,
gboolean attached, gboolean attached,
GdkGLContext *share, GdkGLContext *share,
GError **error) GError **error)
{ {
GdkDisplay *display = gdk_surface_get_display (surface); GdkDisplay *display = gdk_surface_get_display (surface);
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display); GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
GdkWin32GLContext *context = NULL; GdkWin32GLContext *context = NULL;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
/* Acquire and store up the Windows-specific HWND and HDC */
/* HWND hwnd;*/
HDC hdc;
#ifdef GDK_WIN32_ENABLE_EGL #ifdef GDK_WIN32_ENABLE_EGL
EGLContext egl_context; EGLContext egl_context;
EGLConfig config; EGLConfig config;
#endif #endif
display_win32->gl_hwnd = GDK_SURFACE_HWND (surface); impl->hdc = GetDC (GDK_SURFACE_HWND (surface));
hdc = GetDC (display_win32->gl_hwnd);
#ifdef GDK_WIN32_ENABLE_EGL #ifdef GDK_WIN32_ENABLE_EGL
/* display_win32->hdc_egl_temp should *not* be destroyed here! It is destroyed at dispose()! */ /* display_win32->hdc_egl_temp should *not* be destroyed here! It is destroyed at dispose()! */
display_win32->hdc_egl_temp = hdc; display_win32->hdc_egl_temp = impl->hdc;
#endif #endif
if (!_gdk_win32_display_init_gl (display)) if (!_gdk_win32_display_init_gl (display))
@ -1109,16 +1101,6 @@ _gdk_win32_surface_create_gl_context (GdkSurface *surface,
return NULL; return NULL;
} }
#if 0
if (display_win32->have_wgl)
{
hwnd = GDK_SURFACE_HWND (surface);
hdc = GetDC (hwnd);
display_win32->gl_hwnd = hwnd;
}
#endif
#ifdef GDK_WIN32_ENABLE_EGL #ifdef GDK_WIN32_ENABLE_EGL
if (display_win32->have_egl && !find_eglconfig_for_window (display_win32, &config, if (display_win32->have_egl && !find_eglconfig_for_window (display_win32, &config,
&display_win32->egl_min_swap_interval, error)) &display_win32->egl_min_swap_interval, error))
@ -1130,7 +1112,7 @@ _gdk_win32_surface_create_gl_context (GdkSurface *surface,
"shared-context", share, "shared-context", share,
NULL); NULL);
context->gl_hdc = hdc; context->gl_hdc = impl->hdc;
context->is_attached = attached; context->is_attached = attached;
#ifdef GDK_WIN32_ENABLE_EGL #ifdef GDK_WIN32_ENABLE_EGL

View File

@ -681,7 +681,7 @@ enum_monitor (HMONITOR hmonitor,
else else
{ {
/* First acquire the scale using the current screen */ /* First acquire the scale using the current screen */
scale = _gdk_win32_display_get_monitor_scale_factor (data->display, NULL, NULL, NULL); scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, NULL);
/* acquire the scale using the monitor which the window is nearest on Windows 8.1+ */ /* acquire the scale using the monitor which the window is nearest on Windows 8.1+ */
if (data->display->have_at_least_win81) if (data->display->have_at_least_win81)
@ -695,7 +695,7 @@ enum_monitor (HMONITOR hmonitor,
pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2; pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2;
pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2; pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2;
hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST); hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
scale = _gdk_win32_display_get_monitor_scale_factor (data->display, hmonitor, NULL, NULL); scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, hmonitor);
} }
} }

View File

@ -78,8 +78,7 @@ init_root_window (GdkWin32Screen *screen_win32)
win32_display = GDK_WIN32_DISPLAY (_gdk_display); win32_display = GDK_WIN32_DISPLAY (_gdk_display);
if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE) if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
screen_win32->surface_scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, screen_win32->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
NULL,
NULL, NULL,
NULL); NULL);
else else

View File

@ -522,7 +522,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
surface->width = width; surface->width = width;
surface->height = height; surface->height = height;
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL, NULL); impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
dwExStyle = 0; dwExStyle = 0;
owner = NULL; owner = NULL;
@ -4427,19 +4427,19 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
int int
_gdk_win32_surface_get_scale_factor (GdkSurface *window) _gdk_win32_surface_get_scale_factor (GdkSurface *surface)
{ {
GdkDisplay *display; GdkDisplay *display;
GdkWin32Surface *impl; GdkWin32Surface *impl;
GdkWin32Display *win32_display; GdkWin32Display *win32_display;
if (GDK_SURFACE_DESTROYED (window)) if (GDK_SURFACE_DESTROYED (surface))
return 1; return 1;
g_return_val_if_fail (window != NULL, 1); g_return_val_if_fail (surface != NULL, 1);
display = gdk_surface_get_display (window); display = gdk_surface_get_display (surface);
impl = GDK_WIN32_SURFACE (window); impl = GDK_WIN32_SURFACE (surface);
win32_display = GDK_WIN32_DISPLAY (display); win32_display = GDK_WIN32_DISPLAY (display);
@ -4448,9 +4448,8 @@ _gdk_win32_surface_get_scale_factor (GdkSurface *window)
if (win32_display->has_fixed_scale) if (win32_display->has_fixed_scale)
impl->surface_scale = win32_display->surface_scale; impl->surface_scale = win32_display->surface_scale;
else else
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
NULL, surface,
GDK_SURFACE_HWND (window),
NULL); NULL);
return impl->surface_scale; return impl->surface_scale;
@ -5067,7 +5066,10 @@ _gdk_win32_surface_get_egl_surface (GdkSurface *surface,
else else
{ {
if (impl->egl_surface == EGL_NO_SURFACE) if (impl->egl_surface == EGL_NO_SURFACE)
impl->egl_surface = eglCreateWindowSurface (display->egl_disp, config, display->gl_hwnd, NULL); impl->egl_surface = eglCreateWindowSurface (display->egl_disp,
config,
GDK_SURFACE_HWND (surface),
NULL);
return impl->egl_surface; return impl->egl_surface;
} }