pub struct MpvRenderContext {
ctx: *mut mpv_render_context,
gl: Gl,
target: Option<Target>,
}Expand description
mpv’s render context plus the framebuffer it draws into.
§Lifetime (DR-232)
The render context must not outlive the GL context it was created against.
Drop unregisters mpv’s update callback before freeing the context, so a
callback cannot land on a freed pointer, and frees the GL objects while the
caller still has the context current. The caller is responsible for making
the GL context current around both creation and drop — see video_surface.
This is DR-184 on Android restated: a surface outliving its player. The spike had no defence at all and saw one unexplained SIGSEGV in a decoder thread.
Fields§
§ctx: *mut mpv_render_context§gl: Gl§target: Option<Target>Implementations§
Source§impl MpvRenderContext
impl MpvRenderContext
Sourcepub unsafe fn new(mpv: *mut mpv_handle) -> Option<Self>
pub unsafe fn new(mpv: *mut mpv_handle) -> Option<Self>
Create a render context over an existing mpv handle.
The GL context must already be current on this thread.
TRACES: UR-080 | DR-231, IR-033
Sourcepub unsafe fn set_update_callback(
&mut self,
callback: mpv_render_update_fn,
ctx: *mut c_void,
)
pub unsafe fn set_update_callback( &mut self, callback: mpv_render_update_fn, ctx: *mut c_void, )
Ask to be told when a new frame is ready.
Paired with report_swap: without both, mpv has
nothing to time against. The symptom is misleading — playback looks fine
in a window and judders at fullscreen, which reads as a compositing or
GPU limit and is neither (DR-233).
TRACES: UR-080 | DR-233
Sourcepub unsafe fn has_frame(&self) -> bool
pub unsafe fn has_frame(&self) -> bool
Whether mpv has a new frame waiting.
Asked of mpv directly rather than inferred from its update callback, and that distinction is the whole of frame pacing here:
- Waiting only on the callback deadlocks — mpv will not progress until the client renders, so if the client will not render until mpv says so, neither moves. That presents as a file that loads, shows one frame, and then sits silent.
- Rendering on every frame-clock tick regardless is the opposite
error:
report_swapthen claims a presentation far more often than real frames exist, mpv has nothing coherent to time against, and playback judders badly.
Polling is neither. It runs on the main thread, costs a single atomic read inside mpv, and answers the only question that matters.
TRACES: UR-080 | DR-233
Sourcepub unsafe fn render(&mut self, width: i32, height: i32) -> Option<u32>
pub unsafe fn render(&mut self, width: i32, height: i32) -> Option<u32>
Render the current frame at width x height, returning the texture id
holding it. The GL context must be current.
TRACES: UR-080 | DR-231
Sourcepub unsafe fn report_swap(&self)
pub unsafe fn report_swap(&self)
Tell mpv the frame reached the screen. See [set_update_callback].
TRACES: UR-080 | DR-233
Sourceunsafe fn ensure_target(&mut self, width: i32, height: i32) -> Option<()>
unsafe fn ensure_target(&mut self, width: i32, height: i32) -> Option<()>
Create or resize the framebuffer. Reused across frames — reallocating per frame would churn GPU memory at the display rate.