MCPcopy Create free account
hub / github.com/GameTechDev/PresentMon / CompletePresent

Method CompletePresent

PresentData/PresentMonTraceConsumer.cpp:2084–2451  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2082}
2083
2084void PMTraceConsumer::CompletePresent(std::shared_ptr<PresentEvent> const& p)
2085{
2086 // We use the first completed present to indicate that all necessary
2087 // providers are running and able to successfully track/complete presents.
2088 //
2089 // At the first completion, there may be numerous presents that have been
2090 // created but not properly tracked due to missed events. This is
2091 // especially prevalent in ETLs that start runtime providers before backend
2092 // providers and/or start capturing while an intensive graphics application
2093 // is already running. When that happens, PresentStartTime/TimeInPresentAPI and
2094 // ReadyTime/ScreenTime times can become mis-matched, and that offset can
2095 // persist for the full capture.
2096 //
2097 // We handle this by throwing away all queued presents up to this point.
2098 if (!mHasCompletedAPresent && !p->IsLost) {
2099 for (auto const& pr : mOrderedPresentsByProcessId) {
2100 for (auto orderedPresents = &pr.second; !orderedPresents->empty(); ) {
2101 RemoveLostPresent(orderedPresents->begin()->second);
2102 }
2103 }
2104
2105 mHasCompletedAPresent = true;
2106 return;
2107 }
2108
2109 // Protect against CompletePresent() being called twice for the same present. That isn't
2110 // intended, but there have been cases observed where it happens (in some cases leading to
2111 // infinite recursion with a DWM present and a dependent present completing each other).
2112 //
2113 // The exact pattern causing this has not yet been identified, so is the best fix for now.
2114 DebugAssert(p->IsCompleted == false);
2115 if (p->IsCompleted) {
2116 return;
2117 }
2118
2119 // Mark the present as completed.
2120 VerboseTraceBeforeModifyingPresent(p.get());
2121 p->IsCompleted = true;
2122
2123 // It is possible for a present to be displayed or discarded before Present_Stop. If this
2124 // happens, we stop tracking the present (except for mPresentByThreadId which is required by
2125 // Present_Stop to lookup the present) but do not add the present to the dequeue list yet.
2126 // Present_Stop will check if the present is completed and add it to the dequeue list if so.
2127 if (!p->IsLost && p->Runtime != Runtime::Other && p->TimeInPresent == 0) {
2128 VerboseTraceBeforeModifyingPresent(p.get());
2129 p->WaitingForPresentStop = true;
2130 }
2131
2132 // If flip frame type tracking is enabled, we defer the completion because we may see subsequent
2133 // FlipFrameType events that need to refer back to this PresentEvent. The deferral will be
2134 // completed when we see another MMIOFlipMultiPlaneOverlay3_Info event for the same
2135 // (VidPnSourceId, LayerIndex) pair.
2136 if (!p->IsLost && !p->DoneWaitingForFlipFrameType && mEnableFlipFrameTypeEvents && p->FinalState == PresentResult::Presented) {
2137 VerboseTraceBeforeModifyingPresent(p.get());
2138 p->WaitingForFlipFrameType = true;
2139 }
2140
2141 // If this is a DWM present, update the dependent presents' final state and complete them as

Callers

nothing calls this directly

Calls 4

emptyMethod · 0.80
beginMethod · 0.45
sizeMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected