Commit Graph

186 Commits

Author SHA1 Message Date
Niklas Haas dd78cc6fe7 vo_opengl: refactor vo performance subsystem
This replaces `vo-performance` by `vo-passes`, bringing with it a number
of changes and improvements:

1. mpv users can now introspect the vo_opengl passes, which is something
   that has been requested multiple times.

2. performance data is now measured per-pass, which helps both
   development and debugging.

3. since adding more passes is cheap, we can now report information for
   more passes (e.g. the blit pass, and the osd pass). Note: we also
   switch to nanosecond scale, to be able to measure these passes
   better.

4. `--user-shaders` authors can now describe their own passes, helping
   users both identify which user shaders are active at any given time
   as well as helping shader authors identify performance issues.

5. the timing data per pass is now exported as a full list of samples,
   so projects like Argon-/mpv-stats can immediately read out all of the
   samples and render a graph without having to manually poll this
   option constantly.

Due to gl_timer's design being complicated (directly reading performance
data would block, so we delay the actual read-back until the next _start
command), it's vital not to conflate different passes that might be
doing different things from one frame to another. To accomplish this,
the actual timers are stored as part of the gl_shader_cache's sc_entry,
which makes them unique for that exact shader.

Starting and stopping the time measurement is easy to unify with the
gl_sc architecture, because the existing API already relies on a
"generate, render, reset" flow, so we can just put timer_start and
timer_stop in sc_generate and sc_reset, respectively.

The ugliest thing about this code is that due to the need to keep pass
information relatively stable in between frames, we need to distinguish
between "new" and "redrawn" frames, which bloats the code somewhat and
also feels hacky and vo_opengl-specific. (But then again, this entire
thing is vo_opengl-specific)
2017-07-01 00:58:27 +02:00
wm4 b0cbda84ed vo_opengl: add a backend start_frame callback for context_vdpau
Might be useful for other backends too. For context_vdpau, resize
handling, presentation, and handling the mapping state becomes somewhat
less awkward.
2017-03-20 13:37:47 +01:00
wm4 8fb9cc2534 vo_opengl: read framebuffer depth from actual FBO used for rendering
In some cases, such as when using the libmpv opengl-cb API, or with
certain vo_opengl backends, the main framebuffer is never accessed.
Instead, rendering is done to a FBO that acts as back buffer. This meant
an incorrect/broken bit depth could be used for dithering.

Change it to read the framebuffer depth lazily on the first render call.

Also move the main FBO field out of the GL struct to MPGLContext,
because the renderer's init function does not need to access it anymore.
2017-03-20 13:31:28 +01:00
wm4 7e4a73c8e4 vo_opengl: add a --opengl-es=force2 option
Useful for testing. Unfortunately, the nVidia EGL driver ignores this,
and returns a GLES 3.2 context anyway (which it is allowed to do). Might
still be useable with ANGLE, which will really give you a GLES 2 context
if you ask for it.
2017-03-20 04:57:51 +01:00
wm4 eae12bf963 vo: fix subtleties in the redrawing logic
This fixes a race condition created by the previous commit, and possibly
others. Sometimes interpolated frames weren't redrawn as uninterpolated
ones.

The problem is that redrawing/drawing a frame can't reset the VO
want_redraw flags, because logically these have to happen after the core
acknowledged and explicitly reissued a redraw. The core needs to be
involved because the OSD text and drawings could depend on the playback
or window state.

Change it such that it always goes through the core.

Also, VOs inconsistently called vo_wakeup() when setting want_redraw,
which is also taken care of by this commit.
2017-02-21 15:39:44 +01:00
wm4 fd203ff16a options: refacactor how --opengl-dwmflush is declared
Same deal as previous commit, except this time we just readd it as lone
global option, and read it directly.
2017-01-20 14:03:34 +01:00
wm4 d890e0731c options: refactor how --opengl-dcomposition is declared
vo_opengl used to have it as sub-option, which made it very hard to pass
down option values to backends in a generic way (even if these options
were completely backend-specific). For --opengl-dcomposition we used a
VOFLAG to deal with this. Fortunately, sub-options are gone, and we can
just add it as global option.

Move the option to context_angle.c and add it as global option. I
thought about adding a mechanism to let backends declare options, which
would get magically picked up my m_config instead of having to add them
to the global option list manually (similar to VO vo_driver.options),
but decided against this complexity just for 1 or 2 backends. Likewise,
it could have been added as a single option to avoid the boilerplate of
an option struct, but then again there are probably going to be more
angle suboptions, and it's cleaner.
2017-01-20 13:40:59 +01:00
wm4 9d68d8fb0f vo_opengl, vo_opengl_cb: better hwdec interop backend selection
Introduce the --opengl-hwdec-interop option, which replaces
--hwdec-preload. The new option allows explicit selection of the interop
backend.

