[PATCH 1/5] ddraw: Implement ddraw7_GetScanLine() on top of wined3d_get_adapter_raster_status().

Henri Verbeet hverbeet at codeweavers.com
Wed Jul 18 14:32:30 CDT 2012


---
 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 28cb707..19bd926 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -3220,6 +3220,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);
-- 
1.7.8.6




More information about the wine-patches mailing list