The pseudo code was just meant to show the type of call required to make it wait. If I take away the call to draw the point then it stalls instead on the next loop at the first draw call inside drawing the UI. Since it is always the first draw after the present that blocks for 16.67ms (in the case of 60Hz) and all other calls are as good as instant led me to believe it must be waiting on the v-sync. With the Direct3D 11 it is always the RenderPresent that blocks. Only METAL was behaving differently.
Actually what I was trying to achieve was smooth video playback where the video framerate matches the refresh rate. By knowing when the v-sync occurs, I can ensure video frames are scheduled to be presented midway between two successive v-syncs. This means small amounts of variation in the time taken to get the next frame, draw the UI etc, don’t end up causing the video frame to miss the v-sync which is what happens if I don’t do this and the frame presentation times happen to be too close to the v-sync boundaries. Then you get some judder caused by dropped or duplicated frames.
By adding the draw point at the end of present, I know that after that it has just completed a v-sync, and I can calibrate things more easily. I know that each loop starts at time zero after the last vsync. I have a timer and I would reset it here. I guess I could instead reset the timer after the next draw in the next loop but this might not always be in the same place, depending on what needed drawing for the UI, and this would then also become wrong on, for example, D3D where RenderPresent does indeed seem to block for the vsync. In my local copy of SDL2 I have activated the command encoder at the end of METAL_Present and that gives me consistent behaviour across platforms (and what I envisaged SDL2 doing in the first place - but point totally taken re: METAL best practices).
Although from what you are saying, the delay doesn’t necessarily mean it waited for a v-sync? Which is odd, because it still fixes the issue I was having…