1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-21 23:23:19 +00:00

vo_opengl: angle: rewrite with custom swap chain

This replaces the old backend that exclusively used EGL windowing with
one that can also use ANGLE's ability to render to directly to a
texture. The advantage of this is that it allows mpv to create the swap
chain itself and this allows mpv to use a flip-mode swap chain on a HWND
(which avoids problems with DirectComposition) and to use a longer swap
chain that has six backbuffers by default (which reportedly fixes
problems with rendering 24fps video on 24Hz monitors.)

Also, "screenshot window" should now work on DXGI 1.2 and up (Windows 8
and up.)
This commit is contained in:
James Ross-Gowan 2017-02-04 19:16:02 +11:00
parent 5fbad204a6
commit e0250b9604
7 changed files with 761 additions and 277 deletions

View File

@ -4331,16 +4331,70 @@ The following video options are currently all specific to ``--vo=opengl`` and
Windows only.
``--opengl-dcomposition=<yes|no>``
Allows DirectComposition when using the ANGLE backend (default: yes).
DirectComposition implies flip-model presentation, which can improve
rendering efficiency on Windows 8+ by avoiding a copy of the video frame.
mpv uses it by default where possible, but it can cause poor behaviour with
some drivers, such as a black screen or graphical corruption when leaving
full-screen mode. Use "no" to disable it.
``--angle-d3d11-feature-level=<11_0|10_1|10_0|9_3>``
Selects a specific feature level when using the ANGLE backend with D3D11.
By default, the highest available feature level is used. This option can be
used to select a lower feature level, which is mainly useful for debugging.
Note that OpenGL ES 3.0 is only supported at feature level 10_1 or higher.
Most extended OpenGL features will not work at lower feature levels
(similar to ``--opengl-dumb-mode``).
Windows with ANGLE only.
``--angle-d3d11-warp=<yes|no|auto>``
Use WARP (Windows Advanced Rasterization Platform) when using the ANGLE
backend with D3D11 (default: auto). This is a high performance software
renderer. By default, it is used when the Direct3D hardware does not
support Direct3D 11 feature level 9_3. While the extended OpenGL features
will work with WARP, they can be very slow.
Windows with ANGLE only.
``--angle-egl-windowing=<yes|no|auto>``
Use ANGLE's built in EGL windowing functions to create a swap chain
(default: auto). If this is set to ``no`` and the D3D11 renderer is in use,
ANGLE's built in swap chain will not be used and a custom swap chain that
is optimized for video rendering will be created instead. If set to
``auto``, a custom swap chain will be used for D3D11 and the built in swap
chain will be used for D3D9. This option is mainly for debugging purposes,
in case the custom swap chain has poor performance or does not work.
If set to ``yes``, the ``--angle-max-frame-latency`` and
``--angle-swapchain-length`` options will have no effect.
Windows with ANGLE only.
``--angle-max-frame-latency=<1-16>``
Sets the maximum number of frames that the system is allowed to queue for
rendering with the ANGLE backend (default: 3). Lower values should make
VSync timing more accurate, but a value of ``1`` requires powerful
hardware, since the CPU will not be able to "render ahead" of the GPU.
Windows with ANGLE only.
``--angle-renderer=<d3d9|d3d11|auto>``
Forces a specific renderer when using the ANGLE backend (default: auto). In
auto mode this will pick D3D11 for systems that support Direct3D 11 feature
level 9_3 or higher, and D3D9 otherwise. This option is mainly for
debugging purposes. Normally there is no reason to force a specific
renderer, though ``--angle-renderer=d3d9`` may give slightly better
performance on old hardware. Note that the D3D9 renderer only supports
OpenGL ES 2.0, so most extended OpenGL features will not work if this
renderer is selected (similar to ``--opengl-dumb-mode``).
Windows with ANGLE only.
``--angle-swapchain-length=<2-16>``
Sets the number of buffers in the D3D11 presentation queue when using the
ANGLE backend (default: 6). At least 2 are required, since one is the back
buffer that mpv renders to and the other is the front buffer that is
presented by the DWM. Additional buffers can improve performance, because
for example, mpv will not have to wait on the DWM to release the front
buffer before rendering a new frame to it. For this reason, Microsoft
recommends at least 4.
Windows 8+ with ANGLE only.
``--opengl-sw``
Continue even if a software renderer is detected.

