Commit Graph

3264 Commits

Author SHA1 Message Date
Jan Ekström 684ffd13b4 vo_gpu/d3d11: fixup adapter selection by switching it all to bstr
I did ponder if I should have done this right away, and it seems
like not doing it at first was a mistake.
2019-10-15 22:12:48 +03:00
Jan Ekström 648d785930 vo_gpu/d3d11: add support for configuring swap chain format
Query information on the system output most linked to the swap chain,
and either utilize a user-configured format, or either 8bit
RGBA or 10bit RGB with 2bit alpha depending on the system output's
bit depth.
2019-10-13 22:31:33 +11:00
James Ross-Gowan 4809a3f48d vo_gpu/d3d11: utilize actual backbuffer values for bit depth
And if backbuffer is not around, return an error value utilized
elsewhere already.
2019-10-13 22:31:33 +11:00
dudemanguy ea4685b233 wayland: use callback flag + poll for buffer swap
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.
2019-10-10 17:41:19 +00:00
dudemanguy e0895e097b Revert "vo: add support for externally driven renderloop and make wayland use it"
The externally driven renderloop was originally added for the wayland
context (to make display sync somewhat work), but it has a lot of issues
with mpv's internal structure. A different approach should be used.

This reverts commit a743fef837.
2019-10-10 17:41:19 +00:00
James Ross-Gowan 6002e2705f vo_gpu: d3d11: use linear filtering for wrapped textures
This affects hwdec_dxva2dxgi, which uses ra_d3d11_wrap_tex to wrap RGB
video frames that are shared with a D3D9 device. Without it, mpv uses
nearest instead of bilinear scaling with --scale=bilinear (the default)
and --hwdec=dxva2. It's kind of hard to believe this bug has gone
unnoticed for almost two years, but that seems to have been the case.

Fixes: #7042
2019-10-10 19:52:19 +11:00
der richter 6d0f0546ee cocoa-cb: remove get_property_* usages and split up mpv helper
all the get_property_* usages were removed because in some circumstances
they can lead to deadlocks. they were replaced by accessing the vo and
mp_vo_opts structs directly, like on other vos.

additionally the mpv helper was split into a mpv and libmpv helper, to
differentiate between private and public APIs and for future changes
like a macOS vulkan context for vo=gpu.
2019-10-06 13:29:48 +02:00
dudemanguy fd7aff7a9d wayland opengl: actually call uninit if init fails
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.
2019-10-03 14:56:43 +00:00
dudemanguy 9d6ae83fdc Revert "wayland: free wayland_state on a false return"
Dumb idea. The correct thing to do is to fix the preinit and context
creation so that the uninit is correctly executed when probing fails
(and then everything gets freed).

This reverts commit defc8f359c.
2019-10-03 14:56:43 +00:00
Dudemanguy911 defc8f359c wayland: free wayland_state on a false return
wm4 mentioned that the wayland autoprobe leaked. A simple oversight in
the wayland_common code forgot to free the vo_wayland_state if
vo_wayland_init returned false.
2019-10-02 18:38:45 -05:00
Dudemanguy911 d823b3b39a wayland: always create wl_output before rendering
I previously skipped creating the wl_output if the --fullscreen flag
with no --fsscreen_id was inputted, so the fullscreen video lands on the
correct output (where mpv was launched). This has breakage if someone
combines the --autofit flag (or other similar options with it). Instead,
just actually read xdg_shell spec and realize that you can pass NULL to
xdg_toplevel_set_fullscreen and let the compositor choose the output if
the user doesn't specify it. If this has issues, get a better
compositor.
2019-10-02 22:43:13 +00:00
Jan Ekström 1f76e69145 vo_gpu/d3d11: add adapter name validation and listing with "help"
Not the prettiest way to get it done, but seems to work.
2019-09-29 19:39:26 +03:00
Jan Ekström bca6e14702 vo_gpu/d3d11: refactor pthread_once d3d11 loading to function
Lets us reuse this in the future.
2019-09-29 19:39:26 +03:00
Jan Ekström b7438d3aff vo_gpu/d3d11: utilize the passed adapter name
Normalize nullptr and an empty string both to nullptr to simplify
handling. API users cannot set a value back to nullptr, so both
an empty string as well as nullptr should behave the same.
2019-09-29 19:39:26 +03:00
Jan Ekström e6447e2e89 vo_gpu/d3d11: add an option for the adapter name
Set it from the adapter name in the d3d11 options.
2019-09-29 19:39:26 +03:00
Jan Ekström 8163906299 video/d3d11: add adapter selection by name into d3d11 options
This lets the user define an adapter name that can then be passed
further into the internals.
2019-09-29 19:39:26 +03:00
Jan Ekström e205e179e0 vo_gpu/d3d11_helpers: also load up CreateDXGIFactory1
Just a factory, without a device, is required for listing of devices.
2019-09-29 19:39:26 +03:00
Anton Kindestam 0d4f165d81 vo_drm: fix flickering when setting pan/scan
Turns out clearing all frambuffers in reconfig isn't such a great idea
when you also end up here when setting pan/scan.

