summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/context_wayland.c
Commit message (Collapse)AuthorAgeFilesLines
* wayland: conditionally commit surface on resizeDudemanguy2020-08-201-0/+2
| | | | | | | | | | | | | | | | | | | | | It was possible for sway to get incorrectly sized borders if you resized the mpv window in a creative manner (e.g. open a video in a non-floating mode, set window scale to 2, then float it and witness wrong border sizes). This is possibly a sway bug (Plasma doesn't have these border issues at least), but there's a reasonable workaround for this. The reason for the incorrect border size is because it is possible for mpv to ignore the width/height from the toplevel listener and set its own size. This new size can differ from what sway/wlroots believes the size is which is what causes the sever side decorations to be drawn on incorrect dimensions. A simple trick is to just explicitly commit the surface after a resize is performed. This is only done if mpv is not fullscreened or maximized since we always obey the compositor widths/heights in those cases. Sending the commit signals the compositor of the new change in the surface and thus sway/wlroots updates its internal coordinates appropriately and borders are no longer broken.
* wayland: don't rely on presentation discardedDudemanguy2020-08-161-3/+0
| | | | | | | | | | | | | When using presentation time, we have to be sure to update the ust when no presentation events are received to make sure playback is still smooth and in sync. Part of the recent presentation time refactor was to use the presentation discarded event to signal that the window is hidden. Evidently, this doesn't work the same everywhere for whatever reason (drivers?? hardware??) and at least one user experienced issues with playback getting out of sync since (presumably) the discarded event didn't occur when hiding the window. Instead, let's just go back to the old way of checking if the last_ust is equal to the ust value of the last member in the wayland sync queue. Fixes #8010.
* wayland: refactor presentation timeDudemanguy2020-08-161-30/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The motivation for this change was a segfault caused by e107342 which has complicated reasons for occuring (i.e. I'm not 100% sure but I think it is a really weird race). The major part of this commit is moving the initialization of presentation listener to the frame_callback function. Calling it in swap_buffers worked fine but in practice it meant a lot of meaningless function calls if a window was hidden (the presentation would just be immediately discarded). By calling it in frame_callback, we ensure the listener is only created when it is possible to receive a presentation event. Of course calling the presentation listener in feedback_presented or feedback_discarded was considered, but ultimately these events are too slow. Receiving the ust/msc/sbc triplet here and then passing it to mpv results in higher vsync judder since there is (likely) not enough time before the next pageflip. By design, the frame callback is meant to give us as much time as possible before the next repaint so calling it here is probably optimal. Additionally, we can make better use of the feedback_discarded event. The wp_presentation_feedback should not be destroyed here. It will be taken care of either when we get feedback again or when the player quits. Instead what we can do is set a bool that tells wayland_sync_swap to update itself based on mp_time delta. In practice, the result is not any different than before, but it should be more understandable what is going on now. Of course, the segfault mentioned at the beginning is fixed with this as well.
* wayland: fix buildwm42020-06-041-1/+1
| | | | | | Broken by previous commit. I've split a commit incorrectly. Fixes: #7802
* wayland: use mp_time deltas for presentation timeDudemanguy2020-04-201-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | One not-so-nice hack in the wayland code is the assumption of when a window is hidden (out of view from the compositor) and an arbitrary delay for enabling/disabling the usage of presentation time. Since you do not receive any presentation feedback when a window is hidden on wayland (a feature or misfeature depending on who you ask), the ust is updated based on the refresh_nsec statistic gathered from the previous feedback event. The flaw with this is that refresh_nsec basically just reports back the display's refresh rate (1 / refresh_rate * 10^9). It doesn't tell you how long the vsync interval really was. So as a video is left playing out of view, the wl->last_queue_display_time becomes increasingly inaccurate. This led to a vsync spike when bringing the mpv window back into sight after it was hidden for a period of time. The hack for working around this is to just wait a while before enabling presentation time again. The discrepancy between the "bogus" wl->last_queue_display_time and the actual value you get from the feedback only happens initially after a switch. If you just discard those values, you avoid the dramatic vsync spike. It turns out that there's a smarter way to do this. Just use mp_time_us deltas. The whole reason for these hacks is because wl->last_queue_display_time wasn't close enough to how long it would take for a frame to actually display if it wasn't hidden. Instead, mpv's internal timer can be used, and the difference between wayland_sync_swap calls is a close enough proxy for the vsync interval (certainly better than using the monitor's refresh rate). This avoids the entire conundrum of massive vsync spikes when bringing the player back into view, and it means we can get rid of extra crap like wl->hidden.
* wayland: remove wayland-frame-wait-offset optiondudemanguy2020-01-311-1/+1
| | | | | | | | | | | | | | | | | This originally existed as a hack for weston. In certain scenarios, a frame taking too long to render would cause vo_wayland_wait_frame to timeout which would result in a ton of dropped frames. The naive solution was to just to add a slight delay to the time value. If a frame took too long, it would likely to fall under the timeout value and all was well. This was exposed to the user since the default delay (1000) was completely arbitrary. However with presentation time, this doesn't appear to be neccesary. Fresh frames that take longer than the display's refresh rate (16.666 ms in most cases) behave well in Weston. In the other two main compositors without presentation time (GNOME and Plasma), they also do not experience any ill effects. It's better not to overcomplicate things, so this "feature" can be removed now.
* vo_gpu: opengl: make it work with EGL 1.4wm42019-12-161-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This tries to deal with the crazy EGL situation. The summary is: - using eglGetDisplay() with multiple windowing platforms doesn't really work, but Mesa had an awful hack for it - this hack can be disabled at build time, and some distros sometimes accidentally or intentionally do so - Mesa will probably eventually disable it by default - we switched to eglGetPlatformDisplay(), but this requires EGL 1.5 - the very regrettable graphics company (also known as Nvidia) ships drivers (for old hardware I think) that are EGL 1.4 only - that means even though we "require" EGL 1.5 and link against it, the runtime EGL may be 1.4 - trying to run mpv there crashes in the dynamic linker - so we have to go through some more awful compatibility hacks This commit tries to do it "properly", but using EGL 1.4 as base. The plaform selection mechanism is a messy extension there, which got elevated to core API in 1.5 (but OF COURSE in incompatible ways). I'm not sure whether the EGL 1.5 code path (by parsing the EGL_VERSION) is really needed, but if you ask me, it feels slightly saner not to rely on an EGL 1.4 kludge forever. But maybe this is just an instance of self-harm, since they will most likely never drop or not provide this API. Also, unlike before, we actually check the extension string for the individual platform extensions, because who knows, some EGL implementations might curse us if we pass unknown platform parameters. (But actually, the more I think about this, the more bullshit it is.) X11 and Wayland were the only ones trying to call eglGetPlatformDisplay, so they're the only ones which are adjusted in this commit. Unfortunately, correct function of this commit is unconfirmed. It's possible that it crashes with the old drivers mentioned above. Why didn't they solve it like this: struct native_display { int platform_type; void *native_display; }; Could have kept eglGetDisplay() without all the obnoxious extension BS.
* wayland: use eglGetPlatformDisplay()Dudemanguy2019-11-161-1/+2
| | | | | See aacc194. The same logic all applies to Wayland. In fact, we already require EGL 1.5 for wayland anyway, so it's better to do it right.
* wayland: fix presentation timeDudemanguy9112019-10-201-1/+1
| | | | | | | | | | There's 2 stupid things here that need to be fixed. First of all, vulkan wasn't actually using presentation time because somehow the get_vsync function in context.c disappeared. Secondly, if the mpv window was hidden it was updating the ust time based on the refresh_usec but really it should simply just not feed any information to the vsync info structure. So this adds some logic to assume whether or not a window is hidden.
* wayland: add various render-related optionsdudemanguy2019-10-201-1/+2
| | | | | The newest wayland changes have some new logic that make sense to expose to users as configurable options.
* wayland: add presentation timedudemanguy2019-10-201-2/+78
| | | | | Use ust/msc/refresh values from wayland's presentation time in mpv's ra_swapchain_fns.get_vsync for the wayland contexts.
* wayland: use callback flag + poll for buffer swapdudemanguy2019-10-101-0/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The old way of using wayland in mpv relied on an external renderloop for semi-accurate timings. This had multiple issues though. Display sync would break whenever the window was hidden (since the frame callback stopped being executed) which was really annoying. Also the entire external renderloop logic was kind of fragile and didn't play well with mpv's internal structure (i.e. using presentation time in that old paradigm breaks stats.lua). Basically the problem is that swap buffers blocks on wayland which is crap whenever you hide the mpv window since it looks up the entire player. So you have to make swap buffers not block, but this has a different problem. Timings will be terrible if you use the unblocked swap buffers call. Based on some discussion in #wayland, the trick here is relatively simple and works well enough for our purposes. Instead we basically build a way to block with a timeout in the wayland buffer swap functions. A bool is set in the frame callback function that indicates whether or not mpv is waiting for a frame to be displayed. In the actual buffer swap function, we enter into a while loop waiting for this flag to be set. At the same time, the wl_display is polled to block the thread and wakeup if it receives any events from the compositor. This loop only breaks if enough time has passed or if the frame callback bool is received. In the near future, it is better to set whether or not frame a frame has been displayed in the presentation feedback. However as a first pass, doing it in the frame callback is more than good enough. The "downside" is that we render frames that aren't actually shown on screen when the player is hidden (it seems like wayland people don't like that). But who cares. Accurate timings are way more important. It's probably not too hard to add that behavior back in the player though.
* wayland opengl: actually call uninit if init failsdudemanguy2019-10-031-1/+3
| | | | | | | | This is the proper fix to the memory leak @wm4 pointed out. It turns out that when you autoprobe opengl and vo_wayland_init returns false, vo_wayland_uninit is never actually executed. So you have a leftover pointer. The vulkan context does this correctly which was why my old, dumb "fix" broke it.
* opengl/context_wayland: Fix crash on configure before initial reconfigMichael Forney2019-07-081-1/+3
| | | | | | | | | If the compositor sends a configure event before the surface is initially mapped, resize gets called before the egl_window gets created, resulting in a crash in wl_egl_window_resize. This was fixed back in 618361c697, but was reintroduced when the wayland code was rewritten in 68f9ee7e0b.
* client API: add a new way to pass X11 Display etc. to render APIwm42018-03-261-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hardware decoding things often need access to additional handles from the windowing system, such as the X11 or Wayland display when using vaapi. The opengl-cb had nothing dedicated for this, and used the weird GL_MP_MPGetNativeDisplay GL extension (which was mpv specific and not officially registered with OpenGL). This was awkward, and a pain due to having to emulate GL context behavior (like needing a TLS variable to store context for the pseudo GL extension function). In addition (and not inherently due to this), we could pass only one resource from mpv builtin context backends to hwdecs. It was also all GL specific. Replace this with a newer mechanism. It works for all RA backends, not just GL. the API user can explicitly pass the objects at init time via mpv_render_context_create(). Multiple resources are naturally possible. The API uses MPV_RENDER_PARAM_* defines, but internally we use strings. This is done for 2 reasons: 1. trying to leave libmpv and internal mechanisms decoupled, 2. not having to add public API for some of the internal resource types (especially D3D/GL interop stuff). To remain sane, drop support for obscure half-working opengl-cb things, like the DRM interop (was missing necessary things), the RPI window thing (nobody used it), and obscure D3D interop things (not needed with ANGLE, others were undocumented). In order not to break ABI and the C API, we don't remove the associated structs from opengl_cb.h. The parts which are still needed (in particular DRM interop) needs to be ported to the render API.
* wayland_common: implement output tracking, cleanups and bugfixesRostislav Pehlivanov2017-10-091-5/+1
| | | | | | | | | | | | | | | | | | This commit: - Implements output tracking (e.g. monitor plug/unplug) - Creates the surface during registry (no other dependencies) - Queues the callback immediately after surface creation - Cleaner and better event handling (functions return directly) - Better reconfigure handling (resizes reduced to 1 during init) - Don't unnecessarily resize (if dimensions match) Apart from that fixes 2 potential memory leaks (mime type and window title), 2 string ownership issues (output name and make need to be dup'd), fixes some style issues (switches were indented) and finally adds messages when disabling/enabling idle inhibition. The callback setter function was removed in preparation for the commit which will use the frame event cb because it was unnecessary.
* wayland_common: rewrite from scratchRostislav Pehlivanov2017-10-031-110/+83
| | | | | | | | | | | | The wayland code was written more than 4 years ago when wayland wasn't even at version 1.0. This commit rewrites everything in a more modern way, switches to using the new xdg v6 shell interface which solves a lot of bugs and makes mpv tiling-friedly, adds support for drag and drop, adds support for touchscreens, adds support for KDE's server decorations protocol, and finally adds support for the new idle-inhibitor protocol. It does not yet use the frame callback as a main rendering loop driver, this will happen with a later commit.
* vo_opengl: refactor into vo_gpuNiklas Haas2017-09-211-33/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is done in several steps: 1. refactor MPGLContext -> struct ra_ctx 2. move GL-specific stuff in vo_opengl into opengl/context.c 3. generalize context creation to support other APIs, and add --gpu-api 4. rename all of the --opengl- options that are no longer opengl-specific 5. move all of the stuff from opengl/* that isn't GL-specific into gpu/ (note: opengl/gl_utils.h became opengl/utils.h) 6. rename vo_opengl to vo_gpu 7. to handle window screenshots, the short-term approach was to just add it to ra_swchain_fns. Long term (and for vulkan) this has to be moved to ra itself (and vo_gpu altered to compensate), but this was a stop-gap measure to prevent this commit from getting too big 8. move ra->fns->flush to ra_gl_ctx instead 9. some other minor changes that I've probably already forgotten Note: This is one half of a major refactor, the other half of which is provided by rossy's following commit. This commit enables support for all linux platforms, while his version enables support for all non-linux platforms. Note 2: vo_opengl_cb.c also re-uses ra_gl_ctx so it benefits from the --opengl- options like --opengl-early-flush, --opengl-finish etc. Should be a strict superset of the old functionality. Disclaimer: Since I have no way of compiling mpv on all platforms, some of these ports were done blindly. Specifically, the blind ports included context_mali_fbdev.c and context_rpi.c. Since they're both based on egl_helpers, the port should have gone smoothly without any major changes required. But if somebody complains about a compile error on those platforms (assuming anybody actually uses them), you know where to complain.
* vo_opengl: add a generic EGL function loader functionwm42017-04-061-5/+1
| | | | | | | This is pretty trivial, but also quite annoying due to details like mismatching eglGetProcAddress() function signature (most callers just cast the function pointer), and ARM/Linux hacks. So move them all to one place.
* context_wayland: do not call vo_wayland_request_frame() upon bufferswapRostislav Pehlivanov2017-01-071-3/+0
| | | | | | | | vo_wayland_wait_events() is going to return when its time to swap the buffers anyway, calling request_frame() before makes no sense. Fixes the constant high CPU usage by the compositor when mpv is paused and the window is in view.
* vo_opengl: wayland: use new EGL context creation codewm42016-09-141-49/+8
|
* wayland_common: fix fullscreen image switching bugRostislav Pehlivanov2016-07-301-2/+0
| | | | | | | | | | | The problem was that when in fullscreen, switching between images did not issue a resize event, causing none of the images to be rendered correctly. This fixes the problem by issuing a resize event with the screen width and height. This commit also moves the zeroing of the events field to when it gets retrieved by mpv rather than randomly after a resize in the vo/backend code.
* wayland: port to the new wakeup/wait_events frameworkRostislav Pehlivanov2016-07-211-2/+13
| | | | | | | | | | | | This fits natively into the vo/backend and allows to simplify the polling code. One new change is the fact that surface_handle_enter flags VO_EVENT_WIN_STATE and VO_EVENT_RESIZE instead of only VO_EVENT_WIN_STATE. Before this, the code hackily relied on the timeout and the loop in the wait_frame function to track and set the scaling factor. Instead, this triggers mpv to run a schedule_resize and adjust the new VO output dimensions immediately. This is also more accurate since surface_handle_enter() gets called when a surface is created, moved and resized, which is exactly what the rest of the player might be interested in.
* wayland: implement HIDPI supportRostislav Pehlivanov2016-05-301-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | | The wayland protocol exposes scaling done by the compositor to compensate for small window sizes on small high DPI displays. If the program ignores the scaling done, what'll happen is the compositor is going to ask the program to be scaled down by N times the window size and then it'll upscale the program's surface by N times. The scaling algorithm seems to be bilinear so the scaling is quite obvious. This commit sets up callbacks to listen for the scaling factor of each output and, on rescale events, notifies the compositor that the surface's scale is what the compositor asked for and changes the player's surface to the appropriate size, causing no scaling to be done by the compositor. Compositors not supporting this interface will ignore the callbacks and do nothing, keeping program behaviour the same. For compositors supporting and using this interface (mutter), this will fix the rendering to be pixel precise as it should be. Both the opengl wayland backend and the wayland vo have been fixed to support this. Verified to not break either on weston and mutter. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
* vo_opengl: wayland: don't destroy NULL wl_egl_windowwm42016-03-031-1/+2
| | | | | The wayland client API crashes intentionally when trying to free NULL objects. (Thanks.)
* Relicense some non-MPlayer source files to LGPL 2.1 or laterwm42016-01-191-7/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This covers source files which were added in mplayer2 and mpv times only, and where all code is covered by LGPL relicensing agreements. There are probably more files to which this applies, but I'm being conservative here. A file named ao_sdl.c exists in MPlayer too, but the mpv one is a complete rewrite, and was added some time after the original ao_sdl.c was removed. The same applies to vo_sdl.c, for which the SDL2 API is radically different in addition (MPlayer supports SDL 1.2 only). common.c contains only code written by me. But common.h is a strange case: although it originally was named mp_common.h and exists in MPlayer too, by now it contains only definitions written by uau and me. The exceptions are the CONTROL_ defines - thus not changing the license of common.h yet. codec_tags.c contained once large tables generated from MPlayer's codecs.conf, but all of these tables were removed. From demux_playlist.c I'm removing a code fragment from someone who was not asked; this probably could be done later (see commit 15dccc37). misc.c is a bit complicated to reason about (it was split off mplayer.c and thus contains random functions out of this file), but actually all functions have been added post-MPlayer. Except get_relative_time(), which was written by uau, but looks similar to 3 different versions of something similar in each of the Unix/win32/OSX timer source files. I'm not sure what that means in regards to copyright, so I've just moved it into another still-GPL source file for now. screenshot.c once had some minor parts of MPlayer's vf_screenshot.c, but they're all gone.
* vo_opengl: prefix per-backend source files with context_wm42015-12-191-0/+237