https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d2a87f1b7fc3cce462ff4…
commit d2a87f1b7fc3cce462ff42c0932aa1b81b533a06
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sun May 22 22:47:20 2022 +0200
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Sun May 22 23:42:03 2022 +0200
[WIN32K] Improve finding the best matching display mode
Search the display mode having the smallest difference with the requested one.
We can then remove the hardcoded values of 60 Hz and 32 bpp by default.
CORE-18189
---
win32ss/gdi/eng/ldevobj.c | 64 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 46 insertions(+), 18 deletions(-)
diff --git a/win32ss/gdi/eng/ldevobj.c b/win32ss/gdi/eng/ldevobj.c
index bd6d282c23c..b7626f92886 100644
--- a/win32ss/gdi/eng/ldevobj.c
+++ b/win32ss/gdi/eng/ldevobj.c
@@ -669,6 +669,8 @@ LDEVOBJ_bBuildDevmodeList(
return TRUE;
}
+/* Search the closest display mode according to some settings.
+ * Note that we don't care about the DM_* flags in dmFields, but check if value != 0
instead */
static
BOOL
LDEVOBJ_bGetClosestMode(
@@ -676,31 +678,57 @@ LDEVOBJ_bGetClosestMode(
_In_ PDEVMODEW RequestedMode,
_Out_ PDEVMODEW *pSelectedMode)
{
- if (pGraphicsDevice->cDevModes == 0)
- return FALSE;
+ DEVMODEW dmDiff;
+ PDEVMODEW pdmCurrent, pdmBest = NULL;
+ ULONG i;
- /* Search a 32bit mode (if not already specified) */
- if (!(RequestedMode->dmFields & DM_BITSPERPEL))
+ /* Use a DEVMODE to keep the differences between best mode found and expected mode.
+ * Initialize fields to max value so we can find better modes. */
+ dmDiff.dmPelsWidth = 0xffffffff;
+ dmDiff.dmPelsHeight = 0xffffffff;
+ dmDiff.dmBitsPerPel = 0xffffffff;
+ dmDiff.dmDisplayFrequency = 0xffffffff;
+
+ /* Search the closest mode */
+#define DM_DIFF(field) (RequestedMode->field > pdmCurrent->field ?
(RequestedMode->field - pdmCurrent->field) : (pdmCurrent->field -
RequestedMode->field))
+ for (i = 0; i < pGraphicsDevice->cDevModes; i++)
{
- RequestedMode->dmBitsPerPel = 32;
- RequestedMode->dmFields |= DM_BITSPERPEL;
+ pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
+
+ /* Skip current mode if it is worse than best mode found */
+ if (RequestedMode->dmPelsWidth != 0 && DM_DIFF(dmPelsWidth) >
dmDiff.dmPelsWidth)
+ continue;
+ if (RequestedMode->dmPelsHeight != 0 && DM_DIFF(dmPelsHeight) >
dmDiff.dmPelsHeight)
+ continue;
+ if (RequestedMode->dmBitsPerPel != 0 && DM_DIFF(dmBitsPerPel) >
dmDiff.dmBitsPerPel)
+ continue;
+ if (RequestedMode->dmDisplayFrequency != 0 &&
DM_DIFF(dmDisplayFrequency) > dmDiff.dmDisplayFrequency)
+ continue;
+
+ /* Better (or equivalent) mode found. Update differences */
+ dmDiff.dmPelsWidth = DM_DIFF(dmPelsWidth);
+ dmDiff.dmPelsHeight = DM_DIFF(dmPelsHeight);
+ dmDiff.dmBitsPerPel = DM_DIFF(dmBitsPerPel);
+ dmDiff.dmDisplayFrequency = DM_DIFF(dmDisplayFrequency);
+ pdmBest = pdmCurrent;
}
- if (LDEVOBJ_bProbeAndCaptureDevmode(pGraphicsDevice, RequestedMode, pSelectedMode,
FALSE))
- return TRUE;
+#undef DM_DIFF
- /* Search 60 Hz (if not already specified) */
- if (!(RequestedMode->dmFields & DM_DISPLAYFREQUENCY))
+ if (pdmBest)
{
- RequestedMode->dmDisplayFrequency = 60;
- RequestedMode->dmFields |= DM_DISPLAYFREQUENCY;
- if (LDEVOBJ_bProbeAndCaptureDevmode(pGraphicsDevice, RequestedMode,
pSelectedMode, FALSE))
- return TRUE;
+ TRACE("Closest display mode to '%dx%dx%d %d Hz' is '%dx%dx%d %d
Hz'\n",
+ RequestedMode->dmPelsWidth,
+ RequestedMode->dmPelsHeight,
+ RequestedMode->dmBitsPerPel,
+ RequestedMode->dmDisplayFrequency,
+ pdmBest->dmPelsWidth,
+ pdmBest->dmPelsHeight,
+ pdmBest->dmBitsPerPel,
+ pdmBest->dmDisplayFrequency);
}
- /* Fall back to first mode */
- WARN("Fall back to first available mode\n");
- *pSelectedMode = pGraphicsDevice->pDevModeList[0].pdm;
- return TRUE;
+ *pSelectedMode = pdmBest;
+ return pdmBest != NULL;
}
BOOL