=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Introduce wined3d_find_closest_matching_adapter_mode().

Alexandre Julliard julliard at winehq.org
Fri Aug 26 10:18:11 CDT 2016


Module: wine
Branch: master
Commit: 41d29a79f51cca0452fb37db38dc6b6df4b32dc1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=41d29a79f51cca0452fb37db38dc6b6df4b32dc1

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Thu Aug 25 12:22:51 2016 +0200

wined3d: Introduce wined3d_find_closest_matching_adapter_mode().

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/directx.c    | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d.spec |   1 +
 include/wine/wined3d.h    |   2 +
 3 files changed, 103 insertions(+)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 9ff88a8..4213df3 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -4199,6 +4199,106 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada
     return WINED3D_OK;
 }
 
+HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *wined3d,
+        unsigned int adapter_idx, struct wined3d_display_mode *mode)
+{
+    unsigned int i, j, mode_count, matching_mode_count, closest;
+    struct wined3d_display_mode **matching_modes;
+    struct wined3d_display_mode *modes;
+    HRESULT hr;
+
+    TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode);
+
+    if (!(mode_count = wined3d_get_adapter_mode_count(wined3d, adapter_idx,
+            mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN)))
+    {
+        WARN("Adapter has 0 matching modes.\n");
+        return E_FAIL;
+    }
+
+    if (!(modes = wined3d_calloc(mode_count, sizeof(*modes))))
+        return E_OUTOFMEMORY;
+    if (!(matching_modes = wined3d_calloc(mode_count, sizeof(*matching_modes))))
+    {
+        HeapFree(GetProcessHeap(), 0, modes);
+        return E_OUTOFMEMORY;
+    }
+
+    for (i = 0; i < mode_count; ++i)
+    {
+        if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, adapter_idx,
+                mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &modes[i])))
+        {
+            HeapFree(GetProcessHeap(), 0, matching_modes);
+            HeapFree(GetProcessHeap(), 0, modes);
+            return hr;
+        }
+        matching_modes[i] = &modes[i];
+    }
+
+    matching_mode_count = mode_count;
+
+    if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN)
+    {
+        for (i = 0, j = 0; i < matching_mode_count; ++i)
+        {
+            if (matching_modes[i]->scanline_ordering == mode->scanline_ordering)
+                matching_modes[j++] = matching_modes[i];
+        }
+        if (j > 0)
+            matching_mode_count = j;
+    }
+
+    if (mode->refresh_rate)
+    {
+        for (i = 0, j = 0; i < matching_mode_count; ++i)
+        {
+            if (matching_modes[i]->refresh_rate == mode->refresh_rate)
+                matching_modes[j++] = matching_modes[i];
+        }
+        if (j > 0)
+            matching_mode_count = j;
+    }
+
+    if (!mode->width || !mode->height)
+    {
+        struct wined3d_display_mode current_mode;
+        if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx,
+                &current_mode, NULL)))
+        {
+            HeapFree(GetProcessHeap(), 0, matching_modes);
+            HeapFree(GetProcessHeap(), 0, modes);
+            return hr;
+        }
+        mode->width = current_mode.width;
+        mode->height = current_mode.height;
+    }
+
+    closest = ~0u;
+    for (i = 0, j = 0; i < matching_mode_count; ++i)
+    {
+        unsigned int d = abs(mode->width - matching_modes[i]->width)
+                + abs(mode->height - matching_modes[i]->height);
+
+        if (closest > d)
+        {
+            closest = d;
+            j = i;
+        }
+    }
+
+    *mode = *matching_modes[j];
+
+    HeapFree(GetProcessHeap(), 0, matching_modes);
+    HeapFree(GetProcessHeap(), 0, modes);
+
+    TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height,
+            mode->refresh_rate, debug_d3dformat(mode->format_id),
+            mode->scanline_ordering);
+
+    return WINED3D_OK;
+}
+
 HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
         struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation)
 {
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index c3899ed..0db371d 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -10,6 +10,7 @@
 @ cdecl wined3d_create(long)
 @ cdecl wined3d_decref(ptr)
 @ cdecl wined3d_enum_adapter_modes(ptr long long long long ptr)
+@ cdecl wined3d_find_closest_matching_adapter_mode(ptr long ptr)
 @ cdecl wined3d_get_adapter_count(ptr)
 @ cdecl wined3d_get_adapter_display_mode(ptr long ptr ptr)
 @ cdecl wined3d_get_adapter_identifier(ptr long long ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 1c9b262..bc343ec 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2105,6 +2105,8 @@ ULONG __cdecl wined3d_decref(struct wined3d *wined3d);
 HRESULT __cdecl wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx,
         enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering,
         UINT mode_idx, struct wined3d_display_mode *mode);
+HRESULT __cdecl wined3d_find_closest_matching_adapter_mode(const struct wined3d *wined3d,
+        unsigned int adapter_idx, struct wined3d_display_mode *mode);
 UINT __cdecl wined3d_get_adapter_count(const struct wined3d *wined3d);
 HRESULT __cdecl wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
         struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);




More information about the wine-cvs mailing list