Skip to content

Commit

Permalink
Merge branch 'dev/lvengesanam/resolve_wndProc_issues' into 'main'
Browse files Browse the repository at this point in the history
[REMIX-3328] Improve handling of recursive calls to WndProc callback procedure

See merge request lightspeedrtx/bridge-remix-nv!116
  • Loading branch information
lvengesanam committed Oct 8, 2024
2 parents 31bea36 + 0c0b8b1 commit b143354
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 41 deletions.
65 changes: 34 additions & 31 deletions src/client/d3d9_lss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ SceneState gSceneState = WaitBeginScene;
std::chrono::steady_clock::time_point gTimeStart;
bool gbBridgeRunning = true;
std::string gRemixFolder = "";
thread_local int gRemixWndProcEntryExitCount = 0;
thread_local std::unordered_map<UINT, int> gRemixWndProcEntryExitCountMap;

void PrintRecentCommandHistory() {
// Log history of recent client side commands sent and received by the server
Expand Down Expand Up @@ -468,35 +468,11 @@ LRESULT WINAPI RemixWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
const bool isUnicode = IsWindowUnicode(hWnd);

LRESULT lresult = 0;
gRemixWndProcEntryExitCount += 1;
int curEntryExitCount = gRemixWndProcEntryExitCount;
// Detecting recursive calls
if (curEntryExitCount > 1) {
int wndProcListLen = 0;
{
std::scoped_lock lock(gWndProcListMapMutex);
if(ogWndProcList.find(hWnd) != ogWndProcList.end())
wndProcListLen = ogWndProcList[hWnd].size();
}
int curWndProcIndex = curEntryExitCount-1;
if (curWndProcIndex >= wndProcListLen) {
gRemixWndProcEntryExitCount = 0;
lresult = !isUnicode ?
DefWindowProcA(hWnd, msg, wParam, lParam) :
DefWindowProcW(hWnd, msg, wParam, lParam);
}
else {
WNDPROC prevWndProc;
{
std::scoped_lock lock(gWndProcListMapMutex);
prevWndProc = ogWndProcList[hWnd][curWndProcIndex];
}
lresult = !isUnicode ?
CallWindowProcA(prevWndProc, hWnd, msg, wParam, lParam) :
CallWindowProcW(prevWndProc, hWnd, msg, wParam, lParam);
}
}
else {
gRemixWndProcEntryExitCountMap[msg] += 1;
int curEntryExitCount = gRemixWndProcEntryExitCountMap[msg];

if (curEntryExitCount == 1)
{
if (msg == WM_ACTIVATEAPP || msg == WM_SIZE || msg == WM_DESTROY) {
gSwapChainMapMutex.lock();
if (gSwapChainMap.find(hWnd) != gSwapChainMap.end()) {
Expand Down Expand Up @@ -549,7 +525,34 @@ LRESULT WINAPI RemixWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
CallWindowProcW(prevWndProc, hWnd, msg, wParam, lParam);
}
}
gRemixWndProcEntryExitCount -= 1;
else {
int wndProcListLen = 0;
{
std::scoped_lock lock(gWndProcListMapMutex);
if(ogWndProcList.find(hWnd) != ogWndProcList.end())
wndProcListLen = ogWndProcList[hWnd].size();
}
int curWndProcIndex = curEntryExitCount-1;
if (curWndProcIndex >= wndProcListLen) {
Logger::warn(logger_strings::WndProcExcessiveRecCall + std::to_string(msg) + " wParam: " + std::to_string(wParam));
lresult = !isUnicode ?
DefWindowProcA(hWnd, msg, wParam, lParam) :
DefWindowProcW(hWnd, msg, wParam, lParam);
}
else {
WNDPROC prevWndProc;
{
std::scoped_lock lock(gWndProcListMapMutex);
prevWndProc = ogWndProcList[hWnd][curWndProcIndex];
}
lresult = !isUnicode ?
CallWindowProcA(prevWndProc, hWnd, msg, wParam, lParam) :
CallWindowProcW(prevWndProc, hWnd, msg, wParam, lParam);
}
}

gRemixWndProcEntryExitCountMap[msg] -= 1;

return lresult;
}

Expand Down
9 changes: 0 additions & 9 deletions src/client/d3d9_swapchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,6 @@ HRESULT Direct3DSwapChain9_LSS::Present(CONST RECT* pSourceRect, CONST RECT* pDe
c.send_data(dwFlags);
}

// Seeing this in the log could indicate the game is sending inputs to a different window
extern std::unordered_map<HWND, std::deque<WNDPROC>> ogWndProcList;
extern std::mutex gWndProcListMapMutex;
if (hDestWindowOverride != NULL) {
std::scoped_lock lock(gWndProcListMapMutex);
if (ogWndProcList.find(hDestWindowOverride) == ogWndProcList.end())
ONCE(Logger::info("Detected unhooked winproc on Direct3DSwapChain9::Present"));
}

extern HRESULT syncOnPresent();
const auto syncResult = syncOnPresent();
if (syncResult == ERROR_SEM_TIMEOUT) {
Expand Down
2 changes: 1 addition & 1 deletion src/util/log/log_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace logger_strings {
constexpr char* MultipleActiveCommands = "Multiple active Command instances detected!";
constexpr char* RtxRemixRuntimeError = "RTX Remix Runtime Error!";
constexpr char* BridgeClientClosing = "The RTX Remix Runtime has encountered an unexpected issue. The application will close.\n\nPlease collect any *.log or *.dmp files next to the application or in the .trex folder, and report the error at https://github.com/NVIDIAGameWorks/rtx-remix/issues.";

constexpr char* WndProcExcessiveRecCall = "Detected excessive recursive calls to RemixWndProc - msg: ";
inline static const std::map<const std::string, const std::string> bufferNameToOptionMap =
{
{"ModuleClient2ServerData", "moduleClientChannelMemSize"},
Expand Down

0 comments on commit b143354

Please sign in to comment.