From 6dbb28751aa27ccd8affbba2f9827c0e2e6889fc Mon Sep 17 00:00:00 2001 From: nikkumaar Date: Thu, 10 Apr 2025 17:18:13 +0530 Subject: [PATCH 1/3] Fix frames marked as discarded incorrectly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The way FrameView/PresentMon marks the completion of frames is to first just mark frames as 'Presented' when it receives MMIO MPO flip call and then once Win32k providers’ (running within DWM process) TokenStateChange(TokenState::Discarded) event is received it is marked as completed. In certain cases like when there are short bursts of presents, we get multiple back to back flips and token tracking thread ends up marking the second frame in the burst as dropped. To fix this issue, we mark the frame as discarded only if the frame already doesn’t have valid ScreenTime. --- PresentData/PresentMonTraceConsumer.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/PresentData/PresentMonTraceConsumer.cpp b/PresentData/PresentMonTraceConsumer.cpp index edd5f8fa..628f2c32 100644 --- a/PresentData/PresentMonTraceConsumer.cpp +++ b/PresentData/PresentMonTraceConsumer.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2017-2024 Intel Corporation +// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved // SPDX-License-Identifier: MIT #include "PresentMonTraceConsumer.hpp" @@ -1568,7 +1569,16 @@ void PMTraceConsumer::HandleWin32kEvent(EVENT_RECORD* pEventRecord) // collisions during lookup for events that don't reference // a context. VerboseTraceBeforeModifyingPresent(prevPresent.get()); - prevPresent->FinalState = PresentResult::Discarded; + + // In certain cases like when there are short bursts of presents, + // we get multiple back to back flips and token tracking thread + // ends up marking the second frame in the burst as dropped. + // To fix this issue, we mark the frame as discarded only if + // the frame already doesn’t have valid ScreenTime. + if (!hWndIter->second->ScreenTime) { + prevPresent->FinalState = PresentResult::Discarded; + } + RemovePresentFromSubmitSequenceIdTracking(prevPresent); } } From 4d5fcdcc9ad6af35eee22cb3cf43a26e083e584e Mon Sep 17 00:00:00 2001 From: nikkumaar <84899212+nikkumaar@users.noreply.github.com> Date: Thu, 24 Apr 2025 18:45:01 +0530 Subject: [PATCH 2/3] Update PresentMonTraceConsumer.cpp Check if there is valid ScreenTime before marking frame as discarded. --- PresentData/PresentMonTraceConsumer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PresentData/PresentMonTraceConsumer.cpp b/PresentData/PresentMonTraceConsumer.cpp index 628f2c32..fa99a3d5 100644 --- a/PresentData/PresentMonTraceConsumer.cpp +++ b/PresentData/PresentMonTraceConsumer.cpp @@ -1575,7 +1575,7 @@ void PMTraceConsumer::HandleWin32kEvent(EVENT_RECORD* pEventRecord) // ends up marking the second frame in the burst as dropped. // To fix this issue, we mark the frame as discarded only if // the frame already doesn’t have valid ScreenTime. - if (!hWndIter->second->ScreenTime) { + if (HasScreenTime(hWndIter->second)) { prevPresent->FinalState = PresentResult::Discarded; } From bef42ca4f9925b09a6f9e1f2ec589b9cc41228aa Mon Sep 17 00:00:00 2001 From: nikkumaar <84899212+nikkumaar@users.noreply.github.com> Date: Thu, 24 Apr 2025 19:00:29 +0530 Subject: [PATCH 3/3] Update PresentMonTraceConsumer.cpp --- PresentData/PresentMonTraceConsumer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PresentData/PresentMonTraceConsumer.cpp b/PresentData/PresentMonTraceConsumer.cpp index fa99a3d5..31186a3a 100644 --- a/PresentData/PresentMonTraceConsumer.cpp +++ b/PresentData/PresentMonTraceConsumer.cpp @@ -1575,7 +1575,7 @@ void PMTraceConsumer::HandleWin32kEvent(EVENT_RECORD* pEventRecord) // ends up marking the second frame in the burst as dropped. // To fix this issue, we mark the frame as discarded only if // the frame already doesn’t have valid ScreenTime. - if (HasScreenTime(hWndIter->second)) { + if (!HasScreenTime(hWndIter->second)) { prevPresent->FinalState = PresentResult::Discarded; }