summaryrefslogtreecommitdiffstats
path: root/video
Commit message (Collapse)AuthorAgeFilesLines
* win32: initial position: center with bordersAvi Halachmi (:avih)2021-09-061-0/+2
| | | | | | | | | | | | | | | | | | | | | | | Previously, the initial positioning and fit ignored the borders, and centered the content (the video itself) at the working area. Now, the initial positioning centers the window, by subtracting the borders (if needed) from the target area for the initial fit/position. While this does mean that the initial maximum content area is now smaller than before, ultimately this has no impact on the window size, because fit_on_screen is called later and, if needed, further shrinks the window to fit the borders too - but without centering the window. So the net impact of this commit is only the initial positioning (same size as before), which now centers the window instead of the content. Note that on Windows 10 the borders include invisible areas at the sides and bottom of the window (for mouse edge-drag), so visibly the window is nearer to the top than to the bottom, but these are the metrics we have (fit_on_screen uses the same border size values). On Windows 7 it looks perfectly centered.
* win32: fix incorrect application of --monitoraspectAvi Halachmi (:avih)2021-09-061-1/+4
| | | | | | | | | | | | | The --monitoraspect value is calculated at vo_calc_window_geometry2 (VCWG2) or VCWG3, and applied via vo_apply_window_geometry. Before this commit, the screen size which the win32 VO used with VCWG2 was the working area (screen minus taskbar). This allows better fitting, but breaks the pixelaspect calculation which is derived from the --monitoraspect value and this rectangle. VCWG3 allows an independent size for the aspect calculations, and now we use it independently of the fit size.
* win_state: add vo_calc_window_geometry3Avi Halachmi (:avih)2021-09-062-5/+21
| | | | | | | | | | | | | | | | | vo_calc_window_geometry2 (VCWG2) calculates both the pixelaspect and the autofit sizes based on one "screen" rectangle. However, these two calculations might need two different "screen" rects if the fit should take into account decorations and/or taskbar etc, while pixelaspect should be based on the full (monitor) rect. VCWG3 does just that. It's the same as VCWG2, but with an additional monitor rect which is used exclussively to calculate pixelaspect, while the "screen" argument is used for fitting (like before). VCWG2 now uses/calls VCWG3 with the same screen and monitor rects. Currently yet unused.
* wayland: set default cursor size to 24Ivan2021-08-281-1/+1
| | | | | Set it to 24 if it couldn't be read frome $XCURSOR_SIZE for some reason. Since it seems to be the default value for most distros/DE.
* wayland: read XCURSOR_THEME to get cursor themeIvan2021-08-281-1/+2
| | | | | Read $XCURSOR_THEME environment variable if set and if not then fall back to "default" (/usr/share/icons/default and ~/.icons/default)
* vo_tct: add resize capabilityCloud116652021-08-261-0/+7
| | | | No performance penalty added by getting the terminal size every frame.
* vo_drm: fix typo in error messagea13460542021-08-261-1/+1
|
* win32: support the property display-hidpi-scaleAvi Halachmi (:avih)2021-08-181-0/+4
| | | | | | | | This read-only property reflects the VO's dpi-scale value, and wasn't supported on win32 until now (it is supported on wayland/x11/osx). Currently in mpv it's only used by the builtin script console.lua, and assumed 1 if unavailable.
* win32: apply dpi-scale with [current]-window-scaleAvi Halachmi (:avih)2021-08-181-2/+5
| | | | | | | | | | | | | | When --window-scale=NUM is set from CLI, the dpi_scale value was/is taken into account when the win32 VO calls vo_calc_window_geometry2. However, when [current]-window-scale is read or set at runtime, it uses the VOCTRL_{GET,SET}_UNFS_WINDOW_SIZE interface, where other VOs apply the dpi_scale value internally (wayland, x11, osx), but the win32 VO didn't before this commit. Fixes two issues when --hidpi-window-scale=yes and dpi_scale != 1 : - Incorrect window-size when setting [current-]window-scale at runtime. - Incorrect current-window-scale value when reading it.
* win32: ensure initial dpi-scale valueAvi Halachmi (:avih)2021-08-181-14/+19
| | | | | | | | | | | | | | | | | | | | vo_calc_window_geometry2(...) is called to initialize the window size with the dpi_scale value as one of the arguments. dpi_scale is 0 initially, and set to a valid value at update_dpi(), which is called from [force_]update_display_info(). However, no measures were taken to ensure that dpi_scale is set correctly before vo_calc_window_geometry2() is called, which could result in incorrect window size if it's not initialized. It did happen to get initialized on time, by luck, because VOCTRL_GET_DISPLAY_FPS is used early, which happens to call update_display_info to read the fps value (other update_display_info() calls are after the first vo_calc_window_geometry2() call). This commit ensures that dpi_scale is initialized on time if needed. Also, update_dpi() now ensures that dpi_scale is never 0.
* vo_tct: fix --vo-tct-256Avi Halachmi (:avih)2021-08-161-3/+3
| | | | | | | | | | | | | | | This is a regression from cbbd81bb (the previous commit): print_seq1 (which prints a sequence with 1 parametric byte value) is used with 256 colors output, and apparently was never tested. Two issues were introduced at the offending commit: 1. The ";5" part was incorrectly removed from the strings ESC_COLOR256_{BG,FG} (affects both *nix and Windows). 2. On windows only - a semicolon was not used after the prefix. Both issues resulted in an invalid 256 colors sequences and output.
* vo_tct: optimize print function on non-windows platformsCloud116652021-08-161-14/+57
| | | | Using fwrite on non-windows platforms yields a ~25% performance increase.
* vo_tct: fix half-block on windowsAvi Halachmi (:avih)2021-08-161-0/+1
| | | | | | | On windows the UTF-8 strings are translated to wchar_t when printed to the console, and some escape sequences are also translated, however, this only works when printf is mapped to mp_printf, and for that to happen we need to include osdep/io.h .
* wayland: check for xkb state in handle modifiersDudemanguy2021-08-151-3/+4
| | | | | | | | | | | | | | | | | | Normally in wayland, you receive a keymap event from the compositor which is what allows the client to setup what is needed for xkb. However, it turns out that this doesn't occur in the case of virtual keyboards, such as from wtype, that come from the custom virtual-keyboard protocol. What happens in this case is that mpv only receives a keyboard entrance event. According to the wayland protocol documentation [1], "the compositor must send wl_keyboard.modifiers event after [the wl_keyboard.enter] event". It is possible for this to occur before the physical keyboard is properly mapped (i.e: using a virtual keyboard to start mpv). What this results in is a segfault once xkb_state_update_mask is called in the modifiers event. The fix is to simply not always assume we have created the xkb state if we get this event and check for its existence first. Closes #9119. https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_keyboard
* vo_rpi: restore fullscreen handlingHo Ming Shun2021-08-131-0/+20
| | | | | | | Previous fullscreen handling code was removed in 59cdfe50b2 during deprecation of VOCTRL_FULLSCREEN. Lack of this code caused the OSD layer to be to be not resized along with the video layer when fullscreen is toggled.
* x11: handle maximized windows with window-scaleDudemanguy2021-08-121-0/+6
| | | | | | | If a user attempted to change the window scale of a maximized window on x11, nothing would happen since the window manager holds the size of the window constant. Just do an unmaximize first before performing the resize.
* vo_vdpau: Don't treat preemption as an error when reconfiguringsjambekar2021-08-121-1/+11
| | | | | | | | | | | | | | | | | | | When the VT switch out is triggered, the decode thread (VD) falls back to sw decoding. However, on the VO thread, which is responsible for handling display preemption and presentation, vo_vdpau.c:reconfig() is called. The reconfig() function returned -1 when the check_preemption() returned 0. The vo_reconfig2() (which calls reconfig()) returned -1 in turn which entered into an error handling path. This led to a series of functions calls that ultimately set the in_terminate flag to TRUE. This led the vo_thread to exit which ultimately led to the MPV application exit. The fix is to return 0 instead of -1 after the check_preemption() in the vo_vpdau.c:reconfig(). Returning 0 instead of -1 is not fatal and does not have any side effects. This is confirmed by testing the VT switching behaviour. And as far as the frames that are going to the display are concerned, they are now dropped. Since the display is preempted, it is okay to drop the frames and continue.
* wayland: fix wrong opts structDudemanguy2021-08-101-1/+1
|
* wayland: request xdg-decoration mode on startupDudemanguy2021-08-101-0/+2
| | | | | | Right after the listener is constructed, request a mode based on the value of the border option. If border, then request SSD. If no border, request CSD. The decoration listener handles it from there.
* 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: check for xdg-decoration on border updateDudemanguy2021-08-091-1/+1
| | | | | Oversight in 69c64f5. If there is no xdg_toplevel_decoration, don't attempt to set the mode.
* wayland: handle xdg-decoration protocol betterDudemanguy2021-08-091-9/+22
| | | | | | | | | | | | | | | | | | | | | The current usage of the xdg-decoration protocol is quite a bit crude. There's a specific listener struct for this like with most wayland things, but mpv wasn't even using it. It also made no attempt to detect if the compositor was telling mpv to use client side decorations. To implement this correctly, first of all we need to create the decoration listener object and add it like how most wayland things work. Secondly, set_border_decorations needs to be changed to accept the uint32_t mode given by the compositor. When we get the decoration event, pass the mode obtained from the compositor to set_border_decorations. Update the mpv border option, based on whether or not we have server side decorations (yes if we have them; no if we don't). mpv can actually request either client side or server side decorations with this protocol. This function doesn't belong in set_border_decorations but rather it should be called when the border option changes. Whether or not this request actually works depends on the compositor (Plasma appears to allow it; sway does not). If the compositor allows this request, then it gets handled by configure_decorations. Note that the enum strangely starts at 1 hence why there is an extra +1.
* wayland: fix keepaspect-window during resizeDudemanguy2021-08-081-9/+6
| | | | | | | | | | | | So the resizing mechanism is actually supposed to match the video size to the window size while preserving the aspect ratio. In wayland, the current logic behaves as if --no-keepaspect-window was set. Fix this by simply multiplying the height by the same scale factor the width is multiplied by. Also get rid of the pointless (width > height) test (it makes no difference in any case) as well as some unneccesary checks for the keepaspect-window option. The use of ceil here is to make sure the window coordinates can never possibly have be 0 due to truncation (weston can still give you a 1x1 window which is fun). Fixes #9098.
* wayland: improve behavior with touch eventsDudemanguy2021-08-082-19/+9
| | | | | | | | | | | | | | | | | | | | | | | There's currently some touch related code in mpv wayland, but clearly nobody actually uses because it's a broken mess. Initially an attempt to distinguish between two finger touches and one finger touch was made, but there's not a good way to make this work. For whatever reason, initiating either xdg_toplevel_resize or xdg_toplevel_move blocks any other touch events from occurring (at least in plasma). Trying to call these functions anywhere else is not really useful since the serial will be invalid outside of the touch down events (well it would work in the touch up event but that's just silly). Anyways, let's just make this work sanely. Eliminate the touch entries variable completely because it's pointless. Only one finger event is ever considered at a time. Touches besides the initial one are all ignored. If a user touches and drags within the touch edge radius, then a resize event occurs. If the user touches and drags elsewhere on the window, a move event occurs. A single tap displays the osc (which is clickable if you tap again). A double tap toggles fullscreen. Additionally, the default touch edge radius of 64 pixels is way too big (at least I think so). Cut this in half to 32 which feels a lot better (on a pinephone using plasma mobile anyway).
* wayland: correct window-scale behaviorDudemanguy2021-08-071-3/+10
| | | | | | | | | | | | | | The way the window-scale option is supposed to behave wasn't really ever documented until 25cfc81. It turns out that different OS/WMs may do slightly different things. For wayland, we need to fix two things. First, only return the wl->window_size in GET_UNFS (aka don't return the fullscreen size). For SET_UNFS, we need to change the behavior for the maximized window case. If the window is maximized, first attempt to unmaximize it and send the wayland event. If the compositor allows this to happen, then go ahead and set the new dimensions and resize it. In the case that the attempt to unmaximize is not successful, then don't attempt the resize and just save the window size dimensions for later to be used when the user unmaximizes the window.
* wayland: keep track of toplevel width/height againDudemanguy2021-08-062-1/+9
| | | | | | | | | | | | | | Regression from 24357cb. It's ugly but unfortunately keeping tracking of the last toplevel width and height really is the best way to solve this problem and removing it was a mistake. Compositors don't always send width/height coordinates of the actual window. The easiest way to trigger this is by changing window-scale/current-window-scale and then unfocusing the window. The compositor will send another toplevel configure event with coordinates of the window before the resize. Maybe compositors could be smarter but multiple ones do this (sway, gnome, plasma), so just keep the old workaround. The only difference this time is that the toplevel width/height is saved at the very beginning which also covers the case where it equals 0 (i.e. weston).
* wayland: cleanup handle_toplevel_configDudemanguy2021-08-032-13/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The source of many geometry woes. There's some loosely related toplevel things that should be cleaned up/fixed. First of all, VO_EVENT_LIVE_RESIZING is actually completely useless. It might have been useful sometime in the past, but there's no point. It doesn't "speed up" resizing in any way and appears to be originally for cocoa. Just remove it. Way back in the day, toplevel_width/height was added as a workaround for when we got uncoorperative (i.e. wrong) width/height coordinates from the compositor in this event. Basically it could happen due to numerous reasons but a lack of atomic commits was part of the reason and also mpv's geometry handling then was a lot rougher. We *shouldn't* need this workaround anymore. The width/height values are only used exactly when we need them. If mpv sets geometry on its own, it should still be the right dimensions. Related to the above, mpv never actually propertly handled the case where width or height was equal to 0. According to the xdg-shell spec, "If the width or height arguments are zero, it means the client should decided its own window dimension." An example of a compositor doing this is weston. It's, unsurprisingly, broken. Getting out of fullscreen or a maximized state does not restore the old window size like it should. The right way to handle this is to just return near the end of the function if we have a 0 for either argument and before any geometry is set (wl->geometry's width or height can never be zero). Luckily, state changes are already being detected so they just trigger the goto when needed. Finally, e2c24ad mistakenly removed the VO_EVENT_EXPOSE. There are edge cases where this is needed and it's safer to just force a redraw here when the window gets activated again. Just force wl->hidden to false first and then trigger the expose.
* wayland: unset hidden state in frame callbackDudemanguy2021-07-261-8/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | More wayland weirdness. So previously, flipping a hidden state from true to false was done in vo_wayland_wait_frame. In theory, this would be after you get the frame callback and all those events so there's no problem. However since the function also does a bunch of flushing/dispatching/etc. to the default display queue so a lot of unknown things can happen before we actually set the hidden variable back to false. For example if a single image was paused and left on another virtual desktop long enough (~5 minutes) while also not having focus, switching back to that desktop could render it a black frame. This edge case was supposed to be handled by the surface being activated again in the toplevel event but apparently that doesn't always work. The fix is to just delete all of that junk and set wl->hidden = false in the frame callback. What's actually happening is kind of a mystery honestly. Probably the compositor drops the buffers after a while as an optimization (sensible) and forces a repaint if you switch back to the virtual desktop. Somehow wl->hidden not being set to false would not properly trigger a repaint (likely because it also sends a toplevel event which does stuff) thus you just get a black window. If you just make sure to set hidden in the frame callback, it appears like all of these problems and edge cases are solved. Since this event must happen first, that makes sense. That simplifies a lot of stuff and fixes some subtle bugs at the same time so just go with this approach.
* egl_helpers: fix create_context fallback behaviorDudemanguy2021-07-253-16/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The EGL stuff is really complicated because of historical reasons (tl;dr: blame EGL). There was one edge case with EGL context creation that lead to incorrect behavior. EGL_KHR_create_context was created with EGL 1.4 (which mpv does support) but it is still possible for an EGL 1.4 device to not implement this extension. That means that none of the EGL attrs that pass a specific opengl version work. So for this obscure case, there is a fallback context creation at the very end which simply creates an EGLContext without passing any special attrs. This has another problem however. mpv has a hard requirement on at least desktop opengl 2.1 or opengl ES 2.0 to function (we're not asking for much here). Since the fallback EGL context creation has no version checking, it is entirely possible to create an EGL context with a desktop opengl version under 2.1. As you get further along in the code, the user will encounter the hard opengl version check and then error out. However, we're supposed to also actually check if GLES works (that's what the opengl-es=auto option is for) so this is a bug. The fix is to do a bit of code duplication and make a mpgl_check_version specifically for if we hit the edge case of needing to create an EGL context without the EGL_KHR_create_context extension. Grab the version with the function pointer, check if it's under 210, if so destroy the EGL context and set it to NULL. After that, if the user has set opengl-es to auto, mpv will try GLES next. If it is set to no, then mpv will simply fail as desired. Fixes #5915. Sidenote: the ra_gl_ctx_test_version originally testing 140 doesn't make any sense. Passing the version number in that function only does something if the user has set opengl-restrict. What we need to do is to pass the version of the created context to that function. If the version is higher than the opengl-restrict option, then make this a failure.
* context_drm_egl: allow autoprobe selectionDudemanguy2021-07-231-5/+0
| | | | | | | | | | This was explictly coded to avoid the autoprobe way back when in 2015[1] with no real explanation. In theory, there shouldn't be any issues allowing this. If a user runs mpv in tty, this is probably what they actually want in most cases. Perhaps something strange happens on nvidia, but it should just fail anyway during the autoprobe. [1]: https://github.com/mpv-player/mpv/commit/f757163058c2e5c7136213b0f79923fcea34b71a
* wayland: refactor surface scalingDudemanguy2021-06-302-33/+56
| | | | | | | | | | | | | | | Another day, another wayland refactor. Way back when, dcc3c2e added support for the hidpi-window-scale option (something you probably should never set to no but whatever) to wayland. Well technically, it never had any runtime toggling support (don't remember if detecting when vo_opts changed was possible or not then; maybe not). Anyways in the process of fixing that, I went ahead and refactored how this is all handled. The key difference is that when hidpi-window-scale is disabled, wl->scaling is directly set to 1 instead of forcibly setting wl->current_output->scale to 1. Note that scaling operations don't always require a geometry reset/resize so set_surface_scaling needs to be separate from set_geometry. The logic here is kind of complicated but it (should) be correct.
* wayland: fix wl_surface_set_buffer_scale usageDudemanguy2021-06-273-3/+2
| | | | | | | | | | | The wl_surface lives for the entire lifetime of the vo. It's only neccesary to set the scale initially and when the output scaling changes (the surface moves to a different output with a different scale or the output itself changes it scale). All of the calls that were being made in the egl/vulkan resize functions are not needed. vo_wlshm wasn't correctly rescaling itself before this commit since it had no logic to handle scale changes. This should all be shared, common code in the surface/output listeners.
* wayland: always be sure to initially try to renderDudemanguy2021-06-275-8/+7
| | | | | | | | | | | | | | | | | | | 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: remove unused includesDudemanguy2021-06-272-6/+0
| | | | Presentation time only lives in in wayland_common.
* wayland: handle app id option less stupidlyDudemanguy2021-06-261-4/+0
| | | | | | Not sure what I was on when I wrote this. wayland-app-id is supposed to default to "mpv". Just set that in the vo_sub_opts and don't do this weird m_config_cache_write_opt thing. Also make the doc entry nicer.
* wayland: reorganize wayland common codeDudemanguy2021-06-265-948/+962
| | | | | | | 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).
* vo_gpu: vulkan: displayvk: Fix handling of unconnected planesPhilip Langdale2021-06-121-1/+6
| | | | | | | | If a plane is not connected to any displays, we won't set an entry in the mapping of planes to displays. So ensure these unset entries are null and skip them. Fixes #8913
* vo_gpu: vulkan: implement a VkDisplayKHR backed contextPhilip Langdale2021-06-112-0/+392
| | | | | | | | | | | | | | | | | | | | | | | | This is the Vulkan equivalent of the drm context for OpenGL, with the big difference that it's implemented purely in terms of Vulkan calls and doesn't actually require drm or kms. The basic idea is to identify a display, mode, and plane on a device, and then create a display backed surface for the swapchain. In theory, past that point, everything is the same, and this is in fact the case on Intel hardware. I can get a video playing on a vt. On nvidia, naturally, things don't work that way. Instead, nvidia only implemented the extension for scenarios where a VR application is stealing a display from a running window system, and not for standalone scenarios. With additional code, I've got this scenario to work but that's a separate incremental change. Other people have tested on AMD, and report roughly the same behaviour as on Intel. Note, that in this change, the VT will not be correctly restored after qutting. The only way to restore the VT is to introduce some drm specific code which I will illustrate in a separate change.
* vo_gpu: vulkan: provide a helper to access device name optionPhilip Langdale2021-06-112-0/+17
| | | | | | | | | | | The VkDisplayKHR context type requires making calls against the physical device before the libplacebo context is initialised. That means we can't simply use the physical device object that libplacebo would create - instead we have to create a separate one, but make sure it's referring to the same physical device. To that end, we need the device name that the user may have requested so we can pass it on.
* vo_rpi: fix argument nameDudemanguy2021-06-081-2/+2
| | | | This is data not arg.
* wayland: refactor dispatching eventsDudemanguy2021-05-281-46/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This was originally just a bugfix for a race condition, but the scope expanded a bit. Currently, the wayland code does a prepare_read -> dispatch_pending -> display_flush -> read_events -> dispatch_pending routine that's basically straight from the wayland client API documentation. This essentially just queues up all the wayland events mpv has and dispatches them to the compositor. We do this for blocking purposes on every frame we render. A very similar thing is done for wait_events from the VO. This code can pretty easily be unified and split off into a separate function, vo_wayland_dispatch_events. vo_wayland_wait_frame will call this function in a while loop (which will break either on timeout or if we receive frame callback from the compositor