| 399 | } |
| 400 | |
| 401 | static void ProcessEvents( |
| 402 | PMTraceSession const& pmSession, |
| 403 | std::vector<std::shared_ptr<PresentEvent>> const& presentEvents, |
| 404 | std::vector<ProcessEvent>* processEvents, |
| 405 | std::vector<uint64_t>* recordingToggleHistory, |
| 406 | bool currentRecordingState) |
| 407 | { |
| 408 | auto const& args = GetCommandLineArgs(); |
| 409 | auto computeAvg = args.mConsoleOutput == ConsoleOutput::Statistics; |
| 410 | |
| 411 | // Determine the recording state and when the next toggle is. |
| 412 | size_t recordingToggleIndex = 0; |
| 413 | size_t recordingToggleCount = recordingToggleHistory->size(); |
| 414 | bool checkRecordingToggle = recordingToggleCount > 0; |
| 415 | bool isRecording = recordingToggleCount & 1 ? !currentRecordingState : currentRecordingState; |
| 416 | |
| 417 | // Determine if there are process events to check. |
| 418 | size_t processEventIndex = 0; |
| 419 | size_t processEventCount = processEvents->size(); |
| 420 | bool checkProcessTime = processEventCount > 0; |
| 421 | |
| 422 | const uint64_t qpcFrequency = static_cast<uint64_t>(pmSession.mTimestampFrequency.QuadPart); |
| 423 | const uint64_t qpcStart = static_cast<uint64_t>(pmSession.mStartTimestamp.QuadPart); |
| 424 | pmon::util::QpcConverter qpc(qpcFrequency, qpcStart); |
| 425 | |
| 426 | // Iterate through the processEvents, handling process events and recording toggles along the |
| 427 | // way. |
| 428 | uint64_t presentTime = 0; |
| 429 | for (auto const& presentEvent : presentEvents) { |
| 430 | |
| 431 | // Ignore failed and lost presents. |
| 432 | if (presentEvent->IsLost || presentEvent->PresentFailed) { |
| 433 | continue; |
| 434 | } |
| 435 | |
| 436 | // Look up the process this present belongs to. If the process info doesn't exist yet, |
| 437 | // handle process events first and then check again. |
| 438 | ProcessInfo* processInfo = nullptr; |
| 439 | SwapChainData* chain = nullptr; |
| 440 | if (GetPresentProcessInfo(presentEvent, false, &processInfo, &chain, &presentTime)) { |
| 441 | continue; |
| 442 | } |
| 443 | |
| 444 | // Handle any process events that occurred before this present |
| 445 | if (checkProcessTime) { |
| 446 | while ((*processEvents)[processEventIndex].QpcTime < presentTime) { |
| 447 | auto& processEvent = (*processEvents)[processEventIndex]; |
| 448 | |
| 449 | // If this is a termination event for the same process as the current present, |
| 450 | // skip processing this termination to avoid removing the process info we need |
| 451 | if (!processEvent.IsStartEvent && processEvent.ProcessId == presentEvent->ProcessId) { |
| 452 | // Don't process this termination yet - we have a present from this process to handle first |
| 453 | break; |
| 454 | } |
| 455 | |
| 456 | ProcessProcessEvent((*processEvents)[processEventIndex]); |
| 457 | processEventIndex += 1; |
| 458 | if (processEventIndex == processEventCount) { |
no test coverage detected