This is relatively complex, and I would have preferred not to add this,
but it's probably useful to debug certain problems. In exchange, the
"new" option documents that pretty much any but the simplest use of it
will not be forward compatible.
2017-01-17 15:48:56 +01:00
wm4 09238a9bb5 vo_opengl: don't rely on viewport to contain window dimensions
Apparently we don't always set the viewport to window dimensions
anymore, e.g. if nothing is actually rendered. This means the viewport
can contain old values.

The window screenshot code uses the viewport values to guess the default
framebuffer dimensions. With --force-window --idle --no-osc (which draws
nothing and issues a glClear() command only), taking a screenshot would
yield an image with the wrong size and possibly garbage in it. Fix this
by explicitly passing the currently known window dimensions. Abusing the
values stored in the viewport was questionable anyway.
2016-12-02 15:26:45 +01:00
wm4 1a2319f3e4 options: remove deprecated sub-option handling for --vo and --ao
Long planned. Leads to some sanity.

There still are some rather gross things. Especially g_groups is ugly,
and a hack that can hopefully be removed. (There is a plan for it, but
whether it's implemented depends on how much energy is left.)
2016-11-25 21:17:25 +01:00
wm4 9a873cc53b vo_opengl: redirect window screenshot requests to backend
If the glReadPixels method is not available, let the backend do it.

Useful for the next commit.
2016-09-12 19:58:58 +02:00
wm4 7177ef3e1c vo: remove unused VOCTRL_GET_PANSCAN
It was used to determine whether the VO supports VOCTRL_SET_PANSCAN.
With all those changes to property semantics this became unnecessary,
and its only use was dropped at some point.
2016-09-08 18:59:21 +02:00
wm4 4ab860cddc options: add a mechanism to make sub-option replacement slightly easier
Instead of requiring each VO or AO to manually add members to MPOpts and
the global option table, make it possible to register them automatically
via vo_driver/ao_driver.global_opts members. This avoids modifying
options.c/options.h every time, including having to duplicate the exact
ifdeffery used to enable a driver.
2016-09-05 21:04:17 +02:00
wm4 849480d0c9 vo_opengl: deprecate sub-options, add them as global options
vo_opengl sub-option were always rather annoying to handle. It seems
better to make them global options instead. This is simpler and easier
to use. The only disadvantage we are aware of is that it's not clear
that many/all of these new global options work with vo_opengl only.

--vo=opengl-hq is also deprecated.

There is extensive compatibility with the old behavior. One exception is
that --vo-defaults will not apply to opengl-hq (though with opengl it
still works). vo-cmdline is also dysfunctional and will be removed in a
following commit.

These changes also affect opengl-cb.

The update mechanism is still rather inefficient: it requires syncing
with the VO after each option change, rather than batching updates.
There's also no granularity (video.c just updates "everything", and if
auto-ICC profiles are enabled, vo_opengl.c will fetch them on each
update).

Most of the manpage changes were done by Niklas Haas <git@haasn.xyz>.
2016-09-02 21:21:47 +02:00
wm4 b2657814c9 vo_opengl: minor renderer option access refactor
Reduce accesses to the renderer opts in vo_opengl.c, and instead add
accessors for them to video.c.

I suppose gamma and maybe icc-auto could be moved to vo_opengl.c
options. Also, the output colorspace could probably be adjusted to what
is really used, not just the options (although it's possible that this
commit changes this, due to video.c mutating its own copy of the options
according to actual renderer capapbilities).

But don't deal with this now.
2016-09-02 14:50:03 +02:00
Avi Halachmi (:avih) ef0b2e33b1 vo_opengl: angle: new opengl flag to control DirectComposition
On some systems DirectComposition might behave poorly. Add an opengl
suboption flag 'dcomposition' (default=yes) which can disable it.
2016-08-25 23:47:37 +10:00
wm4 99d9921f39 vo_opengl: glctx can be NULL during init
This fixes a crash that can happen with the Cocoa backend: it calls
vo_wakeup() during init, which calls vo_opengl.c/wakeup().

Fixes #3360.
2016-07-21 16:07:15 +02:00
wm4 bd9c0a10e5 vo_opengl: allow backends to provide callbacks for custom event loops
Until now, this has been either handled over vo.event_fd (which should
go away), or by putting event handling on a separate thread. The
backends which do the latter do it for a reason and won't need this, but
X11 and Wayland will, in order to get rid of event_fd.
2016-07-20 20:42:30 +02:00
Niklas Haas d81fb97f45 mp_image: split colorimetry metadata into its own struct
This has two reasons:

