| 1036 | } |
| 1037 | |
| 1038 | void DemoUpdateTargetIPD(struct demo *demo) { |
| 1039 | // Look at what happened to previous presents, and make appropriate |
| 1040 | // adjustments in timing: |
| 1041 | VkResult U_ASSERT_ONLY err; |
| 1042 | VkPastPresentationTimingGOOGLE *past = NULL; |
| 1043 | uint32_t count = 0; |
| 1044 | |
| 1045 | err = vkGetPastPresentationTimingGOOGLE(demo->device, demo->swapchain, &count, NULL); |
| 1046 | assert(!err); |
| 1047 | if (count) { |
| 1048 | past = (VkPastPresentationTimingGOOGLE *)malloc(sizeof(VkPastPresentationTimingGOOGLE) * count); |
| 1049 | assert(past); |
| 1050 | err = vkGetPastPresentationTimingGOOGLE(demo->device, demo->swapchain, &count, past); |
| 1051 | assert(!err); |
| 1052 | |
| 1053 | bool early = false; |
| 1054 | bool late = false; |
| 1055 | bool calibrate_next = false; |
| 1056 | for (uint32_t i = 0; i < count; i++) { |
| 1057 | if (!demo->syncd_with_actual_presents) { |
| 1058 | // This is the first time that we've received an |
| 1059 | // actualPresentTime for this swapchain. In order to not |
| 1060 | // perceive these early frames as "late", we need to sync-up |
| 1061 | // our future desiredPresentTime's with the |
| 1062 | // actualPresentTime(s) that we're receiving now. |
| 1063 | calibrate_next = true; |
| 1064 | |
| 1065 | // So that we don't suspect any pending presents as late, |
| 1066 | // record them all as suspected-late presents: |
| 1067 | demo->last_late_id = demo->next_present_id - 1; |
| 1068 | demo->last_early_id = 0; |
| 1069 | demo->syncd_with_actual_presents = true; |
| 1070 | break; |
| 1071 | } else if (CanPresentEarlier(past[i].earliestPresentTime, past[i].actualPresentTime, past[i].presentMargin, |
| 1072 | demo->refresh_duration)) { |
| 1073 | // This image could have been presented earlier. We don't want |
| 1074 | // to decrease the target_IPD until we've seen early presents |
| 1075 | // for at least two seconds. |
| 1076 | if (demo->last_early_id == past[i].presentID) { |
| 1077 | // We've now seen two seconds worth of early presents. |
| 1078 | // Flag it as such, and reset the counter: |
| 1079 | early = true; |
| 1080 | demo->last_early_id = 0; |
| 1081 | } else if (demo->last_early_id == 0) { |
| 1082 | // This is the first early present we've seen. |
| 1083 | // Calculate the presentID for two seconds from now. |
| 1084 | uint64_t lastEarlyTime = past[i].actualPresentTime + (2 * BILLION); |
| 1085 | uint32_t howManyPresents = (uint32_t)((lastEarlyTime - past[i].actualPresentTime) / demo->target_IPD); |
| 1086 | demo->last_early_id = past[i].presentID + howManyPresents; |
| 1087 | } else { |
| 1088 | // We are in the midst of a set of early images, |
| 1089 | // and so we won't do anything. |
| 1090 | } |
| 1091 | late = false; |
| 1092 | demo->last_late_id = 0; |
| 1093 | } else if (ActualTimeLate(past[i].desiredPresentTime, past[i].actualPresentTime, demo->refresh_duration)) { |
| 1094 | // This image was presented after its desired time. Since |
| 1095 | // there's a delay between calling vkQueuePresentKHR and when |
no test coverage detected