The DWM workaround is not needed when DWM composition is disabled

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-01-03 11:03:24 +08:00
parent 9904a5077a
commit c3c5ef0d5d
1 changed files with 58 additions and 56 deletions

View File

@ -376,62 +376,64 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// is not correct. It confuses QPA's internal logic. // is not correct. It confuses QPA's internal logic.
clientRect->bottom += 1; clientRect->bottom += 1;
#endif #endif
// Dirty hack to workaround the DWM flicker. if (Utilities::isDwmCompositionAvailable()) {
LARGE_INTEGER freq = {}; // Dirty hack to workaround the resize flicker caused by DWM.
if (QueryPerformanceFrequency(&freq) == FALSE) { LARGE_INTEGER freq = {};
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("QueryPerformanceFrequency")); if (QueryPerformanceFrequency(&freq) == FALSE) {
break; qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("QueryPerformanceFrequency"));
} break;
TIMECAPS tc = {}; }
if (timeGetDevCaps(&tc, sizeof(tc)) != MMSYSERR_NOERROR) { TIMECAPS tc = {};
qWarning() << "timeGetDevCaps() failed."; if (timeGetDevCaps(&tc, sizeof(tc)) != MMSYSERR_NOERROR) {
break; qWarning() << "timeGetDevCaps() failed.";
} break;
const UINT ms_granularity = tc.wPeriodMin; }
if (timeBeginPeriod(ms_granularity) != TIMERR_NOERROR) { const UINT ms_granularity = tc.wPeriodMin;
qWarning() << "timeBeginPeriod() failed."; if (timeBeginPeriod(ms_granularity) != TIMERR_NOERROR) {
break; qWarning() << "timeBeginPeriod() failed.";
} break;
LARGE_INTEGER now0 = {}; }
if (QueryPerformanceCounter(&now0) == FALSE) { LARGE_INTEGER now0 = {};
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("QueryPerformanceCounter")); if (QueryPerformanceCounter(&now0) == FALSE) {
break; qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("QueryPerformanceCounter"));
} break;
// ask DWM where the vertical blank falls }
DWM_TIMING_INFO dti; // ask DWM where the vertical blank falls
SecureZeroMemory(&dti, sizeof(dti)); DWM_TIMING_INFO dti;
dti.cbSize = sizeof(dti); SecureZeroMemory(&dti, sizeof(dti));
const HRESULT hr = DwmGetCompositionTimingInfo(nullptr, &dti); dti.cbSize = sizeof(dti);
if (FAILED(hr)) { const HRESULT hr = DwmGetCompositionTimingInfo(nullptr, &dti);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("DwmGetCompositionTimingInfo")); if (FAILED(hr)) {
break; qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("DwmGetCompositionTimingInfo"));
} break;
LARGE_INTEGER now1 = {}; }
if (QueryPerformanceCounter(&now1) == FALSE) { LARGE_INTEGER now1 = {};
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("QueryPerformanceCounter")); if (QueryPerformanceCounter(&now1) == FALSE) {
break; qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("QueryPerformanceCounter"));
} break;
// - DWM told us about SOME vertical blank }
// - past or future, possibly many frames away // - DWM told us about SOME vertical blank
// - convert that into the NEXT vertical blank // - past or future, possibly many frames away
const LONGLONG period = dti.qpcRefreshPeriod; // - convert that into the NEXT vertical blank
const LONGLONG dt = dti.qpcVBlank - now1.QuadPart; const LONGLONG period = dti.qpcRefreshPeriod;
LONGLONG w = 0, m = 0; const LONGLONG dt = dti.qpcVBlank - now1.QuadPart;
if (dt >= 0) { LONGLONG w = 0, m = 0;
w = dt / period; if (dt >= 0) {
} else { w = dt / period;
// reach back to previous period } else {
// - so m represents consistent position within phase // reach back to previous period
w = -1 + dt / period; // - so m represents consistent position within phase
} w = -1 + dt / period;
m = dt - (period * w); }
Q_ASSERT(m >= 0); m = dt - (period * w);
Q_ASSERT(m < period); Q_ASSERT(m >= 0);
const qreal m_ms = 1000.0 * static_cast<qreal>(m) / static_cast<qreal>(freq.QuadPart); Q_ASSERT(m < period);
Sleep(static_cast<DWORD>(qRound(m_ms))); const qreal m_ms = 1000.0 * static_cast<qreal>(m) / static_cast<qreal>(freq.QuadPart);
if (timeEndPeriod(ms_granularity) != TIMERR_NOERROR) { Sleep(static_cast<DWORD>(qRound(m_ms)));
qWarning() << "timeEndPeriod() failed."; if (timeEndPeriod(ms_granularity) != TIMERR_NOERROR) {
break; qWarning() << "timeEndPeriod() failed.";
break;
}
} }
// We cannot return WVR_REDRAW otherwise Windows exhibits bugs where // We cannot return WVR_REDRAW otherwise Windows exhibits bugs where
// client pixels and child windows are mispositioned by the width/height // client pixels and child windows are mispositioned by the width/height