1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-16 04:07:08 +00:00
mpv/libmpv
wm4 3ae728532d client API: document unfortunate render API threading requirement
This is because dr_helper.c calls pthread_self(). It's used to avoid
deadlocks. This was not a problem internal to mpv (dr_helper.c was first
created for vo_gpu.c), but it accidentally leaked as an unintended
consequence of an implementation detail to libmpv.

This problem existed for MPV_RENDER_PARAM_ADVANCED_CONTROL users, ever
since it was introduced.

Maybe this could be done differently, but it's certainly very tricky.
the pthread_t is used to avoid deadlocks when the caller is on the same
thread as the one which needs to handle the calls.

The critical code is in free_dr_buffer_on_dr_thread(). It's called when
a DR image is free'd. Freeing a DR image requires access to the GL
context, i.e. it just has to run on the "GL" thread. In libmpv's case,
this is done by calling the API user's wakeup call, and the user will
eventually call mpv_render_context_update() on the "GL" thread, which in
turn calls mp_dispatch_queue_process() on the dispatch queue that was
passed to dr_helper_create(), which then calls av_buffer_unref(), which
calls gl_video_dr_free_buffer(). (God who came up with this rube
goldberg shit.)

The above case will typically happen when e.g. vd_lavc.c (internal mpv
thread) frees images. Allocation works similarly; deallocation is just
trickier because calls to free images are everywhere.

Now consider if mpv_render_context_render() releases a DR image. This
function is always called on the "GL" thread. Going through the dispatch
queue would obviously deadlock, because according to the render API
rules, the user's wakeup callback must not mpv_render_context_update(),
instead it has to signal the "GL" thread, which must wait until
mpv_render_context_render() returns. To avoid this deadlock, dr_helper.c
checks whether the calling thread is the "GL" thread, and if so, allows
a reentrant call (basically gl_video_dr_free_buffer() is called
directly).

While with GL, you usually will stay on the same thread, API users were
in theory allowed to e.g. move the GL context to a different thread. But
this dr_helper issue means this is not possible. Moreover, other APIs
will not have the same thread-locality problems as GL.

FUCK THIS SHIT

In theory, libmpv could provide an API to "move" the context to a
separate thread, but let's not start with even more broken crap like
this. I'm not sure yet whether there is an easy solution. Maybe all
mpv_render() function could be guarded by entry/exit functions, which
set/unset a flag that dr_helper.c should use reentrant calls.

libmpv users which do not set MPV_RENDER_PARAM_ADVANCED_CONTROL were
never affected.
2019-09-20 16:04:18 +02:00
..
client.h client API: fix some comments 2019-09-19 20:37:05 +02:00
mpv.def command: add a way to abort asynchronous commands 2018-05-24 19:56:34 +02:00
mpv.pc.in build: add hacks to force waf to generate valid .pc files 2014-08-07 23:45:40 +02:00
opengl_cb.h drm/atomic: add connector to atomic context 2018-05-01 20:48:02 +03:00
qthelper.hpp client API: deprecate qthelper.hpp 2018-03-15 23:13:53 -07:00
render_gl.h drm: fix libmpv ABI breakage introduced in 351c083487 2019-09-18 23:59:32 +03:00
render.h client API: document unfortunate render API threading requirement 2019-09-20 16:04:18 +02:00
stream_cb.h client API: some doxygen fixes/additions 2018-05-24 19:56:33 +02:00