| 369 | } |
| 370 | |
| 371 | uint32_t PM_DYNAMIC_QUERY::Poll(uint8_t* pBlobBase, ipc::MiddlewareComms& comms, |
| 372 | uint64_t nowTimestamp, FrameMetricsSource* frameSource, uint32_t processId, uint32_t maxSwapChains) const |
| 373 | { |
| 374 | if (pBlobBase == nullptr || maxSwapChains == 0) { |
| 375 | return 0; |
| 376 | } |
| 377 | |
| 378 | const auto window = GenerateQueryWindow_(nowTimestamp); |
| 379 | const bool integrityCheckEnabled = util::log::GlobalPolicy::Get().GetLogLevel() >= util::log::Level::Debug; |
| 380 | |
| 381 | // Validate pending windows from previous polls before polling this window. |
| 382 | if (integrityCheckEnabled) { |
| 383 | ValidatePendingIntegrityWindows_(frameSource, comms, processId, nowTimestamp); |
| 384 | } |
| 385 | |
| 386 | std::vector<uint64_t> swapChainAddresses; |
| 387 | if (frameSource != nullptr) { |
| 388 | swapChainAddresses = frameSource->GetSwapChainAddressesInTimestampRange(window.oldest, window.newest); |
| 389 | } |
| 390 | |
| 391 | const bool snapshotDumpEnabled = util::log::GlobalPolicy::Get().GetLogLevel() >= util::log::Level::Verbose && |
| 392 | util::log::GlobalPolicy::VCheck(util::log::V::middleware); |
| 393 | |
| 394 | std::optional<FrameMetricsSource::PollSnapshotData> pollSnapshots; |
| 395 | if (snapshotDumpEnabled && frameSource != nullptr && frameTimeOrFpsOffset_.has_value()) { |
| 396 | pollSnapshots = frameSource->CapturePollSnapshotData(); |
| 397 | } |
| 398 | |
| 399 | bool sawZeroFrameTimeOrFpsValue = false; |
| 400 | const uint64_t targetStartQpc = GetTargetStartQpc_(comms, processId); |
| 401 | const std::string elapsedSinceTargetStartSecondsText = |
| 402 | BuildElapsedSinceTargetStartText_(targetStartQpc, nowTimestamp, qpcPeriodSeconds_); |
| 403 | |
| 404 | auto dumpSnapshotsIfNeeded = [&]() { |
| 405 | if (!pollSnapshots || !sawZeroFrameTimeOrFpsValue) { |
| 406 | return; |
| 407 | } |
| 408 | size_t totalSwapChainFrameSnapshots = 0; |
| 409 | for (const auto& swapChainSnapshots : pollSnapshots->swapChainSnapshots) { |
| 410 | totalSwapChainFrameSnapshots += swapChainSnapshots.snapshots.size(); |
| 411 | } |
| 412 | |
| 413 | pmlog_verb(util::log::V::middleware)("Dynamic query detected zero frame time/FPS metric and dumped poll snapshots") |
| 414 | .every(std::chrono::milliseconds{ 500 }) |
| 415 | .pmwatch(processId) |
| 416 | .pmwatch(nowTimestamp) |
| 417 | .watch("queryHandle", reinterpret_cast<void*>(const_cast<PM_DYNAMIC_QUERY*>(this))) |
| 418 | .watch("elapsed_since_target_start_s", elapsedSinceTargetStartSecondsText) |
| 419 | .pmwatch(pollSnapshots->ipcStoreSnapshots.size()) |
| 420 | .pmwatch(pollSnapshots->swapChainSnapshots.size()) |
| 421 | .watch("total_swap_chain_frame_snapshots", totalSwapChainFrameSnapshots) |
| 422 | .watch("poll_snapshot_csv", BuildPollSnapshotCsv_(*pollSnapshots)) |
| 423 | .diag(); |
| 424 | }; |
| 425 | |
| 426 | auto pollOnce = [&](const SwapChainState* pSwapChain, uint64_t swapChainAddress, uint8_t* pBlob) { |
| 427 | const bool hasFrameSamples = pSwapChain != nullptr && |
| 428 | pSwapChain->CountInTimestampRange(window.oldest, window.newest) > 0; |
no test coverage detected