1// Copyright (c) 2016-2018 Google Inc. This work is licensed under a 2// Creative Commons Attribution 4.0 International License; see 3// http://creativecommons.org/licenses/by/4.0/ 4 5== Display Timing Queries 6 7Traditional game and real-time-animation applications frequently use 8ename:VK_PRESENT_MODE_FIFO_KHR so that presentable images are updated during 9the vertical blanking period of a given refresh cycle (RC) of the 10presentation engine's display. 11This avoids the visual anomaly known as tearing. 12 13However, synchronizing the presentation of images with the RC does not 14prevent all forms of visual anomalies. 15Stuttering occurs when the geometry for each presentable image isn't 16accurately positioned for when that image will be displayed. 17The geometry may appear to move too little some RCs, and too much for 18others. 19Sometimes the animation appears to freeze, when the same image is used for 20more than one RC. 21 22In order to minimize stuttering, an application needs to correctly position 23their geometry for when the presentable image will be displayed to the user. 24To accomplish this, applications need various timing information about the 25presentation engine's display. 26They need to know when presentable images were actually presented, and when 27they could have been presented. 28Applications also need to tell the presentation engine to display an image 29no sooner than a given time. 30This can allow the application's animation to look smooth to the user, with 31no stuttering. 32The `VK_GOOGLE_display_timing` extension allows an application to satisfy 33these needs. 34 35The presentation engine's display typically refreshes the pixels that are 36displayed to the user on a periodic basis. 37The period may be fixed or variable. 38In many cases, the presentation engine is associated with fixed refresh rate 39(FRR) display technology, with a fixed refresh rate (RR, e.g. 60Hz). 40In some cases, the presentation engine is associated with variable refresh 41rate (VRR) display technology, where each refresh cycle (RC) can vary in 42length. 43This extension treats VRR displays as if they are FRR. 44 45[open,refpage='vkGetRefreshCycleDurationGOOGLE',desc='Obtain the RC duration of the PE\'s display',type='protos'] 46-- 47 48To query the duration of a refresh cycle (RC) for the presentation engine's 49display, call: 50 51include::../../api/protos/vkGetRefreshCycleDurationGOOGLE.txt[] 52 53 * pname:device is the device associated with pname:swapchain. 54 * pname:swapchain is the swapchain to obtain the refresh duration for. 55 * pname:pDisplayTimingProperties is a pointer to an instance of the 56 sname:VkRefreshCycleDurationGOOGLE structure. 57 58include::../../validity/protos/vkGetRefreshCycleDurationGOOGLE.txt[] 59-- 60 61[open,refpage='VkRefreshCycleDurationGOOGLE',desc='Structure containing the RC duration of a display',type='structs'] 62-- 63 64The sname:VkRefreshCycleDurationGOOGLE structure is defined as: 65 66include::../../api/structs/VkRefreshCycleDurationGOOGLE.txt[] 67 68 * pname:refreshDuration is the number of nanoseconds from the start of one 69 refresh cycle to the next. 70 71include::../../validity/structs/VkRefreshCycleDurationGOOGLE.txt[] 72 73-- 74 75[NOTE] 76.Note 77==== 78The rate at which an application renders and presents new images is known as 79the image present rate (IPR, aka frame rate). 80The inverse of IPR, or the duration between each image present, is the image 81present duration (IPD). 82In order to provide a smooth, stutter-free animation, an application will 83want its IPD to be a multiple of pname:refreshDuration. 84For example, if a display has a 60Hz refresh rate, pname:refreshDuration 85will be a value in nanoseconds that is approximately equal to 16.67ms. 86In such a case, an application will want an IPD of 16.67ms (1X multiplier of 87pname:refreshDuration), or 33.33ms (2X multiplier of pname:refreshDuration), 88or 50.0ms (3X multiplier of pname:refreshDuration), etc. 89 90In order to determine a target IPD for a display (i.e. a multiple of 91pname:refreshDuration), an application needs to determine when its images 92are actually displayed. 93Let's say that an application has an initial target IPD of 16.67ms (1X 94multiplier of pname:refreshDuration). 95It will therefore position the geometry of a new image 16.67ms later than 96the previous image. 97Let's say that this application is running on slower hardware, so that it 98actually takes 20ms to render each new image. 99This will create visual anomalies, because the images won't be displayed to 100the user every 16.67ms, nor every 20ms. 101In this case, it is better for the application to adjust its target IPD to 10233.33ms (i.e. a 2X multiplier of pname:refreshDuration), and tell the 103presentation engine to not present images any sooner than every 33.33ms. 104This will allow the geometry to be correctly positioned for each presentable 105image. 106 107Adjustments to an application's IPD may be needed because different views of 108an application's geometry can take different amounts of time to render. 109For example, looking at the sky may take less time to render than looking at 110multiple, complex items in a room. 111In general, it is good to not frequently change IPD, as that can cause 112visual anomalies. 113Adjustments to a larger IPD because of late images should happen quickly, 114but adjustments to a smaller IPD should only happen if the 115pname:actualPresentTime and pname:earliestPresentTime members of the 116slink:VkPastPresentationTimingGOOGLE structure are consistently different, 117and if pname:presentMargin is consistently large, over multiple images. 118==== 119 120[open,refpage='vkGetPastPresentationTimingGOOGLE',desc='Obtain timing of a previously-presented image',type='protos'] 121-- 122 123The implementation will maintain a limited amount of history of timing 124information about previous presents. 125Because of the asynchronous nature of the presentation engine, the timing 126information for a given flink:vkQueuePresentKHR command will become 127available some time later. 128These time values can be asynchronously queried, and will be returned if 129available. 130All time values are in nanoseconds, relative to a monotonically-increasing 131clock (e.g. `CLOCK_MONOTONIC` (see clock_gettime(2)) on Android and Linux). 132 133To asynchronously query the presentation engine, for newly-available timing 134information about one or more previous presents to a given swapchain, call: 135 136include::../../api/protos/vkGetPastPresentationTimingGOOGLE.txt[] 137 138 * pname:device is the device associated with pname:swapchain. 139 * pname:swapchain is the swapchain to obtain presentation timing 140 information duration for. 141 * pname:pPresentationTimingCount is a pointer to an integer related to the 142 number of sname:VkPastPresentationTimingGOOGLE structures to query, as 143 described below. 144 * pname:pPresentationTimings is either `NULL` or a pointer to an array of 145 sname:VkPastPresentationTimingGOOGLE structures. 146 147If pname:pPresentationTimings is `NULL`, then the number of newly-available 148timing records for the given pname:swapchain is returned in 149pname:pPresentationTimingCount. 150Otherwise, pname:pPresentationTimingCount must: point to a variable set by 151the user to the number of elements in the pname:pPresentationTimings array, 152and on return the variable is overwritten with the number of structures 153actually written to pname:pPresentationTimings. 154If the value of pname:pPresentationTimingCount is less than the number of 155newly-available timing records, at most pname:pPresentationTimingCount 156structures will be written. 157If pname:pPresentationTimingCount is smaller than the number of 158newly-available timing records for the given pname:swapchain, 159ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS to indicate 160that not all the available values were returned. 161 162include::../../validity/protos/vkGetPastPresentationTimingGOOGLE.txt[] 163-- 164 165[open,refpage='VkPastPresentationTimingGOOGLE',desc='Structure containing timing information about a previously-presented image',type='structs'] 166-- 167 168The sname:VkPastPresentationTimingGOOGLE structure is defined as: 169 170include::../../api/structs/VkPastPresentationTimingGOOGLE.txt[] 171 172 * pname:presentID is an application-provided value that was given to a 173 previous fname:vkQueuePresentKHR command via 174 slink:VkPresentTimeGOOGLE::pname:presentID (see below). 175 It can: be used to uniquely identify a previous present with the 176 flink:vkQueuePresentKHR command. 177 * pname:desiredPresentTime is an application-provided value that was given 178 to a previous flink:vkQueuePresentKHR command via 179 slink:VkPresentTimeGOOGLE::pname:desiredPresentTime. 180 If non-zero, it was used by the application to indicate that an image 181 not be presented any sooner than pname:desiredPresentTime. 182 * pname:actualPresentTime is the time when the image of the 183 pname:swapchain was actually displayed. 184 * pname:earliestPresentTime is the time when the image of the 185 pname:swapchain could have been displayed. 186 This may: differ from pname:actualPresentTime if the application 187 requested that the image be presented no sooner than 188 slink:VkPresentTimeGOOGLE::pname:desiredPresentTime. 189 * pname:presentMargin is an indication of how early the 190 fname:vkQueuePresentKHR command was processed compared to how soon it 191 needed to be processed, and still be presented at 192 pname:earliestPresentTime. 193 194The results for a given pname:swapchain and pname:presentID are only 195returned once from fname:vkGetPastPresentationTimingGOOGLE. 196 197The application can: use the fname:VkPastPresentationTimingGOOGLE values to 198occasionally adjust its timing. 199For example, if pname:actualPresentTime is later than expected (e.g. one 200pname:refreshDuration late), the application may increase its target IPD to 201a higher multiple of pname:refreshDuration (e.g. decrease its frame rate 202from 60Hz to 30Hz). 203If pname:actualPresentTime and pname:earliestPresentTime are consistently 204different, and if pname:presentMargin is consistently large enough, the 205application may decrease its target IPD to a smaller multiple of 206pname:refreshDuration (e.g. increase its frame rate from 30Hz to 60Hz). 207If pname:actualPresentTime and pname:earliestPresentTime are same, and if 208pname:presentMargin is consistently high, the application may delay the 209start of its input-render-present loop in order to decrease the latency 210between user input and the corresponding present (always leaving some margin 211in case a new image takes longer to render than the previous image). 212An application that desires its target IPD to always be the same as 213pname:refreshDuration, can also adjust features until 214pname:actualPresentTime is never late and pname:presentMargin is 215satisfactory. 216 217-- 218 219The full `VK_GOOGLE_display_timing` extension semantics are described for 220swapchains created with ename:VK_PRESENT_MODE_FIFO_KHR. 221For example, non-zero values of 222sname:VkPresentTimeGOOGLE::pname:desiredPresentTime must: be honored, and 223fname:vkGetPastPresentationTimingGOOGLE should: return a 224sname:VkPastPresentationTimingGOOGLE structure with valid values for all 225images presented with fname:vkQueuePresentKHR. 226The semantics for other present modes are as follows: 227 228 * ename:VK_PRESENT_MODE_IMMEDIATE_KHR. 229 The presentation engine may: ignore non-zero values of 230 sname:VkPresentTimeGOOGLE::pname:desiredPresentTime in favor of 231 presenting immediately. 232 The value of 233 sname:VkPastPresentationTimingGOOGLE::pname:earliestPresentTime must: be 234 the same as 235 sname:VkPastPresentationTimingGOOGLE::pname:actualPresentTime, which 236 should: be when the presentation engine displayed the image. 237 * ename:VK_PRESENT_MODE_MAILBOX_KHR. 238 The intention of using this present mode with this extension is to 239 handle cases where an image is presented late, and the next image is 240 presented soon enough to replace it at the next vertical blanking 241 period. 242 For images that are displayed to the user, the value of 243 sname:VkPastPresentationTimingGOOGLE::pname:actualPresentTime must: be 244 when the image was displayed. 245 For images that are not displayed to the user, 246 fname:vkGetPastPresentationTimingGOOGLE may: not return a 247 sname:VkPastPresentationTimingGOOGLE structure, or it may: return a 248 sname:VkPastPresentationTimingGOOGLE structure with the value of zero 249 for both sname:VkPastPresentationTimingGOOGLE::pname:actualPresentTime 250 and sname:VkPastPresentationTimingGOOGLE::pname:earliestPresentTime. 251 It is possible that an application can: submit images with 252 sname:VkPresentTimeGOOGLE::pname:desiredPresentTime values such that new 253 images may: not be displayed. 254 For example, if sname:VkPresentTimeGOOGLE::pname:desiredPresentTime is 255 far enough in the future that an image is not presented before 256 fname:vkQueuePresentKHR is called to present another image, the first 257 image will not be displayed to the user. 258 If the application continues to do that, the presentation may: not 259 display new images. 260 * ename:VK_PRESENT_MODE_FIFO_RELAXED_KHR. 261 For images that are presented in time to be displayed at the next 262 vertical blanking period, the semantics are identical as for 263 ename:VK_PRESENT_MODE_FIFO_RELAXED_KHR. 264 For images that are presented late, and are displayed after the start of 265 the vertical blanking period (i.e. with tearing), the values of 266 sname:VkPastPresentationTimingGOOGLE may: be treated as if the image was 267 displayed at the start of the vertical blanking period, or may: be 268 treated the same as for ename:VK_PRESENT_MODE_IMMEDIATE_KHR. 269