From: Akihiro Sagawa Subject: [PATCH] wined3d: Use GetDeviceCaps() instead of wined3d_swapchain_get_display_mode(). Message-Id: <20120622231621.B01F.375B48EC@gmail.com> Date: Fri, 22 Jun 2012 23:17:17 +0900 wined3d_swapchain_get_display_mode() sometimes takes over 500 ms due to EDID polling. This prevents an application from getting swapchain status frequently. On the other hand, GetDeviceCaps() just returns current settings without a device query. So it is suitable for retrieving current display height and its refresh rate. See http://bugs.winehq.org/show_bug.cgi?id=30538 for details. --- dlls/wined3d/swapchain.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 6600806..79ec3aa 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -214,9 +214,10 @@ HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain struct wined3d_raster_status *raster_status) { static BOOL warned; + HDC dc; + int refresh_rate, lines; LARGE_INTEGER counter, freq_per_sec; LONGLONG freq_per_frame, freq_per_line; - struct wined3d_display_mode mode; /* No OpenGL equivalent */ if (!warned) @@ -235,16 +236,22 @@ HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec)) return WINED3DERR_INVALIDCALL; - if (FAILED(wined3d_swapchain_get_display_mode(swapchain, &mode))) - return WINED3DERR_INVALIDCALL; - if (mode.refresh_rate == DEFAULT_REFRESH_RATE) - mode.refresh_rate = 60; + /* wined3d_swapchain_get_display_mode() is slow (due to polling EDID). + * So we use GetDeviceCaps instead for now. See bug 30538 for details. */ + dc = GetDC(swapchain->device_window); + refresh_rate = GetDeviceCaps(dc, VREFRESH); + lines = GetDeviceCaps(dc, VERTRES); + TRACE("%d lines at %d Hz.\n", lines, refresh_rate); + ReleaseDC(swapchain->device_window, dc); + + if (refresh_rate == 0 || refresh_rate == 1) + refresh_rate = 60; - freq_per_frame = freq_per_sec.QuadPart / mode.refresh_rate; + freq_per_frame = freq_per_sec.QuadPart / refresh_rate; /* Assume 20 scan lines in the vertical blank */ - freq_per_line = freq_per_frame / (mode.height + 20); + freq_per_line = freq_per_frame / (lines + 20); raster_status->scan_line = (counter.QuadPart % freq_per_frame) / freq_per_line; - if (raster_status->scan_line < mode.height) + if (raster_status->scan_line < lines) raster_status->in_vblank = FALSE; else {