Skip to content
This repository has been archived by the owner on Sep 29, 2022. It is now read-only.

Commit

Permalink
Minor tweaks
Browse files Browse the repository at this point in the history
1. Workaround DWM flicker
2. Cleanup CMake script
3. Simplify some code

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
  • Loading branch information
wangwenx190 committed Dec 1, 2021
1 parent 6170cb8 commit 8a7e256
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 46 deletions.
24 changes: 6 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,7 @@ option(BUILD_DirectComposition_DEMO "Build the Direct Composition demo applicati
option(BUILD_Win32_DEMO "Build the Win32 demo application." ON)
option(OPTIMIZE_FOR_SPEED "Enable as much optimization as possible." OFF)

if(DEFINED CMAKE_BUILD_TYPE)
if("x${CMAKE_BUILD_TYPE}" STREQUAL "xMinSizeRel")
message(FATAL_ERROR "This project doesn't support the MinSizeRel configuration.")
endif()
if("x${CMAKE_BUILD_TYPE}" STREQUAL "xRelWithDebInfo")
message(FATAL_ERROR "This project doesn't support the RelWithDebInfo configuration.")
endif()
else()
# Defaults to release builds if not set by the user.
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()

Expand Down Expand Up @@ -77,12 +69,12 @@ string(APPEND CMAKE_CXX_FLAGS_DEBUG " /JMC ")

set(_optimization_flags)
if(OPTIMIZE_FOR_SPEED)
# Don't use "/GA" for DLLs, it will cause bad code generation.
set(_optimization_flags "/O2 /Ob3 /Oi /GA /GT")
set(_optimization_flags "/O2 /Ob3 /Oi")
else()
set(_optimization_flags "/O1 /Ob1")
endif()
string(APPEND CMAKE_CXX_FLAGS_RELEASE " ${_optimization_flags} /guard:cf /guard:ehcont /Gw /Gy /Zc:inline ")
# Don't use "/GA" for DLLs, it will cause bad code generation.
string(APPEND CMAKE_CXX_FLAGS_RELEASE " ${_optimization_flags} /guard:cf /guard:ehcont /GA /GT /Gw /Gy /Zc:inline ")

string(APPEND CMAKE_EXE_LINKER_FLAGS_RELEASE " /CETCOMPAT /DYNAMICBASE /GUARD:CF /GUARD:EHCONT /HIGHENTROPYVA /LARGEADDRESSAWARE /NXCOMPAT /OPT:REF /OPT:ICF /TSAWARE /WX ")

Expand Down Expand Up @@ -112,14 +104,10 @@ set(SOURCES_Win32AcrylicHelper
Win32AcrylicHelper/Thunks/CoreMessaging_Thunk.cpp Win32AcrylicHelper/Thunks/WinRTWrappers.cpp
Win32AcrylicHelper/Thunks/Undocumented.h Win32AcrylicHelper/Thunks/Undocumented.cpp
Win32AcrylicHelper/Thunks/SHCore_Thunk.cpp Win32AcrylicHelper/Thunks/D2D1_Thunk.cpp
Win32AcrylicHelper/Thunks/WinMM_Thunk.cpp
)
add_library(${PROJECT_NAME} STATIC ${SOURCES_Win32AcrylicHelper})
add_library(wangwenx190::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
# No need to enable link time optimization for static libraries.
#set_target_properties(${PROJECT_NAME} PROPERTIES
# INTERPROCEDURAL_OPTIMIZATION OFF
# INTERPROCEDURAL_OPTIMIZATION_RELEASE OFF
#)
target_include_directories(${PROJECT_NAME} PUBLIC
Win32AcrylicHelper
Win32AcrylicHelper/Thunks
Expand All @@ -139,7 +127,7 @@ target_compile_definitions(${PROJECT_NAME} PUBLIC
WINVER=${_WIN32_WINNT_WIN10} _WIN32_WINNT=${_WIN32_WINNT_WIN10}
_WIN32_IE=${_WIN32_WINNT_WIN10} NTDDI_VERSION=${NTDDI_WIN10_CO}
_KERNEL32_ _USER32_ _SHELL32_ _GDI32_ _OLE32_ _OLEAUT32_
_ADVAPI32_ _COMBASEAPI_ _DWMAPI_ _UXTHEME_ _ROAPI_
_ADVAPI32_ _COMBASEAPI_ _DWMAPI_ _UXTHEME_ _ROAPI_ _WINMM_
)

# Demo applications
Expand Down
1 change: 1 addition & 0 deletions Win32AcrylicHelper/Thunks/DwmApi_Thunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ __THUNK_API(__DWMAPI_DLL_FILENAME, DwmGetWindowAttribute, HRESULT, DEFAULT_HRESU
__THUNK_API(__DWMAPI_DLL_FILENAME, DwmExtendFrameIntoClientArea, HRESULT, DEFAULT_HRESULT, (HWND arg1, const MARGINS *arg2), (arg1, arg2))
__THUNK_API(__DWMAPI_DLL_FILENAME, DwmFlush, HRESULT, DEFAULT_HRESULT, (VOID), ())
__THUNK_API(__DWMAPI_DLL_FILENAME, DwmIsCompositionEnabled, HRESULT, DEFAULT_HRESULT, (BOOL *arg1), (arg1))
__THUNK_API(__DWMAPI_DLL_FILENAME, DwmGetCompositionTimingInfo, HRESULT, DEFAULT_HRESULT, (HWND arg1, DWM_TIMING_INFO *arg2), (arg1, arg2))
12 changes: 4 additions & 8 deletions Win32AcrylicHelper/Thunks/Undocumented.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,11 @@ EXTERN_C result_type WINAPI \
symbol \
argument_signature \
{ \
static bool tried = false; \
static decltype (& :: symbol) symbol ## _API = nullptr; \
if (!tried) { \
tried = true; \
using sig = decltype (& :: symbol); \
static const sig symbol ## _API = [](){ \
const HMODULE dll = LoadLibraryExW(L#library , nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); \
if (dll) { \
symbol ## _API = reinterpret_cast<decltype (& :: symbol)>(GetProcAddress(dll, MAKEINTRESOURCEA( ordinal ))); \
} \
} \
return ( dll ? reinterpret_cast<sig>(GetProcAddress(dll, MAKEINTRESOURCEA( ordinal ))) : nullptr ); \
}(); \
return ( ( symbol ## _API ) ? ( symbol ## _API argument_list ) : ( default_result ) ); \
} \
_LCRT_DEFINE_IAT_SYMBOL( symbol , 0 );
Expand Down
39 changes: 39 additions & 0 deletions Win32AcrylicHelper/Thunks/WinMM_Thunk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* MIT License
*
* Copyright (C) 2021 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#ifndef _WINMM_
#define _WINMM_
#endif // _WINMM_

#include "WindowsAPIThunks.h"

#include <TimeApi.h>

#ifndef __WINMM_DLL_FILENAME
#define __WINMM_DLL_FILENAME winmm.dll
#endif // __WINMM_DLL_FILENAME

__THUNK_API(__WINMM_DLL_FILENAME, timeGetDevCaps, MMRESULT, DEFAULT_UINT, (LPTIMECAPS arg1, UINT arg2), (arg1, arg2))
__THUNK_API(__WINMM_DLL_FILENAME, timeBeginPeriod, MMRESULT, DEFAULT_UINT, (UINT arg1), (arg1))
__THUNK_API(__WINMM_DLL_FILENAME, timeEndPeriod, MMRESULT, DEFAULT_UINT, (UINT arg1), (arg1))
59 changes: 59 additions & 0 deletions Win32AcrylicHelper/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
#include <ShellApi.h>
#include <ShellScalingApi.h>
#include <DwmApi.h>
#include <TimeApi.h>
#include <cmath>
#include <cassert>

#ifndef ABM_GETAUTOHIDEBAREX
#define ABM_GETAUTOHIDEBAREX (0x0000000b)
Expand Down Expand Up @@ -1705,6 +1707,63 @@ bool WindowPrivate::InternalMessageHandler(const UINT message, const WPARAM wPar
}
}
}
// Dirty hack to workaround the DWM flicker.
LARGE_INTEGER freq = {};
if (QueryPerformanceFrequency(&freq) == FALSE) {
PRINT_WIN32_ERROR_MESSAGE(QueryPerformanceFrequency, L"Failed to retrieve the CPU frequency.")
return false;
}
TIMECAPS tc = {};
if (timeGetDevCaps(&tc, sizeof(tc)) != MMSYSERR_NOERROR) {
Utils::DisplayErrorDialog(L"timeGetDevCaps() failed.");
return false;
}
const UINT ms_granularity = tc.wPeriodMin;
if (timeBeginPeriod(ms_granularity) != TIMERR_NOERROR) {
Utils::DisplayErrorDialog(L"timeBeginPeriod() failed.");
return false;
}
LARGE_INTEGER now0 = {};
if (QueryPerformanceCounter(&now0) == FALSE) {
PRINT_WIN32_ERROR_MESSAGE(QueryPerformanceCounter, L"Failed to retrieve the performance counter.")
return false;
}
// ask DWM where the vertical blank falls
DWM_TIMING_INFO dti;
SecureZeroMemory(&dti, sizeof(dti));
dti.cbSize = sizeof(dti);
const HRESULT hr = DwmGetCompositionTimingInfo(nullptr, &dti);
if (FAILED(hr)) {
PRINT_HR_ERROR_MESSAGE(DwmGetCompositionTimingInfo, hr, L"Failed to retrieve the composition timing info.")
return false;
}
LARGE_INTEGER now1 = {};
if (QueryPerformanceCounter(&now1) == FALSE) {
PRINT_WIN32_ERROR_MESSAGE(QueryPerformanceCounter, L"Failed to retrieve the performance counter.")
return false;
}
// - DWM told us about SOME vertical blank
// - past or future, possibly many frames away
// - convert that into the NEXT vertical blank
const LONGLONG period = dti.qpcRefreshPeriod;
const LONGLONG dt = dti.qpcVBlank - now1.QuadPart;
LONGLONG w = 0, m = 0;
if (dt >= 0) {
w = dt / period;
} else {
// reach back to previous period
// - so m represents consistent position within phase
w = -1 + dt / period;
}
m = dt - (period * w);
assert(m >= 0);
assert(m < period);
const double m_ms = 1000.0 * static_cast<double>(m) / static_cast<double>(freq.QuadPart);
Sleep(static_cast<int>(std::round(m_ms)));
if (timeEndPeriod(ms_granularity) != TIMERR_NOERROR) {
Utils::DisplayErrorDialog(L"timeEndPeriod() failed.");
return false;
}
// We cannot return WVR_REDRAW otherwise Windows exhibits bugs
// where client pixels and child windows are mispositioned by
// the width/height of the upper-left nonclient area.
Expand Down
37 changes: 17 additions & 20 deletions Win32AcrylicHelper/WindowsVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,25 @@

const VersionNumber &WindowsVersion::CurrentVersion() noexcept
{
static bool tried = false;
static VersionNumber version = VersionNumber();
if (version.Empty()) {
if (!tried) {
tried = true;
static const auto RtlGetVersion_API = reinterpret_cast<NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW)>(SystemLibrary::GetSymbolNoCache(L"ntdll.dll", L"RtlGetVersion"));
if (RtlGetVersion_API) {
RTL_OSVERSIONINFOEXW osvi;
SecureZeroMemory(&osvi, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (RtlGetVersion_API(reinterpret_cast<PRTL_OSVERSIONINFOW>(&osvi)) == STATUS_SUCCESS) {
version.Major(osvi.dwMajorVersion);
version.Minor(osvi.dwMinorVersion);
version.Patch(osvi.dwBuildNumber);
} else {
PRINT_WIN32_ERROR_MESSAGE(RtlGetVersion, L"Failed to retrieve the current system version.")
}
static const VersionNumber version = [](){
int major = 0, minor = 0, patch = 0;
static const auto RtlGetVersion_API = reinterpret_cast<NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW)>(SystemLibrary::GetSymbolNoCache(L"ntdll.dll", L"RtlGetVersion"));
if (RtlGetVersion_API) {
RTL_OSVERSIONINFOEXW osvi;
SecureZeroMemory(&osvi, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (RtlGetVersion_API(reinterpret_cast<PRTL_OSVERSIONINFOW>(&osvi)) == STATUS_SUCCESS) {
major = osvi.dwMajorVersion;
minor = osvi.dwMinorVersion;
patch = osvi.dwBuildNumber;
} else {
Utils::DisplayErrorDialog(L"Failed to resolve symbol \"RtlGetVersion()\" from dynamic link library \"NTDll.dll\".");
PRINT_WIN32_ERROR_MESSAGE(RtlGetVersion, L"Failed to retrieve the current system version.")
}
} else {
Utils::DisplayErrorDialog(L"Failed to resolve symbol \"RtlGetVersion()\" from dynamic link library \"NTDll.dll\".");
}
}
return VersionNumber(major, minor, patch);
}();
return version;
}

Expand All @@ -76,7 +73,7 @@ std::wstring WindowsVersion::ToHumanReadableString(const VersionNumber &version)
{
std::wstring humanReadableString = {};
if (version >= Windows11) {
humanReadableString = L"Windows 11";
humanReadableString = L"Windows 11 Version 21H2";
} else if (version >= Windows10_21H2) {
humanReadableString = L"Windows 10 Version 21H2 (November 2021 Update)";
} else if (version >= Windows10_21H1) {
Expand Down

0 comments on commit 8a7e256

Please sign in to comment.