1. I tend to add new fields to this metadata, and every time I've done
so I've consistently forgotten to update all of the dozens of places in
which this colorimetry metadata might end up getting used. While most
usages don't really care about most of the metadata, sometimes the
intend was simply to “copy” the colorimetry metadata from one struct to
another. With this being inside a substruct, those lines of code can now
simply read a.color = b.color without having to care about added or
removed fields.

2. It makes the type definitions nicer for upcoming refactors.

In going through all of the usages, I also expanded a few where I felt
that omitting the “young” fields was a bug.
2016-07-03 19:42:52 +02:00
wm4 4a15bc6d73 vo_opengl: add ability to render to an arbitrary backing framebuffer
Most of the functionality already exists for the sake of vo_opengl_cb.
We only have to use it.

This will be used by dxinterop in the following commit.
2016-06-18 15:16:29 +02:00
Niklas Haas 393a069112 vo_opengl: expose performance timers as properties
This is plumbed through a new VOCTRL, VOCTRL_PERFORMANCE_DATA, and
exposed as properties render-time-last, render-time-avg etc.

All of these numbers are in microseconds, which gives a good precision
range when just outputting them via show-text. (Lua scripts can
obviously still do their own formatting etc.)

Signed-off-by: wm4 <wm4@nowhere>
2016-06-07 12:17:25 +02:00
wm4 c1cb04b6a3 vo_opengl: apply vo-cmdline command incrementally
Instead of implicitly resetting the options to defaults and then
applying the options, they're always applied on top of the current
options (in the same way adding new options to the CLI command line
will).

This does not apply to vo_opengl_cb, because that has an even worse mess
which I refuse to deal with.
2016-06-05 16:56:34 +02:00
wm4 b3a3ed00f0 vo_opengl: possibly update icc profile after changing options
Changing the options can enable icc-profile-auto, and in this case the
profile has to be reteieved again from the system.
2016-06-05 12:21:47 +02:00
wm4 026b75e7f5 vo_opengl: move all icc handling from vo_opengl.c to video.c
Originally, video.c did not access any CMS things (other than lut3d
being set on it), but this has changed. In practice, almost all accesses
to it have moved to video.c. vo_opengl only created it, and set the auto
icc profile path.

Complete the move.

Some things wrt. option handling are a bit fishy. (But when is this not
the case.)

icc-profile-auto was not tested, but the distributed human CI will take
care of it.
2016-06-03 20:35:22 +02:00
wm4 e5f49d9685 vo_opengl: always autoselect ANGLE as backend if available
Remove the opengl-hq option default that caused it not to autoselect
ANGLE (unlike --vo=opengl). Details see commit d5df90a2.

Back then the intention was to use ANGLE by default, since it integrates
much nicer with the Windows compositor (instead of native OpenGL, which
tends to cause crazy glitches). On the other hand, many opengl-hq
capabilities are not available with older ANGLE builds, so it didn't
make any sense to autoselect ANGLE for it.

With the GL_EXT_texture_norm16 extension recently added to ANGLE, it has
essentially reached feature parity to desktop GL for the subset we are
using. (Even the integer texture hack for high bit depth input could be
dropped now.)

It (probably) still does not support nnedi3, due to the weird way the NN
coefficients are imported. Also, it uses half-floats instead of 16 bit
fixed-point textures for technical reasons, which implies about 5 bits
of precision loss. If anyone actually manages to distinguish the two
dithering texture formats in a double-blind test, I will fix it.
2016-05-26 00:07:10 +02:00
wm4 c4707cdee6 vo_opengl: fix other minor namespace issues
See previous commit.
2016-05-23 21:27:18 +02:00
wm4 fe540f4477 vo_opengl: fix NULL deref on certain init failures 2016-05-11 17:12:59 +02:00
wm4 46fff8d31a video: refactor how VO exports hwdec device handles
The main change is with video/hwdec.h. mp_hwdec_info is made opaque (and
renamed to mp_hwdec_devices). Its accessors are mainly thread-safe (or
documented where not), which makes the whole thing saner and cleaner. In
particular, thread-safety rules become less subtle and more obvious.

The new internal API makes it easier to support multiple OpenGL interop
backends. (Although this is not done yet, and it's not clear whether it
ever will.)

