Focused follow-up to #2869. The broad API investigation already covers presentation statistics; this issue asks whether a small, feedback-only slice can land first. If maintainers prefer to keep all API discussion in #2869, please close this and I will move the concrete evidence there.
Is your feature request related to a problem? Please describe.
On wgpu 29.0.4, SurfaceTexture::present(self) returns () and the public SurfaceTexture exposes no token that can later be paired with actual presentation. GPU completion and return from present() are both earlier than display presentation, so applications cannot measure frame-specific input-to-display latency or distinguish a displayed frame from a dropped one.
The Metal backend already owns the necessary object: wgpu-hal's private Metal SurfaceTexture retains an MTLDrawable, and Queue::present consumes it through presentDrawable. Metal provides addPresentedHandler, presentedTime, and drawableID, but the current public wgpu boundary cannot reach them.
In a real-window 120 Hz calibration using the current wgpu/Vello surface, the time from SurfaceTexture::present() return to the same CADisplayLink.targetTimestamp was p50 7.613 ms / p95 7.858 ms over 28 valid samples. That fallback only estimates the next display tick; it cannot prove that the particular drawable was shown. The almost-one-tick ambiguity is precisely the information an actual feedback API would remove.
Describe the solution you'd like
A capability-gated, frame-specific feedback API that lets an application associate one presented surface texture with an eventual result such as:
- a stable present ID/token;
Presented { timestamp } or NotPresented/dropped status;
- a timestamp in a documented presentation clock plus a supported way to correlate it with the application's monotonic clock.
The exact Rust shape is open. A future/receiver returned from present, a callback, or a Surface::poll_presentation_feedback() queue could all work as long as feedback stays paired to the submitted SurfaceTexture. For a Metal-first implementation, wgpu-hal could register MTLDrawable.addPresentedHandler before presentDrawable, retain only the minimal ID/result state, and report presentedTime == 0 as not presented.
This request intentionally does not require exposing raw MTLDrawable, predicting or scheduling future presentation, damage rectangles, monitor statistics, or changing surface ownership. Other backends can report the capability as unavailable until they have a reliable implementation.
Describe alternatives you've considered
- GPU completion callbacks: prove GPU work completed, not display presentation.
- Timing
SurfaceTexture::present() return: proves only that the present request returned.
CADisplayLink.targetTimestamp: estimates a display tick but cannot identify which drawable was displayed or whether it was dropped.
- Owning a separate
CAMetalLayer/drawable path: provides feedback but replaces wgpu's single surface owner and is not an acceptable integration for applications that need to keep the standard wgpu surface path.
- Reading private wgpu-hal fields or relying on layout: unsafe and not maintainable.
Additional context
I am happy to adapt the use-case/reporting details to an API direction preferred by maintainers.
Focused follow-up to #2869. The broad API investigation already covers presentation statistics; this issue asks whether a small, feedback-only slice can land first. If maintainers prefer to keep all API discussion in #2869, please close this and I will move the concrete evidence there.
Is your feature request related to a problem? Please describe.
On wgpu 29.0.4,
SurfaceTexture::present(self)returns()and the publicSurfaceTextureexposes no token that can later be paired with actual presentation. GPU completion and return frompresent()are both earlier than display presentation, so applications cannot measure frame-specific input-to-display latency or distinguish a displayed frame from a dropped one.The Metal backend already owns the necessary object:
wgpu-hal's private MetalSurfaceTextureretains anMTLDrawable, andQueue::presentconsumes it throughpresentDrawable. Metal providesaddPresentedHandler,presentedTime, anddrawableID, but the current public wgpu boundary cannot reach them.In a real-window 120 Hz calibration using the current wgpu/Vello surface, the time from
SurfaceTexture::present()return to the sameCADisplayLink.targetTimestampwas p50 7.613 ms / p95 7.858 ms over 28 valid samples. That fallback only estimates the next display tick; it cannot prove that the particular drawable was shown. The almost-one-tick ambiguity is precisely the information an actual feedback API would remove.Describe the solution you'd like
A capability-gated, frame-specific feedback API that lets an application associate one presented surface texture with an eventual result such as:
Presented { timestamp }orNotPresented/dropped status;The exact Rust shape is open. A future/receiver returned from present, a callback, or a
Surface::poll_presentation_feedback()queue could all work as long as feedback stays paired to the submittedSurfaceTexture. For a Metal-first implementation, wgpu-hal could registerMTLDrawable.addPresentedHandlerbeforepresentDrawable, retain only the minimal ID/result state, and reportpresentedTime == 0as not presented.This request intentionally does not require exposing raw
MTLDrawable, predicting or scheduling future presentation, damage rectangles, monitor statistics, or changing surface ownership. Other backends can report the capability as unavailable until they have a reliable implementation.Describe alternatives you've considered
SurfaceTexture::present()return: proves only that the present request returned.CADisplayLink.targetTimestamp: estimates a display tick but cannot identify which drawable was displayed or whether it was dropped.CAMetalLayer/drawable path: provides feedback but replaces wgpu's single surface owner and is not an acceptable integration for applications that need to keep the standard wgpu surface path.Additional context
MTLDrawable.presentedTime: https://developer.apple.com/documentation/metal/mtldrawable/presentedtimeMTLDrawable.addPresentedHandler: https://developer.apple.com/documentation/metal/mtldrawable/addpresentedhandler(_:)wgpu-hal/src/metal/mod.rs, whereSurfaceTextureowns the drawable andQueue::presentcallspresentDrawable.I am happy to adapt the use-case/reporting details to an API direction preferred by maintainers.