| 3668 | } |
| 3669 | |
| 3670 | AppTimingData* PMTraceConsumer::ExtractAppTimingData( |
| 3671 | std::unordered_map<std::pair<uint32_t, uint32_t>, AppTimingData, PairHash<uint32_t, uint32_t>>& timingDataByFrameId, |
| 3672 | uint32_t processId, uint32_t appFrameId, uint64_t presentStartTime, std::function<uint64_t(const AppTimingData&)> timingSelector) { |
| 3673 | if (appFrameId != 0) { |
| 3674 | // If the incoming app frame id is already assigned then we receiving |
| 3675 | // the information from version 2 of the PresentFrameType event. |
| 3676 | auto key = std::make_pair(appFrameId, processId); |
| 3677 | auto ii = timingDataByFrameId.find(key); |
| 3678 | if (ii != timingDataByFrameId.end()) { |
| 3679 | ii->second.AssignedToPresent = true; |
| 3680 | ii->second.PresentCompleted = false; |
| 3681 | return &ii->second; |
| 3682 | } |
| 3683 | } else { |
| 3684 | auto itToReturn = timingDataByFrameId.end(); |
| 3685 | uint32_t earlierFrameId = std::numeric_limits<uint32_t>::max(); |
| 3686 | uint64_t smallestPresentStartDelta = std::numeric_limits<uint64_t>::max(); |
| 3687 | // Search for the timing data with the closest PresentStartTime to the passed |
| 3688 | // in PresentStartTime that has not been assigned. This is a hack and will not work for x-platform. |
| 3689 | for (auto it = timingDataByFrameId.begin(); it != timingDataByFrameId.end(); ++it) { |
| 3690 | if (it->first.second == processId) { |
| 3691 | if (it->second.AssignedToPresent == false) { |
| 3692 | uint64_t timingValue = timingSelector(it->second); |
| 3693 | if (timingValue != 0 && timingValue < presentStartTime) { |
| 3694 | auto tempPresentStartDelta = presentStartTime - timingValue; |
| 3695 | if (tempPresentStartDelta < smallestPresentStartDelta) { |
| 3696 | smallestPresentStartDelta = tempPresentStartDelta; |
| 3697 | earlierFrameId = it->first.first; |
| 3698 | itToReturn = it; |
| 3699 | } |
| 3700 | } |
| 3701 | } |
| 3702 | } |
| 3703 | } |
| 3704 | |
| 3705 | // If we found the app timing data and if the Present it is attached is not completed return |
| 3706 | // the data |
| 3707 | if (itToReturn != timingDataByFrameId.end() && itToReturn->second.PresentCompleted != true) { |
| 3708 | itToReturn->second.AssignedToPresent = true; |
| 3709 | return &itToReturn->second; |
| 3710 | } |
| 3711 | } |
| 3712 | |
| 3713 | return nullptr; // No frame found |
| 3714 | } |
| 3715 | |
| 3716 | bool PMTraceConsumer::IsApplicationPresent(std::shared_ptr<PresentEvent> const& present) { |
| 3717 | DebugAssert(present->Displayed.size() <= 1); |