Henri Verbeet : ddraw: Implement ddraw7_GetScanLine() on top of wined3d_get_adapter_raster_status().
Alexandre Julliard
julliard at winehq.org
Thu Jul 19 13:23:42 CDT 2012
Module: wine
Branch: master
Commit: 2bfc5214be461882ee314cf5301e7a98e84ac94c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2bfc5214be461882ee314cf5301e7a98e84ac94c
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Wed Jul 18 21:32:30 2012 +0200
ddraw: Implement ddraw7_GetScanLine() on top of wined3d_get_adapter_raster_status().
---
dlls/ddraw/ddraw.c | 42 ++++-----------------------------------
dlls/wined3d/directx.c | 47 +++++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/swapchain.c | 43 ++--------------------------------------
dlls/wined3d/wined3d.spec | 1 +
include/wine/wined3d.h | 2 +
5 files changed, 58 insertions(+), 77 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 1963de2..b96fd48 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1931,60 +1931,28 @@ static HRESULT WINAPI ddraw1_WaitForVerticalBlank(IDirectDraw *iface, DWORD flag
return ddraw7_WaitForVerticalBlank(&ddraw->IDirectDraw7_iface, flags, event);
}
-/*****************************************************************************
- * IDirectDraw7::GetScanLine
- *
- * Returns the scan line that is being drawn on the monitor
- *
- * Parameters:
- * Scanline: Address to write the scan line value to
- *
- * Returns:
- * Always returns DD_OK
- *
- *****************************************************************************/
static HRESULT WINAPI ddraw7_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
{
struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
- struct wined3d_display_mode mode;
- static BOOL hide = FALSE;
- DWORD time, frame_progress, lines;
+ struct wined3d_raster_status raster_status;
HRESULT hr;
TRACE("iface %p, line %p.\n", iface, Scanline);
- /* This function is called often, so print the fixme only once */
- if(!hide)
- {
- FIXME("iface %p, line %p partial stub!\n", iface, Scanline);
- hide = TRUE;
- }
-
wined3d_mutex_lock();
- hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL);
+ hr = wined3d_get_adapter_raster_status(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &raster_status);
wined3d_mutex_unlock();
if (FAILED(hr))
{
- ERR("Failed to get display mode, hr %#x.\n", hr);
+ WARN("Failed to get raster status, hr %#x.\n", hr);
return hr;
}
- /* Fake the line sweeping of the monitor */
- /* FIXME: We should synchronize with a source to keep the refresh rate */
+ *Scanline = raster_status.scan_line;
- /* Simulate a 60Hz display */
- time = GetTickCount();
- frame_progress = time & 15; /* time % (1000 / 60) */
- if (!frame_progress)
- {
- *Scanline = 0;
+ if (raster_status.in_vblank)
return DDERR_VERTICALBLANKINPROGRESS;
- }
- /* Convert frame_progress to estimated scan line. Return any line from
- * block determined by time. Some lines may be never returned */
- lines = mode.height / 15;
- *Scanline = (frame_progress - 1) * lines + time % lines;
return DD_OK;
}
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index f80e80c..9e9af8a 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -3225,6 +3225,53 @@ HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d,
return WINED3D_OK;
}
+HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
+ struct wined3d_raster_status *raster_status)
+{
+ LONGLONG freq_per_frame, freq_per_line;
+ LARGE_INTEGER counter, freq_per_sec;
+ struct wined3d_display_mode mode;
+ static UINT once;
+
+ if (!once++)
+ FIXME("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
+ wined3d, adapter_idx, raster_status);
+ else
+ WARN("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
+ wined3d, adapter_idx, raster_status);
+
+ /* Obtaining the raster status is a widely implemented but optional
+ * feature. When this method returns OK StarCraft 2 expects the
+ * raster_status->InVBlank value to actually change over time.
+ * And Endless Alice Crysis doesn't care even if this method fails.
+ * Thus this method returns OK and fakes raster_status by
+ * QueryPerformanceCounter. */
+
+ if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec))
+ return WINED3DERR_INVALIDCALL;
+ if (FAILED(wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, NULL)))
+ return WINED3DERR_INVALIDCALL;
+ if (mode.refresh_rate == DEFAULT_REFRESH_RATE)
+ mode.refresh_rate = 60;
+
+ freq_per_frame = freq_per_sec.QuadPart / mode.refresh_rate;
+ /* Assume 20 scan lines in the vertical blank. */
+ freq_per_line = freq_per_frame / (mode.height + 20);
+ raster_status->scan_line = (counter.QuadPart % freq_per_frame) / freq_per_line;
+ if (raster_status->scan_line < mode.height)
+ raster_status->in_vblank = FALSE;
+ else
+ {
+ raster_status->scan_line = 0;
+ raster_status->in_vblank = TRUE;
+ }
+
+ TRACE("Returning fake value, in_vblank %u, scan_line %u.\n",
+ raster_status->in_vblank, raster_status->scan_line);
+
+ return WINED3D_OK;
+}
+
static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info,
const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
{
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index dd00e55..8c37659 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -220,47 +220,10 @@ HRESULT CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *
HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain,
struct wined3d_raster_status *raster_status)
{
- static BOOL warned;
- LARGE_INTEGER counter, freq_per_sec;
- LONGLONG freq_per_frame, freq_per_line;
- struct wined3d_display_mode mode;
-
- /* No OpenGL equivalent */
- if (!warned)
- {
- FIXME("swapchain %p, raster_status %p semi-stub!\n", swapchain, raster_status);
- warned = TRUE;
- }
-
- /* Obtaining the raster status is a widely implemented but optional
- * feature. When this method returns OK StarCraft 2 expects the
- * raster_status->InVBlank value to actually change over time.
- * And Endless Alice Crysis doesn't care even if this method fails.
- * Thus this method returns OK and fakes raster_status by
- * QueryPerformanceCounter. */
-
- if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec))
- return WINED3DERR_INVALIDCALL;
+ TRACE("swapchain %p, raster_status %p.\n", swapchain, raster_status);
- if (FAILED(wined3d_swapchain_get_display_mode(swapchain, &mode, NULL)))
- return WINED3DERR_INVALIDCALL;
- if (mode.refresh_rate == DEFAULT_REFRESH_RATE)
- mode.refresh_rate = 60;
-
- freq_per_frame = freq_per_sec.QuadPart / mode.refresh_rate;
- /* Assume 20 scan lines in the vertical blank */
- freq_per_line = freq_per_frame / (mode.height + 20);
- raster_status->scan_line = (counter.QuadPart % freq_per_frame) / freq_per_line;
- if (raster_status->scan_line < mode.height)
- raster_status->in_vblank = FALSE;
- else
- {
- raster_status->scan_line = 0;
- raster_status->in_vblank = TRUE;
- }
- TRACE("Returning fake value, in_vblank %u, scan_line %u.\n",
- raster_status->in_vblank, raster_status->scan_line);
- return WINED3D_OK;
+ return wined3d_get_adapter_raster_status(swapchain->device->wined3d,
+ swapchain->device->adapter->ordinal, raster_status);
}
HRESULT CDECL wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain,
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index a22ebd1..eed1174 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -14,6 +14,7 @@
@ cdecl wined3d_get_adapter_identifier(ptr long long ptr)
@ cdecl wined3d_get_adapter_mode_count(ptr long long long)
@ cdecl wined3d_get_adapter_monitor(ptr long)
+@ cdecl wined3d_get_adapter_raster_status(ptr long ptr)
@ cdecl wined3d_get_device_caps(ptr long long ptr)
@ cdecl wined3d_incref(ptr)
@ cdecl wined3d_register_software_device(ptr ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index f587e44..5208a79 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2045,6 +2045,8 @@ HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UI
UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering);
HMONITOR __cdecl wined3d_get_adapter_monitor(const struct wined3d *wined3d, UINT adapter_idx);
+HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
+ struct wined3d_raster_status *raster_status);
HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_device_type device_type, WINED3DCAPS *caps);
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
More information about the wine-cvs
mailing list