This also removes all the API-specific fields from mp_hwdec_ctx and
replaces them with a "ctx" field. For d3d in particular, we drop the
mp_d3d_ctx struct completely, and pass the interfaces directly.

Remove the emulation checks from vaapi.c and vdpau.c; they are
pointless, and the checks that matter are done on the VO layer.

The d3d hardware decoders might slightly change behavior: dxva2-copy
will not use the VO device anymore if the VO supports proper interop.
This pretty much assumes that any in such cases the VO will not use any
form of exclusive mode, which makes using the VO device in copy mode
unnecessary.

This is a big refactor. Some things may be untested and could be broken.
2016-05-09 20:03:22 +02:00
Niklas Haas 2dcf18c0c0 vo_opengl: generate 3DLUT against source and use full BT.1886
This commit refactors the 3DLUT loading mechanism to build the 3DLUT
against the original source characteristics of the file. This allows us,
among other things, to use a real BT.1886 profile for the source. This
also allows us to actually use perceptual mappings. Finally, this
reduces errors on standard gamut displays (where the previous 3DLUT
target of BT.2020 was unreasonably wide).

This also improves the overall accuracy of the 3DLUT due to eliminating
rounding errors where possible, and allows for more accurate use of
LUT-based ICC profiles.

The current code is somewhat more ugly than necessary, because the idea
was to implement this commit in a working state first, and then maybe
refactor the profile loading mechanism in a later commit.

Fixes #2815.
2016-04-01 10:27:27 +02:00
wm4 e4ec0f42e4 Change GPL/LGPL dual-licensed files to LGPL
Do this to make the license situation less confusing.

This change should be of no consequence, since LGPL is compatible with
GPL anyway, and making it LGPL-only does not restrict the use with GPL
code.

Additionally, the wording implies that this is allowed, and that we can
just remove the GPL part.
2016-01-19 18:36:34 +01:00
Dmitrij D. Czarkoff ea442fa047 mpv_talloc.h: rename from talloc.h
This change helps avoiding conflict with talloc.h from libtalloc.
2016-01-11 21:05:55 +01:00
wm4 504286b006 vo_opengl: flip image if backend uses flipped rendering
Should fix #2635 (untested).
2015-12-25 15:08:41 +01:00
wm4 6154c1d06d vo_opengl: split backend code from common.c to context.c
Now common.c only contains the code for the function loader, while
context.c contains the backend loader/dispatcher.

Not calling it "backend.c", because the central struct is called
MPGLContext.
2015-12-19 14:14:12 +01:00
wm4 3394d37b4e vo_opengl: refactor how framebuffer depth is passed from backends
Store the determined framebuffer depth in struct GL instead of
MPGLContext. This means gl_video_set_output_depth() can be removed, and
also justifies adding new fields describing framebuffer/backend
properties to struct GL instead of having to add more functions just to
shovel the information around.

Keep in mind that mpgl_load_functions() will wipe struct GL, so the
new fields must be set before calling it.
2015-12-19 14:14:12 +01:00
James Ross-Gowan 3d12312806
vo_opengl: add dxinterop backend
WGL_NV_DX_interop is widely supported by Nvidia and AMD drivers. It
allows a texture to be shared between Direct3D and WGL, so that
rendering can be done with WGL and presentation can be done with
Direct3D. This should allow us to work around some persistent WGL
issues, such as dropped frames with some driver/OS combos, drivers that
buffer frames to increase performance at the cost of latency, and the
inability to disable exclusive fullscreen mode when using WGL to render
to a fullscreen window.

The addition of a DX_interop backend might also enable some cool
Direct3D-specific enhancements in the future, such as using the
GetPresentStatistics API to get accurate frame presentation timestamps.

Note that due to a driver bug, this backend is currently broken on
Intel. It will appear to work as long as the window is not resized too
often, but after a few changes of size it will be unable to share the
newly created renderbuffer with GL. See:
https://software.intel.com/en-us/forums/graphics-driver-bug-reporting/topic/562051
2015-12-11 18:29:18 +01:00
wm4 d5df90a295 vo_opengl: use ANGLE by default if available (except for "hq" preset)
Running mpv with default config will now pick up ANGLE by default. Since
some think ANGLE is still not good enough for hq features, extend the
"es" option to reject GLES backends, and add to to the opengl-hq preset.

One consequence is that mpv will by default use libswscale to convert
10 bit video to 8 bit, before it reaches the VO.
2015-11-21 18:17:14 +01:00
wm4 0ec35fa111 videotoolbox: make decoder format customizable
Because apparently there's no ideal universally working format.

The weird OpenGL texture format for kCVPixelFormatType_32BGRA is from:

