summaryrefslogtreecommitdiffstats
path: root/video/out/vo_wlshm.c
Commit message (Collapse)AuthorAgeFilesLines
* wayland: use bool type for alpha framebuffer trackingRay Smith2023-02-281-1/+1
| | | | | | | | | ra_ctx_opts.want_alpha and vo_wayland_set_opaque_region's alpha argument are only used as bool but both are ints. Particularly for the function argument, passing a 0 or 1 is confusing - at first glance it looks like you're specifying an alpha value of 0 or 1. Since they're only used as bools, make them bools.
* wayland: add wp-fractional-scale-v1 supportDudemanguy2023-01-241-0/+3
| | | | | | | | | | | | | This protocol is pretty important since it finally lets us solve the longstanding issue of fractional scaling in wayland (no more mpv doing rendering over the target resolution and then being scaled down). This protocol also can completely replace the buffer_scale usage that we are currently using for integer scaling so hopefully this can be removed sometime in the future. Note that vo_dmabuf_wayland is omitted from the fractional scale handling because we want the compositor to handle all the scaling for that VO. Fixes #9443.
* wayland: rewrite geometry and scaling handlingDudemanguy2023-01-241-2/+2
| | | | | | | | | This is in preparation for fractional scaling support. Basically, redo all the coordinates in wayland so that wl->geometry is equal exactly to what is being put out to the screen (no extra wl->scaling multiplication required). The wl->vdparams variable is also eliminated for simplicity. This changes mpv's behavior on wayland with hidpi scaling but that will be addressed in more detail with the next commit.
* vo_wlshm: properly support video panscanDudemanguy2023-01-091-0/+6
| | | | | Turns out it was already doing this under the hood the entire time. The only catch is that the vo just needed a resize.
* vo_wlshm: cleanup on failureDudemanguy2023-01-081-15/+18
| | | | | If failure occurs during preinit, vo_wlshm should goto an error and cleaup itself like the other VOs.
* wayland: error out if essential protocol support is missingDudemanguy2022-11-151-0/+5
| | | | | | | | | | | | | | Related issue: #10868. While most protocols are in theory optional, a small amount of them are absolutely essential and nothing will work without them. We should make sure to error out in those cases and not try to actually do anything. For wayland support in general, wl_compositor support is obviously required. If there is no wl_surface, you can't do anything. Additionally, vo_wlshm quite obviously requires wl_shm so mark that one as well. vo_dmabuf_wayland needs linux_dmabuf, viewporter, wl_shm, and wl_subcompositor. In practice, these are all very standard protocols and shouldn't be missing but the linked issue above is at least one example where a compositor was stuck on an ancient version of a wayland interface.
* wayland: correctly handle non-CLOCK_MONOTONIC clocksDudemanguy2022-10-061-2/+2
| | | | | | | | | | | | | The wayland presentation time code currently always assumes that only CLOCK_MONOTONIC can be used. There is a naive attempt to ignore clocks other than CLOCK_MONOTONIC, but the logic is actually totally wrong and the timestamps would be used anyway. Fix this by checking a use_present bool (similar to use_present in xorg) which is set to true if we receive a valid clock in the clockid event. Additionally, allow CLOCK_MONOTONIC_RAW as a valid clockid. In practice, it should be the same as CLOCK_MONOTONIC for us (ntp/adjustime difference wouldn't matter). Since this is a linux-specific clock, add a define for it if it is not found.
* vo: move wayland presentation to separate filesDudemanguy2022-06-191-6/+4
| | | | | | | | | | | | | | | | | | | | | | | | | Wayland had some specific code that it used for implementing the presentation time protocol. It turns out that xorg's present extension is extremely similar, so it would be silly to duplicate this whole mess again. Factor this out to separate, independent code and introduce the mp_present struct which is used for handling the ust/msc values and some other associated values. Also, add in some helper functions so all the dirty details live specifically in present_sync. The only wayland-specific part is actually obtaining ust/msc values. Since only wayland or xorg are expected to use this, add a conditional to the build that only adds this file when either one of those are present. You may observe that sbc is completely omitted. This field existed in wayland, but was completely unused (presentation time doesn't return this). Xorg's present extension also doesn't use this so just get rid of it all together. The actual calculation is slightly altered so it is correct for our purposes. We want to get the presentation event of the last frame that was just occured (this function executes right after the buffer swap). The adjustment is to just remove the vsync_duration subtraction. Also, The overly-complicated queue approach is removed. This has no actual use in practice (on wayland or xorg). Presentation statistics are only ever used after the immediate preceding swap to update vsync timings or thrown away.
* vo: move allocate_memfd method to wayland_commonAaron Boxer2022-05-301-16/+1
|
* wayland: use wl_surface_damage_bufferDudemanguy2022-04-271-2/+2
| | | | | | | | | | | | | | | | Since 2018, wl_surface_damage_buffer has been explicitly preferred and recommended over wl_surface_damage*. mpv was still using the old function in a couple of spots. The only difference is that we need to pass buffer coordinates instead of surface coordinates. In vo_wlshm, this is done by using vo->dwidth/vo->dheight since that is always used whenever wl_buffers are created. In the case of the cursor surfaace, we actually already passed buffer coordinates to it (img->width/height) which was probablly technically wrong with wl_surface_damage, but it doesn't really matter in practice. This requires bumping wl_compositor to version 4 which is no problem since this dates back to 2015*. https://gitlab.freedesktop.org/wayland/wayland/-/commit/921d0548035673a1bf6aeb9396b9bc728133411e https://gitlab.freedesktop.org/wayland/wayland/-/commit/3384f69ecf043d62a4e036c0353c2daa01d7c4d0
* vo_wlshm: use draw_frame instead of draw_imageDudemanguy2022-04-211-3/+3
| | | | | | | | draw_image is an old API that was deprecated long ago. However when wlshm was originally added, it used draw_image. There's no particular reason for this and it can trivially be switched to draw_frame instead. This has some real advantages (notably --vo=wlshm --idle --force-window actually works).
* wayland: unify visibility checking codeDudemanguy2022-04-111-2/+1
| | | | | | | | | | | A bit of a personal pet peeve. vulkan, opengl, and wlshm all had different methods for doing wayland's "check for visibility before drawing" thing. The specific backend doesn't matter in this case and the logic should all be shared. Additionally, the external swapchain that the opengl code on wayland uses is done away with and it instead copies vulkan by using a param. This keeps things looking more uniform across backends and also makes it easier to extend to other platforms (see the next couple of commits).
* vo_wlshm: remove empty options structDudemanguy2021-08-091-6/+0
| | | | | This doesn't do anything and isn't needed as there are no wlshm-specific options.
* wayland: always be sure to initially try to renderDudemanguy2021-06-271-1/+1
| | | | | | | | | | | | | | | | | | | A subtle regression from c26d833. On sway if mpv was set to be a floating window in the config, set_buffer_scale would actually get applied twice according to the wayland log. That meant a 1920x1080 window would appear as a 960x540 window if the scale of the wl_output was set to 2. This only affected egl on sway (didn't occur on weston and was too lazy to try anything else; probably they were fine). Since wl->render is initially false, that meant that the very first run through the render loop returns false. This probably caused something weird to happen with the set_buffer_scale calls (the egl window gets created and everything but mpv doesn't write to it just yet) which makes the set_buffer_scale call happen an extra time. Since it was always intended for mpv to initally render, this is worth fixing. Just chnage wl->render to wl->hidden (again) and flip the bools around. That way, the initial false value results in render == true and mpv tries to draw on the first pass. This fixes the weird scaling behavior because reasons.
* wayland: reorganize wayland common codeDudemanguy2021-06-261-1/+1
| | | | | | | Mostly a cosmetic change that (hopefully) makes things look better. Some functions and structs that were previously being exported in the wayland header were made static to the wayland_common.c file (these shouldn't be accessed by anyone else).
* wayland: shuffle around the render loop againDudemanguy2021-05-241-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Take two. f4e89dd went wrong by moving vo_wayland_wait_frame before start_frame was called. Whether or not this matters depends on the compositor, but some weird things can happen. Basically, it's a scheduling issue. vo_wayland_wait_frame queues all events and sends them to the server to process (with no blocking if presentation time is available). If mpv changes state while rendering (and this function is called before every frame is drawn), then that event also gets dispatched and sent to the compositor. This, in some cases, can cause some funny behavior because the next frame gets attached to the surface while the old buffer is getting released. It's safer to call this function after the swap already happens and well before mpv calls its next draw. There's no weird scheduling of events, and the compositor log is more normal. The second part of this is to fix some stuttering issues. This is mostly just conjecture, but probably what was happening was this thing called "composition". The easiest way to see this is to play a video on the default audio sync mode (probably easiest to see on a typical 23.976 video). Have that in a window and float it over firefox (floating windows are bloat on a tiling wm anyway). Then in firefox, do some short bursts of smooth scrolling (likely uses egl). Some stutter in video rendering could be observed, particularly in panning shots. Compositors are supposed to prevent tearing so what likely was happening was that the compositor was simply holding the buffer a wee bit longer to make sure it happened in sync with the smooth scrolling. Because the mpv code waits precisely on presentation time, the loop would timeout on occasion instead of receiving the frame callback. This would then lead to a skipped frame when rendering and thus causing stuttering. The fix is simple: just only count consecutive timeouts as not receiving frame callback. If a compositor holds the mpv buffer slightly longer to avoid tearing, then we will definitely receive frame callback on the next round of the render loop. This logic also appears to be sound for plasma (funfact: Plasma always returns frame callback even when the window is hidden. Not sure what's up with that, but luckily it doesn't matter to us.), so get rid of the goofy 1/vblank_time thing and just keep it a simple > 1 check.
* wayland: simplify render loopDudemanguy2021-05-221-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is actually a very nice simplification that should have been thought of years ago (sue me). In a nutshell, the story with the wayland code is that the frame callback and swap buffer behavior doesn't fit very well with mpv's rendering loop. It's been refactored/changed quite a few times over the years and works well enough but things could be better. The current iteration works with an external swapchain to check if we have frame callback before deciding whether or not to render. This logic was implemented in both egl and vulkan. This does have its warts however. There's some hidden state detection logic which works but is kind of ugly. Since wayland doesn't allow clients to know if they are actually visible (questionable but whatever), you can just reasonably assume that if a bunch of callbacks are missed in a row, you're probably not visible. That's fine, but it is indeed less than ideal since the threshold is basically entirely arbitrary and mpv does do a few wasteful renders before it decides that the window is actually hidden. The biggest urk in the vo_wayland_wait_frame is the use of wl_display_roundtrip. Wayland developers would probably be offended by the way mpv abuses that function, but essentially it was a way to have semi-blocking behavior needed for display-resample to work. Since the swap interval must be 0 on wayland (otherwise it will block the entire player's rendering loop), we need some other way to wait on vsync. The idea here was to dispatch and poll a bunch of wayland events, wait (with a timeout) until we get frame callback, and then wait for the compositor to process it. That pretty much perfectly waits on vsync and lets us keep all the good timings and all that jazz that we want for mpv. The problem is that wl_display_roundtrip is conceptually a bad function. It can internally call wl_display_dispatch which in certain instances, empty event queue, will block forever. Now strictly speaking, this probably will never, ever happen (once I was able to to trigger it by hardcoding an error into a compositor), but ideally vo_wayland_wait_frame should never infinitely block and stall the player. Unfortunately, removing that function always lead to problems with timings and unsteady vsync intervals so it survived many refactors. Until now, of course. In wayland, the ideal is to never do wasteful rendering (i.e. don't render if the window isn't visible). Instead of wrestling around with hidden states and possible missed vblanks, let's rearrange the wayland rendering logic so we only ever draw a frame when the frame callback is returned to use (within a reasonable timeout to avoid blocking forever). This slight rearrangement of the wait allows for several simplifications to be made. Namely, wl_display_roundtrip stops being needed. Instead, we can rely entirely on totally nonblocking calls (dispatch_pending, flush, and so on). We still need to poll the fd here to actually get the frame callback event from the compositor, but there's no longer any reason to do extra waiting. As soon as we get the callback, we immediately draw. This works quite well and has stable vsync (display-resample and audio). Additionally, all of the logic about hidden states is no longer needed. If vo_wayland_wait_frame times out, it's okay to assume immediately that the window is not visible and skip rendering. Unfortunately, there's one limitation on this new approach. It will only work correctly if the compositor implements presentation time. That means a reduced version of the old way still has to be carried around in vo_wayland_wait_frame. So if the compositor has no presentation time, then we are forced to use wl_display_roundtrip and juggle some funny assumptions about whether or not the window is hidden or not. Plasma is the only real notable compositor without presentation time at this stage so perhaps this "legacy" mechanism could be removed in the future.
* vo_wlshm: support big endian systemsEmmanuel Gil Peyrot2021-02-041-1/+2
| | | | The video was otherwise blue, and that’s not how it should be. :)
* vo_wlshm: support presentation timeDudemanguy2020-12-141-0/+14
| | | | | We get presentation feedback for free thanks to the last commit. Implementing it in wlshm is pretty straightfoward from there.
* wayland: unify frame/presentation callback codeDudemanguy2020-12-141-23/+0
| | | | | | | | | | | | | | | | Originally when presentation time was implemented, the frame callback and presentation feedback functions were called in each rendering api's separate backend (egl and vulkan). This meant that their respective structs were basically copy and pasted across both files. Plus later vo_wlshm started using frame callbacks too. Things got refactored a few times and it turns out there's actually no need to have these things separate anymore. The frame callback can just be initialized in vo_wayland_init and then everything else will follow from there. Just move all of this code to wayland_common and get rid of the duplication. Sidenote: This means that vo_wlshm can actually receive presentation feedback now. It's really simple to do so might as well. See the next commit.
* Revert "wayland: conditionally commit surface on resize"Dudemanguy2020-11-081-4/+1
| | | | | | | | | | | | 30dcfbc is a workaround for incorrect border sizes that could occur on sway/wlroots in certain edge cases. This seemed harmless enough, but it turns out that on mutter the extra wl_surface_commit somehow causes the window always go to the top left of the screen after you leave fullscreen. No idea why this occurs, but the original commit is a workaround a sway bug and causing regressions for other users isn't right despite the author being biased towards sway/wlroots. This reverts commit 30dcfbc9cb3f77dbb729fb6f95ffde7dbdddc4cb.
* wayland: update opaque region on runtimeDudemanguy2020-10-151-5/+1
| | | | | | | | | | Made possible with 00b9c81. 34b8adc let the wayland surface set an opaque region depending on if alpha was set by the user or not. However, there was no attempted detection for runtime changes and it is possible (at least in wayland vulkan) to toggle the alpha on and off. So this meant, we could be incorrectly signalling an opaque region if the user happened to change the alpha. Additionally, add a helper function for this and use it everywhere we want to set the opaque region.
* wayland: be less strict about when to renderDudemanguy2020-10-151-1/+1
| | | | | | | | | | | | | | | | | | | | | efb0c5c changed the rendering logic of mpv on wayland and made it skip rendering when it did not receive frame callback in time. The idea was to skip rendering when the surface was hidden and be less wasteful. This unfortunately had issues in certain instances where a frame callback could be missed (but the window was still in view) due to imprecise rendering (like the default audio video-sync mode). This would lead to the video appearing to stutter since mpv would skip rendering in those cases. To account for this case, simply re-add an old heuristic for detecting if a window is hidden or not since the goal is to simply not render when a window is hidden. If the wait on the frame callback times out enough times in a row, then we consider the window hidden and thus begin to skip rendering then. The actual threshold to consider a surface as hidden is completely arbitrary (greater than your monitor's refresh rate), but it's safe enough since realistically you're not going to miss 60+ frame callbacks in a row unless the surface actually is hidden. Fixes #8169.
* wayland: set an opaque regionDudemanguy2020-10-011-0/+5
| | | | | | | | | Apparently a part of the wayland spec. A compositor may use a surface that has set part of itself as opaque for various optimizations. For mpv, we simply set the entire surface as opaque as long as the user has not set alpha=yes (note: alpha is technically broken in the wayland EGL backend at the time of this commit but oh well). wlshm is always opaque. Fixes #8125.
* wayland: only render if we have frame callbackDudemanguy2020-09-211-0/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Back in the olden days, mpv's wayland backend was driven by the frame callback. This had several issues and was removed in favor of the current approach which allowed some advanced features (like display-resample and presentation time) to actually work properly. However as a consequence, it meant that mpv always rendered, even if the surface was hidden. Wayland people consider this "wasteful" (and well they aren't wrong). This commit aims to avoid wasteful rendering by doing some additional checks in the swapchain. There's three main parts to this. 1. Wayland EGL now uses an external swapchain (like the drm context). Before we start a new frame, we check to see if we are waiting on a callback from the compositor. If there is no wait, then go ahead and proceed to render the frame, swap buffers, and then initiate vo_wayland_wait_frame to poll (with a timeout) for the next potential callback. If we are still waiting on callback from the compositor when starting a new frame, then we simple skip rendering it entirely until the surface comes back into view. 2. Wayland on vulkan has essentially the same approach although the details are a little different. The ra_vk_ctx does not have support for an external swapchain and although such a mechanism could theoretically be added, it doesn't make much sense with libplacebo. Instead, start_frame was added as a param and used to check for callback. 3. For wlshm, it's simply a matter of adding frame callback to it, leveraging vo_wayland_wait_frame, and using the frame callback value to whether or not to draw the image.
* wayland: conditionally commit surface on resizeDudemanguy2020-08-201-1/+4
| | | | | | | | | | | | | | | | | | | | | 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.
* vo_wlshm, vo_drm: set image size with mp_image_set_sizeMichael Forney2020-05-171-2/+1
| | | | | | | | | | The image w and h members must match params.w and params.h, so should not be changed directly. The helper function mp_image_set_size is designed for this purpose, so just use that instead. This prevents an assertion error with the rewritten draw_bmp. Fixes #7721.
* vo_drm, wo_wlshm: mention that it's software scalingwm42020-02-111-1/+1
| | | | (But does anyone even read --vo=help output?)
* sws_utils: shuffle around some shitwm42019-10-311-1/+2
| | | | | | | | | | | Purpose uncertain. I guess it's slightly better, maybe. The move of the sws/zimg options from VO opts (vo_opt_list) to the top-level option list is tricky. VO opts have some helper code in vo.c, that sends VOCTRL_SET_PANSCAN to the VO on every VO opts change. That's because updating certain VO options used to be this way (and not just the panscan option). This isn't needed anymore for sws/zimg options, so explicitly move them away.
* vo_wlshm: use memfd_create() instead of shm_open()Emmanuel Gil Peyrot2019-10-171-23/+11
| | | | | | | | | | | This syscall avoids the need to guess an unused filename in /dev/shm and allows seals to be placed on it. We immediately return if no fd got returned, as there isn’t anything we can do otherwise. Seals especially allow the compositor to drop the SIGBUS protections, since the kernel promises the fd won’t ever shrink. This removes support for any platform but Linux from this vo.
* Reintroduce vo_wayland as vo_wlshmMichael Forney2019-10-171-0/+312
vo_wayland was removed during the wayland rewrite done in 0.28. However, it is still useful for systems that do not have OpenGL. The new wayland_common code makes vo_wayland much simpler, and eliminates many of the issues the previous vo_wayland had.