I guess this is just a leftover from a previous iteration of vo_drm
where doing this made sense.
2019-09-29 12:16:26 +02:00
Philip Langdale 8c1f94f0e7 vo_gpu: hwdec_cuda: Synchronise OpenGL Interop
Previously, there appeared to be implicit synchronisation in the
GL interop path, and we never observed any visual glitches. However,
recently, I started seeing stuttering in the GL path and on closer
examination it looked like read-before-write behaviour where GL
would display an old frame again rather than the current one.

After verifying that disabling hwdec made the problem go away,
I tried adding a cuStreamSynchronize() after the memcpys and that
also resolved the problem, so it's clearly sync related.

cuStreamSynchronize() is a CPU sync and so more heavy-weight than
you want, but it's the only tool we have. There is no mechanism
defined for synchronising GL to CUDA (It looks like there is a way
to synchronise CUDA to EGL but it appears one way and so wouldn't
directly address this problem).

Anyway, empirically, the output now looks the same as with hwdec
off.
2019-09-28 19:24:24 +03:00
Anton Kindestam 0c8eb80e98 vo_drm: support controlling swapchain depth using swapchain-depth option 2019-09-28 14:10:01 +03:00
Anton Kindestam 6290420380 vo: make swapchain-depth option generic for all VOs
In preparation for making vo_drm able to use swapchain-depth
2019-09-28 14:10:01 +03:00
Anton Kindestam 9538fb5a7a drm: refactor page_flipped callback
Avoid duplicating the same callback function in both context_drm_egl
and vo_drm.
2019-09-28 14:10:01 +03:00
Anton Kindestam 77980c8184 vo_drm: Implement N-buffering and presentation feedback
Swapchain depth currently hard-coded to 3 (4 buffers).

As we now avoid redrawing on repeat frames (we simply requeue the same fb
again), this should give a nice performance boost when playing videos with a
lower FPS than the display FPS in video-sync=display-resample mode.

Presentation feedback has also been implemented to help counter the
significant amounts of jitter we would otherwise be seeing.
2019-09-28 14:10:01 +03:00
Anton Kindestam dfe45f018e vo_drm: fix more than 2 buffers
Now we can increase BUF_COUNT. Yay.
2019-09-28 14:10:01 +03:00
Anton Kindestam 2cf8dd6451 drm: move struct vsync_tuple into drm_common as drm_vsync_tuple
This struct will be useful in vo_drm as well.
2019-09-28 14:10:01 +03:00
Anton Kindestam 22252432e2 context_drm_egl: define EGL_PLATFORM_GBM_MESA, EGL_PLATFORM_GBM_KHR if not in system headers
To account for oddball setups where EGL_PLATFORM_GBM_MESA or
EGL_PLATFORM_GBM_KHR might not be defined for whatever reason.
2019-09-27 20:01:15 +02:00
Wessel Dankers 643417dd17 video: add pure gamma TRC curves for 2.0, 2.4 and 2.6. 2019-09-27 13:21:41 +02:00
Philip Sequeira 21a5c416d5 options: add M_OPT_FILE to some more options that take files 2019-09-27 13:19:29 +02:00
Jonas Karlman 16d2ddb505 vo_gpu: hwdec_drmprime_drm: add hwdec ctx
This allows to use drm hwaccels that require a hwdevice.

Tested with v4l2request hwaccel and cedrus driver on an allwinner device
running mpv with --vo=gpu --gpu-context=drm --hwdec=drm.
2019-09-27 13:08:27 +02:00
wm4 c3687b9eaa hwdec_vaapi_gl: add missing compatibility defines
At first, this code used only 1 plane, so the compatibility stuff was
sufficient. But then use of planes 1 and 2 was added, without extending
the compatibility stuff.

I think I've seen a case recently where this broke the build and caused
users to apply invalid fixes, but I don't remember where.

It's possible that I didn't get all defines that are needed.
2019-09-27 13:05:21 +02:00
sfan5 e350ceef4c vo_gpu: vulkan: add Android context 2019-09-27 00:05:06 +03:00
sfan5 508e35881e context_android: move common code to a separate file
In preparation for a Vulkan Android context.
This also replaces querying for EGL_WIDTH and EGL_HEIGHT
with equivalent ANativeWindow calls.
2019-09-27 00:05:06 +03:00
James Ross-Gowan 03cb8755e1 vo_gpu: d3d11: don't reset frame stats after pause
I think I was wrong about having to reset the stats when mpv stops
producing frames, eg. when it's paused. As long as the swapchain doesn't
underflow, last_queue_display_time will still be accurate, because the
next frame produced should still be presented one vsync after the
last one in the swapchain.