http://stackoverflow.com/questions/22077544/draw-an-iosurface-to-an-opengl-context

(Which apparently got it from the linked Apple example code.)
2015-11-17 21:21:19 +01:00
wm4 4682b0147e vo_opengl: move the glFlush() call to the renderer 2015-11-10 14:36:23 +01:00
wm4 76e50f6a3d vo_opengl: always preload hwdec interop
Simplifies some auto detection matters.

I _still_ don't want to remove the lazy loading mechanism, because it's
still slightly useful for filters using the hwdec APIs. My main
motivation for not always preloading them is actually that libva prints
random useless crap to the terminal with no way to prevent this.
2015-11-09 11:57:11 +01:00
wm4 30a6106477 vo_opengl: win32: try to enable DwmFlush by default
Enable it by default, but not unconditionally. Add an "auto" mode, which
disable DwmFlush if the compositor is (probably) inactive. Let's see how
this goes.

Since I accidentally enabled DwmFlush always by default (more or less)
in a previous commit touching this code, this is probably mostly just
cargo-culting, and it's uncertain whether it does anything.

Note that I still got bad vsync behavior when fullscreening mpv, and
making another window visible on the same screen. This happens even if
forcing DWM.
2015-11-01 20:47:57 +01:00
wm4 2b6241a09a vo_opengl: add vsync-fences option
Yet another relatively useless option that tries to make OpenGL's sync
behavior somewhat sane. The results are not too encouraging. With a
value of 1, vsync jitter is gone on nVidia, but there are frame drops
(less than with glfinish). With 2, I get the usual vsync jitter _and_
frame drops.

There's still some hope that it might prevent too deep queuing with some
GPUs, I guess.

The timeout for the wait call is 1 second. The value is pretty
arbitrary; it should just not be too high to freeze the process (if
the GPU is un-nice), and not too low to trigger the timeout in normal
cases, even if the GPU load is very high. So I guess 1 second is ok
as a timeout.

The idea to use fences this way to control the queue depth was stolen
from RetroArch:

df01279cf3/gfx/drivers/gl.c (L1856)
2015-10-30 20:26:51 +01:00
wm4 93f748e77f vo_opengl: cosmetics: flip the order of 2 functions
draw_frame() is called first, then flip_page(). Order them in the order
they're called.
2015-10-30 20:26:43 +01:00
wm4 291f301c10 video/out: remove an unused parameter
This parameter has been unused for years (the last flag was removed in
commit d658b115). Get rid of it.

This affects the general VO API, as well as the vo_opengl backend API,
so it touches a lot of files.

The VOFLAGs are still used to control OpenGL context creation, so move
them to the OpenGL backend code.
2015-10-03 18:20:16 +02:00
wm4 69bc7e34b9 vo_opengl: refactor DwmFlush crap
Get it out of the way in the common code. MPGLContext.dwm_flush_opt can
be removed as well as soon as the option system gets overhauled.
2015-10-02 17:59:05 +02:00
wm4 f4d62da8f0 vo_opengl: cocoa: switch to new internal API 2015-10-01 22:42:25 +02:00
wm4 98c4ab6d13 vo_opengl: make sw suboption work without explicit backend selection
You needed to select a GL backend with the backend suboption. This was
confusing.

Fixes #2361.
2015-10-01 20:57:29 +02:00
Niklas Haas 44eda2177d vo_opengl: remove gl_ prefixes from files in video/out/opengl
This is a bit redundant with the name of the directory itself, and not
in line with existing naming conventions.
2015-09-09 18:09:31 +02:00
Niklas Haas deebc55014 vo_opengl: move gl_* files to their own subdir
This is mainly just to keep things a bit more organized and separated
inside the codebase.
2015-09-09 18:09:25 +02:00
wm4 6238491688 vo_opengl: force redraw when framestepping with interpolation
This might fix some problems when framestepping with interpolation
enabled. The problem here is that we want to show the non-interpolated
frame while paused. Framestepping is like unpausing the video for a
frame, and then pausing again. This draws an interpolated frame, and
redrawing on pausing is supposed to take care of this.

This possibly didn't always work, because vo->want_redraw is not checked
by the vo_control() code path. So wake up the VO thread (which takes
care of servicing redraw requests, kind of) explicitly.

The correct solution is getting rid of the public-writable want_redraw
field and replacing it with a new vo_request_redraw() function, but this
can come later.
2015-08-25 21:31:37 +02:00
wm4 1e4113040c vo_opengl: remove dead code
Leftover from 3245bfef.
2015-08-22 21:05:32 +02:00