View File

@ -22,6 +22,7 @@
#include <errors.h>
#include <audioclient.h>
#include <d3d9.h>
#include <dxgi1_2.h>
#include "windows_utils.h"
@ -118,6 +119,13 @@ static char *hresult_to_str(const HRESULT hr)
E(D3DERR_CANNOTPROTECTCONTENT)
E(D3DERR_UNSUPPORTEDCRYPTO)
E(D3DERR_PRESENT_STATISTICS_DISJOINT)
E(DXGI_ERROR_DEVICE_HUNG)
E(DXGI_ERROR_DEVICE_REMOVED)
E(DXGI_ERROR_DEVICE_RESET)
E(DXGI_ERROR_DRIVER_INTERNAL_ERROR)
E(DXGI_ERROR_INVALID_CALL)
E(DXGI_ERROR_WAS_STILL_DRAWING)
E(DXGI_STATUS_OCCLUDED)
default:
return "<Unknown>";
}

View File

@ -45,9 +45,12 @@
(EGLDisplay, EGLint)) \
FN(eglSwapBuffers, EGLBoolean (*EGLAPIENTRY PFN_eglSwapBuffers) \
(EGLDisplay, EGLSurface)) \
FN(eglSwapInterval, EGLBoolean (*EGLAPIENTRY PFN_eglSwapInterval) \
(EGLDisplay, EGLint)) \
FN(eglReleaseTexImage, EGLBoolean (*EGLAPIENTRY PFN_eglReleaseTexImage) \
(EGLDisplay, EGLSurface, EGLint)) \
FN(eglTerminate, EGLBoolean (*EGLAPIENTRY PFN_eglTerminate)(EGLDisplay))
FN(eglTerminate, EGLBoolean (*EGLAPIENTRY PFN_eglTerminate)(EGLDisplay)) \
FN(eglWaitClient, EGLBoolean (*EGLAPIENTRY PFN_eglWaitClient)(void))
#define ANGLE_EXT_DECL(NAME, VAR) \
extern VAR;
@ -76,7 +79,9 @@ bool angle_load(void);
#define eglQueryString PFN_eglQueryString
#define eglReleaseTexImage PFN_eglReleaseTexImage
#define eglSwapBuffers PFN_eglSwapBuffers
#define eglSwapInterval PFN_eglSwapInterval
#define eglTerminate PFN_eglTerminate
#define eglWaitClient PFN_eglWaitClient
#endif
#endif

View File

@ -57,7 +57,6 @@ static const struct mpgl_driver *const backends[] = {
#endif
#if HAVE_EGL_ANGLE
&mpgl_driver_angle,
&mpgl_driver_angle_es2,
#endif
#if HAVE_GL_WIN32
&mpgl_driver_w32,

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,12 @@
#include "common.h"
#include "context.h"
#ifdef HAVE_EGL_ANGLE
// On Windows, egl_helpers.c is only used by ANGLE, where the EGL functions may
// be loaded dynamically from ANGLE DLLs
#include "angle_dynamic.h"
#endif
// EGL 1.5
#ifndef EGL_CONTEXT_OPENGL_PROFILE_MASK
#define EGL_CONTEXT_MAJOR_VERSION 0x3098

View File

@ -792,7 +792,8 @@ video_output_features = [
}, {
'name': 'egl-helpers',
'desc': 'EGL helper functions',
'deps_any': [ 'egl-x11', 'mali-fbdev', 'rpi', 'gl-wayland', 'egl-drm' ],
'deps_any': [ 'egl-x11', 'mali-fbdev', 'rpi', 'gl-wayland', 'egl-drm',
'egl-angle' ],
'func': check_true
}
]