Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 41 additions & 16 deletions PresentData/PresentMonTraceConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2235,6 +2235,7 @@ void PMTraceConsumer::CompletePresent(std::shared_ptr<PresentEvent> const& p)
p->ProcessId,
0,
p->PresentStartTime,
p->PresentStartTime + p->TimeInPresent,
[this](const AppTimingData& d) {
if (mUsingOutOfBoundPresentStart) {
return d.PclOutOfBandPresentStartTime;
Expand Down Expand Up @@ -2637,6 +2638,7 @@ void PMTraceConsumer::RuntimePresentStop(Runtime runtime, EVENT_HEADER const& hd
return;
}
auto present = eventIter->second;
auto PresentStopTime = static_cast<uint64_t>(hdr.TimeStamp.QuadPart);

if (mTrackAppTiming) {
if (IsApplicationPresent(present)) {
Expand All @@ -2645,7 +2647,9 @@ void PMTraceConsumer::RuntimePresentStop(Runtime runtime, EVENT_HEADER const& hd
present->ProcessId,
present->AppFrameId,
present->PresentStartTime,
[](const AppTimingData& d) { return d.AppPresentStartTime; });
PresentStopTime,
[](const AppTimingData& d) { return d.AppPresentStartTime; },
false);
if (appTimingData) {
if (present->ProcessId == appTimingData->ProcessId) {
if (present->AppFrameId == 0) {
Expand Down Expand Up @@ -2683,7 +2687,7 @@ void PMTraceConsumer::RuntimePresentStop(Runtime runtime, EVENT_HEADER const& hd
// Set the runtime and Present_Stop time.
VerboseTraceBeforeModifyingPresent(present.get());
present->Runtime = runtime;
present->TimeInPresent = *(uint64_t*) &hdr.TimeStamp - present->PresentStartTime;
present->TimeInPresent = PresentStopTime - present->PresentStartTime;

// If this present completed early and was deferred until the Present_Stop, then no more
// analysis is needed; we just clear the deferral.
Expand Down Expand Up @@ -3669,7 +3673,8 @@ PMTraceConsumer::EventProcessingScope::~EventProcessingScope()

AppTimingData* PMTraceConsumer::ExtractAppTimingData(
std::unordered_map<std::pair<uint32_t, uint32_t>, AppTimingData, PairHash<uint32_t, uint32_t>>& timingDataByFrameId,
uint32_t processId, uint32_t appFrameId, uint64_t presentStartTime, std::function<uint64_t(const AppTimingData&)> timingSelector) {
uint32_t processId, uint32_t appFrameId, uint64_t presentStartTime, uint64_t presentStopTime, std::function<uint64_t(const AppTimingData&)> timingSelector,
bool isPcLatency) {
if (appFrameId != 0) {
// If the incoming app frame id is already assigned then we receiving
// the information from version 2 of the PresentFrameType event.
Expand All @@ -3682,19 +3687,39 @@ AppTimingData* PMTraceConsumer::ExtractAppTimingData(
}
} else {
auto itToReturn = timingDataByFrameId.end();
uint32_t earlierFrameId = std::numeric_limits<uint32_t>::max();
uint64_t smallestPresentStartDelta = std::numeric_limits<uint64_t>::max();
// Search for the timing data with the closest PresentStartTime to the passed
// in PresentStartTime that has not been assigned. This is a hack and will not work for x-platform.
for (auto it = timingDataByFrameId.begin(); it != timingDataByFrameId.end(); ++it) {
if (it->first.second == processId) {
if (it->second.AssignedToPresent == false) {
uint64_t timingValue = timingSelector(it->second);
if (timingValue != 0 && timingValue < presentStartTime) {
auto tempPresentStartDelta = presentStartTime - timingValue;
if (tempPresentStartDelta < smallestPresentStartDelta) {
smallestPresentStartDelta = tempPresentStartDelta;
earlierFrameId = it->first.first;
if (isPcLatency) {
// For PC latency we match the app timing data to the present by selecting the unassigned entry whose selected
// time is closest to (but earlier than) PresentStartTime.
uint64_t smallestPresentStartDelta = std::numeric_limits<uint64_t>::max();
// Search for the timing data with the closest PresentStartTime to the passed
// in PresentStartTime that has not been assigned. This is a hack and will not work for x-platform.
for (auto it = timingDataByFrameId.begin(); it != timingDataByFrameId.end(); ++it) {
if (it->first.second == processId) {
if (it->second.AssignedToPresent == false) {
uint64_t timingValue = timingSelector(it->second);
if (timingValue != 0 && timingValue < presentStartTime) {
auto tempPresentStartDelta = presentStartTime - timingValue;
if (tempPresentStartDelta < smallestPresentStartDelta) {
smallestPresentStartDelta = tempPresentStartDelta;
itToReturn = it;
}
}
}
}
}
} else {
// For non-PC latency metrics we match unassigned timing data whose selected time falls
// between present start and stop. If more than one qualifies, use the earliest.
uint64_t earliestTimingValueInWindow = std::numeric_limits<uint64_t>::max();
for (auto it = timingDataByFrameId.begin(); it != timingDataByFrameId.end(); ++it) {
if (it->first.second == processId) {
if (it->second.AssignedToPresent == false) {
uint64_t timingValue = timingSelector(it->second);
if (timingValue != 0
&& presentStartTime <= timingValue
&& timingValue <= presentStopTime
&& timingValue < earliestTimingValueInWindow) {
earliestTimingValueInWindow = timingValue;
itToReturn = it;
}
}
Expand Down
4 changes: 3 additions & 1 deletion PresentData/PresentMonTraceConsumer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,9 @@ struct PMTraceConsumer

// -------------------------------------------------------------------------------------------
// Function for managing app provided events
AppTimingData* ExtractAppTimingData(std::unordered_map<std::pair<uint32_t, uint32_t>, AppTimingData, PairHash<uint32_t, uint32_t>>& timingDataByFrameId, uint32_t processId, uint32_t appFrameId, uint64_t presentStartTime, std::function<uint64_t(const AppTimingData&)> timingSelector);
AppTimingData* ExtractAppTimingData(std::unordered_map<std::pair<uint32_t, uint32_t>, AppTimingData, PairHash<uint32_t, uint32_t>>& timingDataByFrameId,
uint32_t processId, uint32_t appFrameId, uint64_t presentStartTime, uint64_t presentStopTime,
std::function<uint64_t(const AppTimingData&)> timingSelector, bool isPcLatency = true);
bool IsApplicationPresent(std::shared_ptr<PresentEvent> const& present);
void SetAppTimingDataAsComplete(uint32_t processId, uint32_t appFrameId);

Expand Down