If the swapchain underflows (which is the common case for when mpv is
paused for more than 150ms,) the next predicted frame time should be in
the past. It should be fine to leave last_queue_display_time unset in
this case, since vo.c will use the current time instead, which is a
decent guess (though it doesn't take vsync phase into account.)

last_sync_refresh_count and last_sync_qpc_time should be kept on
swapchain underflow as well. Assuming the display refresh rate doesn't
change while mpv is paused, they'll only provide a more accurate guess
of the vsync duration when mpv starts playing again. Also,
vsync_duration_qpc never needs to get reset. It will get overwritten
immediately in most cases, and when it doesn't, it's still a better
guess of the vsync duration than nothing.
2019-09-26 23:41:38 +03:00
wm4 4d43c79e4c client API: fix potential deadlock problems by throwing more shit at it
The render API (vo_libmpv) had potential deadlock problems with
MPV_RENDER_PARAM_ADVANCED_CONTROL. This required vd-lavc-dr to be
enabled (the default). I never observed these deadlocks in the wild
(doesn't mean they didn't happen), although I could specifically provoke
them with some code changes.

The problem was mostly about DR (direct rendering, letting the video
decoder write to OpenGL buffer memory). Allocating/freeing a DR image
needs to be done on the OpenGL thread, even though _lots_ of threads are
involved with handling images. Freeing a DR image is a special case that
can happen any time. dr_helper.c does most of the evil magic of
achieving this. Unfortunately, there was a (sort of) circular lock
dependency: freeing an image while certain internal locks are held would
trigger the user's context update callback, which in turn would call
mpv_render_context_update(), which processed all pending free requests,
and then acquire an internal lock - which the caller might not release
until a further DR image could be freed.

"Solve" this by making freeing DR images asynchronous. This is slightly
risky, but actually not much. The DR images will be free'd eventually.
The biggest disadvantage is probably that debugging might get trickier.

Any solution to this problem will probably add images to free to some
sort of queue, and then process it later. I considered making this more
explicit (so there'd be a point where the caller forcibly waits for all
queued items to be free'd), but discarded these ideas as this probably
would only increase complexity.

Another consequence is that freeing DR images on the GL thread is not
synchronous anymore. Instead, it mpv_render_context_update() will do it
with a delay. This seems roundabout, but doesn't actually change
anything, and avoids additional code.

This also fixes that the render API required the render API user to
remain on the same thread, even though this wasn't documented. As such,
it was a bug. OpenGL essentially forces you to do all GL usage on a
single thread, but in theory the API user could for example move the GL
context to another thread.

The API bump is because I think you can't make enough noise about this.
Since we don't backport fixes to old versions, I'm specifically stating
that old versions are broken, and I'm supplying workarounds.

Internally, dr_helper_create() does not use pthread_self() anymore, thus
the vo.c change. I think it's better to make binding to the current
thread as explicit as possible.

Of course it's not sure that this fixes all deadlocks (probably not).
2019-09-26 14:14:49 +02:00
der richter 41f290f54e cocoa-cb: add support for 10bit opengl rendering
this will request a 16bit half-float framebuffer instead if a 8bit
integer framebuffer.

Fixes #3613
2019-09-26 00:02:02 +02:00
Anton Kindestam bbf6e103b4 drm_common: add missing zero-initialization of struct vt_mode variable
Some fields were being left uninitialized. This could be a problem
particularly on non-Linux OS:s with vt_mode (see PR #6976).
2019-09-24 21:46:52 +02:00
der richter 422b486200 cocoa-cb: fix title bar button state on start up
on start up it was possible to click the hidden buttons. hide the
buttons ons tart up to make the state consistent with the visible state.
2019-09-23 21:10:38 +02:00
Anton Kindestam b6def652a4 context_drm_egl: Don't get stuck forever if drmHandleEvent fails 2019-09-22 22:39:10 +02:00
Anton Kindestam e2f96535f5 vo_drm: 30bpp support 2019-09-22 15:59:24 +02:00
James Ross-Gowan a9f9601ca8 vo_gpu: d3d11: add support for presentation feedback
This adds vsync reporting to the D3D11 backend using the presentation
feedback provided by DXGI, which is pretty similar to what's provided by
GLX_OML_sync_control in the GLX backend. In DirectX, PresentCount is the
SBC, PresentRefreshCount and SyncRefreshCount are kind of like the MSC
and SyncQPCTime is the UST.

Unlike GLX, the DXGI API makes it possible for PresentCount and
SyncQPCTime to refer to different physical vsyncs, in which case
PresentRefreshCount and SyncRefreshCount will be different. The code
supports this possibility, even though it's not clear whether it can
happen when using flip-model presentation. The docs say for flip-model
apps, PresentRefreshCount is equal to SyncRefreshCount "when the app
presents on every vsync," but on my hardware, they're always equal, even
when mpv misses a vsync. They can definitely be different in exclusive
fullscreen bitblt mode, though, which mpv doesn't support now, but might
support in future.

Another difference to GLX is that, at least on my hardware,
PresentRefreshCount and SyncRefreshCount always refer to the last
physical vsync on which mpv presented a frame, but glxGetSyncValues can
apparently return a MSC and UST from the most recent physical vsync,
even if mpv didn't present a new frame on it. This might result in
different behaviour between the two backends after dropped frames or
brief pauses.

Also note, the docs for the DXGI presentation feedback APIs are pretty
awful, even by Microsoft standards. In particular the docs for
DXGI_FRAME_STATISTICS are misleading (PresentCount really is the number
of times Present() has been called for that frame, not "the running
total count of times that an image was presented to the monitor since
the computer booted.")

For good documentation, try these:
https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/dxgi-flip-model
https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dpresentstats
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/d3dkmthk/ns-d3dkmthk-_d3dkmt_present_stats

(Yeah, the docs for the D3D9Ex and even the kernel-mode version of this
structure are better than the DXGI ones. It seems possible that they're
all rewordings of the same internal Microsoft docs, but whoever wrote
the DXGI one didn't really understand it.)
2019-09-22 23:18:40 +10:00
dudemanguy 0f938b197a wayland: create current_output in wayland_reconfig
Certain mpv config options require wl->current_output to be created
before the video can actually start rendering. Just always create it
here if the current_output doesn't exist (the one exception being the
--fs option with no --fs-screen flag). Incidentally, this also fixes
--fs-screen not working on wayland.
2019-09-22 03:33:21 +00:00
Dudemanguy911 685e927fbe wayland: avoid handling a 0-value axis event
This shouldn't be possible, but an extra check never hurts.
2019-09-21 10:38:43 -05:00
emersion 600824494d wayland: read xcursor size from XCURSOR_SIZE env
This allows compositors to set the cursor size from user
configuration.
2019-09-21 15:43:54 +02:00
slatchurie 1591ccfff5 x11: fix ICC profiling for multiple monitors
To find the correct ICC profile X atom, the screen number was calculated
directly from the xrandr order of the screens.
But if a primary screen is set, it should be the first Xinerama screen,
even if it is not the first xrandr screen.

Calculate the the proper atom id for each screen.
2019-09-21 15:36:16 +02:00
dudemanguy cdad5cc65f wayland: don't show cursor when fullscreening 2019-09-21 15:24:06 +02:00
Thomas Weißschuh 9e304ab974 wayland: reconfigure cursor on pointer enter event
On wayland the cursor has to be configured each time the pointer enters.
Currently if the window (re)gains the focus, the pointer is not hidden,
even when configured. After the mouse has been moved the pointer hides
correctly.

https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_pointer:

    wl_pointer::enter - enter event

    ...

    When a seat's focus enters a surface, the pointer image is undefined
    and a client should respond to this event by setting an appropriate
    pointer image with the set_cursor request.

Fixes #6185.

Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
2019-09-21 15:24:06 +02:00
dudemanguy f54ad8eb05 wayland: add mouse buttons and fix axis scaling
Previously, the only mouse buttons supported in wayland were left,
right, and middle click. This adds the thumb back/forward buttons as
valid bindings. Also it removes the old, default behavior of always
sending a right click if an unrecognized mouse button is clicked.
In a related but different fix, the magnitude of an axis event in
wayland is not important to mpv since it internally handles all scaling.
The only thing we care about is getting the sign when the event occurs.
2019-09-21 14:35:03 +02:00
Cameron Cawley 70f8154b3d vo_sdl: Only create the SDL window once 2019-09-21 12:58:01 +02:00
memeka 0bdcbd75e0 context_drm_egl: Use eglGetPlatformDisplayEXT if available
Check if eglGetPlatformDisplayEXT is available and try to
use it to obtain the display connection. Fall back to eglGetDisplay
if eglGetPlatformDisplayEXT is not available or failing.

From PR #5992
2019-09-20 19:09:36 +02:00
wm4 4fa8f33b92 client API, vo_libmpv: document random deadlock problems
I guess trying to make DR work on libmpv was a mistake.

I never observed such a deadlock, but it's looks like it's theoretically
possible.
2019-09-20 16:47:16 +02:00