vo_gpu: convert windows/osx hwdecs/contexts to new API

This commit is contained in:
James Ross-Gowan 2017-09-16 01:37:28 +10:00 committed by Niklas Haas
parent 65979986a9
commit 75c0c06640
11 changed files with 410 additions and 362 deletions

View File

@ -4541,14 +4541,6 @@ The following video options are currently all specific to ``--vo=gpu`` and
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
@ -4561,17 +4553,6 @@ The following video options are currently all specific to ``--vo=gpu`` and
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 with ANGLE only.
``--cocoa-force-dedicated-gpu=<yes|no>``
Deactivates the automatic graphics switching and forces the dedicated GPU.
(default: no)

View File

@ -40,7 +40,7 @@ extern const struct ra_ctx_fns ra_ctx_cocoa;
extern const struct ra_ctx_fns ra_ctx_wayland_egl;
extern const struct ra_ctx_fns ra_ctx_wgl;
extern const struct ra_ctx_fns ra_ctx_angle;
extern const struct ra_ctx_fns ra_ctx_dxinterop;
extern const struct ra_ctx_fns ra_ctx_dxgl;
extern const struct ra_ctx_fns ra_ctx_rpi;
extern const struct ra_ctx_fns ra_ctx_mali;
extern const struct ra_ctx_fns ra_ctx_vdpauglx;
@ -50,7 +50,6 @@ static const struct ra_ctx_fns *contexts[] = {
#if HAVE_RPI
&ra_ctx_rpi,
#endif
/*
#if HAVE_GL_COCOA
&ra_ctx_cocoa,
#endif
@ -61,9 +60,8 @@ static const struct ra_ctx_fns *contexts[] = {
&ra_ctx_wgl,
#endif
#if HAVE_GL_DXINTEROP
&ra_ctx_dxinterop,
&ra_ctx_dxgl,
#endif
*/
#if HAVE_GL_X11
&ra_ctx_glx_probe,
#endif

View File

@ -31,6 +31,7 @@
#include "video/out/w32_common.h"
#include "osdep/windows_utils.h"
#include "context.h"
#include "utils.h"
#ifndef EGL_D3D_TEXTURE_ANGLE
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
@ -52,8 +53,6 @@ struct angle_opts {
int d3d11_warp;
int d3d11_feature_level;
int egl_windowing;
int swapchain_length; // Currently only works with DXGI 1.2+
int max_frame_latency;
int flip;
};
@ -77,9 +76,9 @@ const struct m_sub_options angle_conf = {
({"auto", -1},
{"no", 0},
{"yes", 1})),
OPT_INTRANGE("angle-swapchain-length", swapchain_length, 0, 2, 16),
OPT_INTRANGE("angle-max-frame-latency", max_frame_latency, 0, 1, 16),
OPT_FLAG("angle-flip", flip, 0),
OPT_REPLACED("angle-max-frame-latency", "swapchain-depth"),
OPT_REMOVED("angle-swapchain-length", "controlled by --swapchain-depth"),
{0}
},
.defaults = &(const struct angle_opts) {
@ -87,14 +86,14 @@ const struct m_sub_options angle_conf = {
.d3d11_warp = -1,
.d3d11_feature_level = D3D_FEATURE_LEVEL_11_0,
.egl_windowing = -1,
.swapchain_length = 6,
.max_frame_latency = 3,
.flip = 1,
},
.size = sizeof(struct angle_opts),
};
struct priv {
GL gl;
IDXGISwapChain *dxgi_swapchain;
ID3D11Device *d3d11_device;
@ -110,20 +109,21 @@ struct priv {
int sc_width, sc_height; // Swap chain width and height
int swapinterval;
bool flipped;
struct angle_opts *opts;
};
static __thread struct MPGLContext *current_ctx;
static __thread struct ra_ctx *current_ctx;
static void update_sizes(MPGLContext *ctx)
static void update_sizes(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
p->sc_width = ctx->vo->dwidth ? ctx->vo->dwidth : 1;
p->sc_height = ctx->vo->dheight ? ctx->vo->dheight : 1;
}
static void d3d11_backbuffer_release(MPGLContext *ctx)
static void d3d11_backbuffer_release(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
@ -137,7 +137,7 @@ static void d3d11_backbuffer_release(MPGLContext *ctx)
SAFE_RELEASE(p->d3d11_backbuffer);
}
static bool d3d11_backbuffer_get(MPGLContext *ctx)
static bool d3d11_backbuffer_get(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@ -168,7 +168,7 @@ static bool d3d11_backbuffer_get(MPGLContext *ctx)
return true;
}
static void d3d11_backbuffer_resize(MPGLContext *ctx)
static void d3d11_backbuffer_resize(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@ -197,7 +197,7 @@ static void d3d11_backbuffer_resize(MPGLContext *ctx)
MP_FATAL(vo, "Couldn't get back buffer after resize\n");
}
static void d3d11_device_destroy(MPGLContext *ctx)
static void d3d11_device_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
@ -215,7 +215,7 @@ static void d3d11_device_destroy(MPGLContext *ctx)
SAFE_RELEASE(p->d3d11_device);
}
static bool d3d11_device_create(MPGLContext *ctx, int flags)
static bool d3d11_device_create(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@ -226,7 +226,7 @@ static bool d3d11_device_create(MPGLContext *ctx, int flags)
.force_warp = o->d3d11_warp == 1,
.max_feature_level = o->d3d11_feature_level,
.min_feature_level = D3D_FEATURE_LEVEL_9_3,
.max_frame_latency = o->max_frame_latency,
.max_frame_latency = ctx->opts.swapchain_depth,
};
if (!mp_d3d11_create_present_device(vo->log, &device_opts, &p->d3d11_device))
return false;
@ -262,7 +262,7 @@ static bool d3d11_device_create(MPGLContext *ctx, int flags)
return true;
}
static void d3d11_swapchain_surface_destroy(MPGLContext *ctx)
static void d3d11_swapchain_surface_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
@ -277,7 +277,7 @@ static void d3d11_swapchain_surface_destroy(MPGLContext *ctx)
ID3D11DeviceContext_Flush(p->d3d11_context);
}
static bool d3d11_swapchain_surface_create(MPGLContext *ctx, int flags)
static bool d3d11_swapchain_surface_create(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@ -292,7 +292,9 @@ static bool d3d11_swapchain_surface_create(MPGLContext *ctx, int flags)
.width = p->sc_width,
.height = p->sc_height,
.flip = o->flip,
.length = o->swapchain_length,
// Add one frame for the backbuffer and one frame of "slack" to reduce
// contention with the window manager when acquiring the backbuffer
.length = ctx->opts.swapchain_depth + 2,
.usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT,
};
if (!mp_d3d11_create_swapchain(p->d3d11_device, vo->log, &swapchain_opts,
@ -301,8 +303,7 @@ static bool d3d11_swapchain_surface_create(MPGLContext *ctx, int flags)
if (!d3d11_backbuffer_get(ctx))
goto fail;
// EGL_D3D_TEXTURE_ANGLE pbuffers are always flipped vertically
ctx->flip_v = true;
p->flipped = true;
return true;
fail:
@ -310,7 +311,7 @@ fail:
return false;
}
static void d3d9_device_destroy(MPGLContext *ctx)
static void d3d9_device_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
@ -319,7 +320,7 @@ static void d3d9_device_destroy(MPGLContext *ctx)
p->egl_display = EGL_NO_DISPLAY;
}
static bool d3d9_device_create(MPGLContext *ctx, int flags)
static bool d3d9_device_create(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@ -348,7 +349,7 @@ static bool d3d9_device_create(MPGLContext *ctx, int flags)
return true;
}
static void egl_window_surface_destroy(MPGLContext *ctx)
static void egl_window_surface_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
if (p->egl_window) {
@ -357,7 +358,7 @@ static void egl_window_surface_destroy(MPGLContext *ctx)
}
}
static bool egl_window_surface_create(MPGLContext *ctx, int flags)
static bool egl_window_surface_create(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@ -374,7 +375,7 @@ static bool egl_window_surface_create(MPGLContext *ctx, int flags)
EGL_SURFACE_ORIENTATION_ANGLE);
MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len,
EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE);
ctx->flip_v = true;
p->flipped = true;
MP_VERBOSE(vo, "Rendering flipped.\n");
}
}
@ -396,7 +397,7 @@ fail:
return false;
}
static void context_destroy(struct MPGLContext *ctx)
static void context_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
if (p->egl_context) {
@ -407,7 +408,7 @@ static void context_destroy(struct MPGLContext *ctx)
p->egl_context = EGL_NO_CONTEXT;
}
static bool context_init(struct MPGLContext *ctx, int flags)
static bool context_init(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@ -421,8 +422,8 @@ static bool context_init(struct MPGLContext *ctx, int flags)
if (exts)
MP_DBG(vo, "EGL extensions: %s\n", exts);
if (!mpegl_create_context(p->egl_display, vo->log, flags | VOFLAG_GLES,
&p->egl_context, &p->egl_config))
if (!mpegl_create_context(ctx, p->egl_display, &p->egl_context,
&p->egl_config))
{
MP_FATAL(vo, "Could not create EGL context!\n");
goto fail;
@ -434,10 +435,12 @@ fail:
return false;
}
static void angle_uninit(struct MPGLContext *ctx)
static void angle_uninit(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
ra_gl_ctx_uninit(ctx);
DwmEnableMMCSS(FALSE);
// Uninit the EGL surface implementation that is being used. Note: This may
@ -474,17 +477,56 @@ static int GLAPIENTRY angle_swap_interval(int interval)
}
}
static int angle_init(struct MPGLContext *ctx, int flags)
static void d3d11_swap_buffers(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
// Calling Present() on a flip-sequential swap chain will silently change
// the underlying storage of the back buffer to point to the next buffer in
// the chain. This results in the RTVs for the back buffer becoming
// unbound. Since ANGLE doesn't know we called Present(), it will continue
// using the unbound RTVs, so we must save and restore them ourselves.
ID3D11RenderTargetView *rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0};
ID3D11DepthStencilView *dsv = NULL;
ID3D11DeviceContext_OMGetRenderTargets(p->d3d11_context,
MP_ARRAY_SIZE(rtvs), rtvs, &dsv);
HRESULT hr = IDXGISwapChain_Present(p->dxgi_swapchain, p->swapinterval, 0);
if (FAILED(hr))
MP_FATAL(ctx->vo, "Couldn't present: %s\n", mp_HRESULT_to_str(hr));
// Restore the RTVs and release the objects
ID3D11DeviceContext_OMSetRenderTargets(p->d3d11_context,
MP_ARRAY_SIZE(rtvs), rtvs, dsv);
for (int i = 0; i < MP_ARRAY_SIZE(rtvs); i++)
SAFE_RELEASE(rtvs[i]);
SAFE_RELEASE(dsv);
}
static void egl_swap_buffers(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
eglSwapBuffers(p->egl_display, p->egl_window);
}
static void angle_swap_buffers(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
if (p->dxgi_swapchain)
d3d11_swap_buffers(ctx);
else
egl_swap_buffers(ctx);
}
static bool angle_init(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
struct vo *vo = ctx->vo;
GL *gl = &p->gl;
p->opts = mp_get_config_group(ctx, ctx->global, &angle_conf);
struct angle_opts *o = p->opts;
// DWM MMCSS cargo-cult. The dxinterop backend also does this.
DwmEnableMMCSS(TRUE);
if (!angle_load()) {
MP_VERBOSE(vo, "Failed to load LIBEGL.DLL\n");
goto fail;
@ -493,19 +535,19 @@ static int angle_init(struct MPGLContext *ctx, int flags)
// Create the underlying EGL device implementation
bool context_ok = false;
if ((!context_ok && !o->renderer) || o->renderer == RENDERER_D3D11) {
context_ok = d3d11_device_create(ctx, flags);
context_ok = d3d11_device_create(ctx);
if (context_ok) {
context_ok = context_init(ctx, flags);
context_ok = context_init(ctx);
if (!context_ok)
d3d11_device_destroy(ctx);
}
}
if ((!context_ok && !o->renderer) || o->renderer == RENDERER_D3D9) {
context_ok = d3d9_device_create(ctx, flags);
context_ok = d3d9_device_create(ctx);
if (context_ok) {
MP_VERBOSE(vo, "Using Direct3D 9\n");
context_ok = context_init(ctx, flags);
context_ok = context_init(ctx);
if (!context_ok)
d3d9_device_destroy(ctx);
}
@ -519,34 +561,58 @@ static int angle_init(struct MPGLContext *ctx, int flags)
// Create the underlying EGL surface implementation
bool surface_ok = false;
if ((!surface_ok && o->egl_windowing == -1) || o->egl_windowing == 0) {
surface_ok = d3d11_swapchain_surface_create(ctx, flags);
surface_ok = d3d11_swapchain_surface_create(ctx);
}
if ((!surface_ok && o->egl_windowing == -1) || o->egl_windowing == 1) {
surface_ok = egl_window_surface_create(ctx, flags);
surface_ok = egl_window_surface_create(ctx);
if (surface_ok)
MP_VERBOSE(vo, "Using EGL windowing\n");
}
if (!surface_ok)
goto fail;
mpegl_load_functions(ctx->gl, vo->log);
mpegl_load_functions(gl, vo->log);
current_ctx = ctx;
ctx->gl->SwapInterval = angle_swap_interval;
gl->SwapInterval = angle_swap_interval;
return 0;
// ANGLE doesn't actually need to override any of the functions (yet)
static const struct ra_swapchain_fns empty_swapchain_fns = {0};
struct ra_gl_ctx_params params = {
.swap_buffers = angle_swap_buffers,
.flipped = p->flipped,
.external_swapchain = p->dxgi_swapchain ? &empty_swapchain_fns : NULL,
};
if (!ra_gl_ctx_init(ctx, gl, params))
goto fail;
DwmEnableMMCSS(TRUE); // DWM MMCSS cargo-cult. The dxgl backend also does this.
return true;
fail:
angle_uninit(ctx);
return -1;
return false;
}
static int angle_reconfig(struct MPGLContext *ctx)
static void resize(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
if (p->dxgi_swapchain)
d3d11_backbuffer_resize(ctx);
else
eglWaitClient(); // Should get ANGLE to resize its swapchain
ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0);
}
static bool angle_reconfig(struct ra_ctx *ctx)
{
vo_w32_config(ctx->vo);
return 0;
resize(ctx);
return true;
}
static struct mp_image *d3d11_screenshot(MPGLContext *ctx)
static struct mp_image *d3d11_screenshot(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
ID3D11Texture2D *frontbuffer = NULL;
@ -624,10 +690,8 @@ done:
return img;
}
static int angle_control(MPGLContext *ctx, int *events, int request, void *arg)
static int angle_control(struct ra_ctx *ctx, int *events, int request, void *arg)
{
struct priv *p = ctx->priv;
// Try a D3D11-specific method of taking a window screenshot
if (request == VOCTRL_SCREENSHOT_WIN) {
struct mp_image *img = d3d11_screenshot(ctx);
@ -637,63 +701,17 @@ static int angle_control(MPGLContext *ctx, int *events, int request, void *arg)
}
}
int r = vo_w32_control(ctx->vo, events, request, arg);
if (*events & VO_EVENT_RESIZE) {
if (p->dxgi_swapchain)
d3d11_backbuffer_resize(ctx);
else
eglWaitClient(); // Should get ANGLE to resize its swapchain
}
return r;
int ret = vo_w32_control(ctx->vo, events, request, arg);
if (*events & VO_EVENT_RESIZE)
resize(ctx);
return ret;
}
static void d3d11_swap_buffers(MPGLContext *ctx)
{
struct priv *p = ctx->priv;
// Calling Present() on a flip-sequential swap chain will silently change
// the underlying storage of the back buffer to point to the next buffer in
// the chain. This results in the RTVs for the back buffer becoming
// unbound. Since ANGLE doesn't know we called Present(), it will continue
// using the unbound RTVs, so we must save and restore them ourselves.
ID3D11RenderTargetView *rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0};
ID3D11DepthStencilView *dsv = NULL;
ID3D11DeviceContext_OMGetRenderTargets(p->d3d11_context,
MP_ARRAY_SIZE(rtvs), rtvs, &dsv);
HRESULT hr = IDXGISwapChain_Present(p->dxgi_swapchain, p->swapinterval, 0);
if (FAILED(hr))
MP_FATAL(ctx->vo, "Couldn't present: %s\n", mp_HRESULT_to_str(hr));
// Restore the RTVs and release the objects
ID3D11DeviceContext_OMSetRenderTargets(p->d3d11_context,
MP_ARRAY_SIZE(rtvs), rtvs, dsv);
for (int i = 0; i < MP_ARRAY_SIZE(rtvs); i++)
SAFE_RELEASE(rtvs[i]);
SAFE_RELEASE(dsv);
}
static void egl_swap_buffers(MPGLContext *ctx)
{
struct priv *p = ctx->priv;
eglSwapBuffers(p->egl_display, p->egl_window);
}
static void angle_swap_buffers(MPGLContext *ctx)
{
struct priv *p = ctx->priv;
if (p->dxgi_swapchain)
d3d11_swap_buffers(ctx);
else
egl_swap_buffers(ctx);
}
const struct mpgl_driver mpgl_driver_angle = {
const struct ra_ctx_fns ra_ctx_angle = {
.type = "opengl",
.name = "angle",
.priv_size = sizeof(struct priv),
.init = angle_init,
.reconfig = angle_reconfig,
.swap_buffers = angle_swap_buffers,
.control = angle_control,
.uninit = angle_uninit,
};

View File

@ -36,6 +36,7 @@ const struct m_sub_options cocoa_conf = {
};
struct priv {
GL gl;
CGLPixelFormatObj pix;
CGLContextObj ctx;
@ -62,7 +63,7 @@ static void *cocoa_glgetaddr(const char *s)
return ret;
}
static CGLError test_gl_version(struct MPGLContext *ctx, CGLOpenGLProfile ver)
static CGLError test_gl_version(struct ra_ctx *ctx, CGLOpenGLProfile ver)
{
struct priv *p = ctx->priv;
@ -107,9 +108,10 @@ error_out:
return err;
}
static bool create_gl_context(struct MPGLContext *ctx, int vo_flags)
static bool create_gl_context(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
GL *gl = &p->gl;
CGLError err;
CGLOpenGLProfile gl_versions[] = {
@ -132,60 +134,82 @@ static bool create_gl_context(struct MPGLContext *ctx, int vo_flags)
vo_cocoa_set_opengl_ctx(ctx->vo, p->ctx);
CGLSetCurrentContext(p->ctx);
if (vo_flags & VOFLAG_ALPHA)
if (ctx->opts.want_alpha)
CGLSetParameter(p->ctx, kCGLCPSurfaceOpacity, &(GLint){0});
mpgl_load_functions(ctx->gl, (void *)cocoa_glgetaddr, NULL, ctx->vo->log);
mpgl_load_functions(gl, (void *)cocoa_glgetaddr, NULL, ctx->vo->log);
gl->SwapInterval = set_swap_interval;
CGLReleasePixelFormat(p->pix);
return true;
}
static void cocoa_uninit(MPGLContext *ctx)
static void cocoa_uninit(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
ra_gl_ctx_uninit(ctx);
CGLReleaseContext(p->ctx);
vo_cocoa_uninit(ctx->vo);
}
static int cocoa_init(MPGLContext *ctx, int vo_flags)
static void cocoa_swap_buffers(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
GL *gl = &p->gl;
vo_cocoa_swap_buffers(ctx->vo);
gl->Flush();
}
static bool cocoa_init(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
GL *gl = &p->gl;
p->opts = mp_get_config_group(ctx, ctx->global, &cocoa_conf);
vo_cocoa_init(ctx->vo);
if (!create_gl_context(ctx, vo_flags))
return -1;
if (!create_gl_context(ctx))
goto fail;
ctx->gl->SwapInterval = set_swap_interval;
return 0;
struct ra_gl_ctx_params params = {
.swap_buffers = cocoa_swap_buffers,
};
if (!ra_gl_ctx_init(ctx, gl, params))
goto fail;
return true;
fail:
cocoa_uninit(ctx);
return false;
}
static int cocoa_reconfig(struct MPGLContext *ctx)
static void resize(struct ra_ctx *ctx)
{
ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0);
}
static bool cocoa_reconfig(struct ra_ctx *ctx)
{
vo_cocoa_config_window(ctx->vo);
return 0;
resize(ctx);
return true;
}
static int cocoa_control(struct MPGLContext *ctx, int *events, int request,
static int cocoa_control(struct ra_ctx *ctx, int *events, int request,
void *arg)
{
return vo_cocoa_control(ctx->vo, events, request, arg);
int ret = vo_cocoa_control(ctx->vo, events, request, arg);
if (*events & VO_EVENT_RESIZE)
resize(ctx);
return ret;
}
static void cocoa_swap_buffers(struct MPGLContext *ctx)
{
vo_cocoa_swap_buffers(ctx->vo);
ctx->gl->Flush();
}
const struct mpgl_driver mpgl_driver_cocoa = {
const struct ra_ctx_fns ra_ctx_cocoa = {
.type = "opengl",
.name = "cocoa",
.priv_size = sizeof(struct priv),
.init = cocoa_init,
.reconfig = cocoa_reconfig,
.swap_buffers = cocoa_swap_buffers,
.control = cocoa_control,
.uninit = cocoa_uninit,
};

View File

@ -22,6 +22,7 @@
#include "osdep/windows_utils.h"
#include "video/out/w32_common.h"
#include "context.h"
#include "utils.h"
// For WGL_ACCESS_WRITE_DISCARD_NV, etc.
#include <GL/wglext.h>
@ -35,6 +36,8 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#endif
struct priv {
GL gl;
HMODULE d3d9_dll;
HRESULT (WINAPI *Direct3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **ppD3D);
@ -54,6 +57,7 @@ struct priv {
// OpenGL resources
GLuint texture;
GLuint main_fb;
// Did we lose the device?
bool lost_device;
@ -63,7 +67,7 @@ struct priv {
int width, height, swapinterval;
};
static __thread struct MPGLContext *current_ctx;
static __thread struct ra_ctx *current_ctx;
static void pump_message_loop(void)
{
@ -84,10 +88,11 @@ static void *w32gpa(const GLubyte *procName)
return GetProcAddress(oglmod, procName);
}
static int os_ctx_create(struct MPGLContext *ctx)
static int os_ctx_create(struct ra_ctx *ctx)
{
static const wchar_t os_wnd_class[] = L"mpv offscreen gl";
struct priv *p = ctx->priv;
GL *gl = &p->gl;
HGLRC legacy_context = NULL;
RegisterClassExW(&(WNDCLASSEXW) {
@ -190,8 +195,8 @@ static int os_ctx_create(struct MPGLContext *ctx)
goto fail;
}
mpgl_load_functions(ctx->gl, w32gpa, wgl_exts, ctx->vo->log);
if (!(ctx->gl->mpgl_caps & MPGL_CAP_DXINTEROP)) {
mpgl_load_functions(gl, w32gpa, wgl_exts, ctx->vo->log);
if (!(gl->mpgl_caps & MPGL_CAP_DXINTEROP)) {
MP_FATAL(ctx->vo, "WGL_NV_DX_interop is not supported\n");
goto fail;
}
@ -205,7 +210,7 @@ fail:
return -1;
}
static void os_ctx_destroy(MPGLContext *ctx)
static void os_ctx_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
@ -219,10 +224,10 @@ static void os_ctx_destroy(MPGLContext *ctx)
DestroyWindow(p->os_wnd);
}
static int d3d_size_dependent_create(MPGLContext *ctx)
static int d3d_size_dependent_create(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct GL *gl = ctx->gl;
GL *gl = &p->gl;
HRESULT hr;
IDirect3DSwapChain9 *sw9;
@ -294,7 +299,7 @@ static int d3d_size_dependent_create(MPGLContext *ctx)
return -1;
}
gl->BindFramebuffer(GL_FRAMEBUFFER, ctx->main_fb);
gl->BindFramebuffer(GL_FRAMEBUFFER, p->main_fb);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, p->texture, 0);
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
@ -302,10 +307,10 @@ static int d3d_size_dependent_create(MPGLContext *ctx)
return 0;
}
static void d3d_size_dependent_destroy(MPGLContext *ctx)
static void d3d_size_dependent_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct GL *gl = ctx->gl;
GL *gl = &p->gl;
if (p->rtarget_h) {
gl->DXUnlockObjectsNV(p->device_h, 1, &p->rtarget_h);
@ -321,7 +326,8 @@ static void d3d_size_dependent_destroy(MPGLContext *ctx)
SAFE_RELEASE(p->swapchain);
}
static void fill_presentparams(MPGLContext *ctx, D3DPRESENT_PARAMETERS *pparams)
static void fill_presentparams(struct ra_ctx *ctx,
D3DPRESENT_PARAMETERS *pparams)
{
struct priv *p = ctx->priv;
@ -338,13 +344,9 @@ static void fill_presentparams(MPGLContext *ctx, D3DPRESENT_PARAMETERS *pparams)
.Windowed = TRUE,
.BackBufferWidth = ctx->vo->dwidth ? ctx->vo->dwidth : 1,
.BackBufferHeight = ctx->vo->dheight ? ctx->vo->dheight : 1,
// The length of the backbuffer queue shouldn't affect latency because
// swap_buffers() always uses the backbuffer at the head of the queue
// and presents it immediately. MSDN says there is a performance
// penalty for having a short backbuffer queue and this seems to be
// true, at least on Nvidia, where less than four backbuffers causes
// very high CPU usage. Use six to be safe.
.BackBufferCount = 6,
// Add one frame for the backbuffer and one frame of "slack" to reduce
// contention with the window manager when acquiring the backbuffer
.BackBufferCount = ctx->opts.swapchain_depth + 2,
.SwapEffect = IsWindows7OrGreater() ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_FLIP,
// Automatically get the backbuffer format from the display format
.BackBufferFormat = D3DFMT_UNKNOWN,
@ -353,10 +355,10 @@ static void fill_presentparams(MPGLContext *ctx, D3DPRESENT_PARAMETERS *pparams)
};
}
static int d3d_create(MPGLContext *ctx)
static int d3d_create(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct GL *gl = ctx->gl;
GL *gl = &p->gl;
HRESULT hr;
p->d3d9_dll = LoadLibraryW(L"d3d9.dll");
@ -396,8 +398,7 @@ static int d3d_create(MPGLContext *ctx)
return -1;
}
// mpv expects frames to be presented right after swap_buffers() returns
IDirect3DDevice9Ex_SetMaximumFrameLatency(p->device, 1);
IDirect3DDevice9Ex_SetMaximumFrameLatency(p->device, ctx->opts.swapchain_depth);
// Register the Direct3D device with WGL_NV_dx_interop
p->device_h = gl->DXOpenDeviceNV(p->device);
@ -410,10 +411,10 @@ static int d3d_create(MPGLContext *ctx)
return 0;
}
static void d3d_destroy(MPGLContext *ctx)
static void d3d_destroy(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct GL *gl = ctx->gl;
GL *gl = &p->gl;
if (p->device_h)
gl->DXCloseDeviceNV(p->device_h);
@ -423,8 +424,9 @@ static void d3d_destroy(MPGLContext *ctx)
FreeLibrary(p->d3d9_dll);
}
static void dxinterop_uninit(MPGLContext *ctx)
static void dxgl_uninit(struct ra_ctx *ctx)
{
ra_gl_ctx_uninit(ctx);
d3d_size_dependent_destroy(ctx);
d3d_destroy(ctx);
os_ctx_destroy(ctx);
@ -433,7 +435,7 @@ static void dxinterop_uninit(MPGLContext *ctx)
pump_message_loop();
}
static void dxinterop_reset(struct MPGLContext *ctx)
static void dxgl_reset(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
HRESULT hr;
@ -468,18 +470,18 @@ static void dxinterop_reset(struct MPGLContext *ctx)
p->lost_device = false;
}
static int GLAPIENTRY dxinterop_swap_interval(int interval)
static int GLAPIENTRY dxgl_swap_interval(int interval)
{
if (!current_ctx)
return 0;
struct priv *p = current_ctx->priv;
p->requested_swapinterval = interval;
dxinterop_reset(current_ctx);
dxgl_reset(current_ctx);
return 1;
}
static void * GLAPIENTRY dxinterop_get_native_display(const char *name)
static void * GLAPIENTRY dxgl_get_native_display(const char *name)
{
if (!current_ctx || !name)
return NULL;
@ -493,60 +495,17 @@ static void * GLAPIENTRY dxinterop_get_native_display(const char *name)
return NULL;
}
static int dxinterop_init(struct MPGLContext *ctx, int flags)
static void dxgl_swap_buffers(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
struct GL *gl = ctx->gl;
p->requested_swapinterval = 1;
if (!vo_w32_init(ctx->vo))
goto fail;
if (os_ctx_create(ctx) < 0)
goto fail;
// Create the shared framebuffer
gl->GenFramebuffers(1, &ctx->main_fb);
current_ctx = ctx;
gl->SwapInterval = dxinterop_swap_interval;
gl->MPGetNativeDisplay = dxinterop_get_native_display;
if (d3d_create(ctx) < 0)
goto fail;
if (d3d_size_dependent_create(ctx) < 0)
goto fail;
// The OpenGL and Direct3D coordinate systems are flipped vertically
// relative to each other. Flip the video during rendering so it can be
// copied to the Direct3D backbuffer with a simple (and fast) StretchRect.
ctx->flip_v = true;
DwmEnableMMCSS(TRUE);
return 0;
fail:
dxinterop_uninit(ctx);
return -1;
}
static int dxinterop_reconfig(struct MPGLContext *ctx)
{
vo_w32_config(ctx->vo);
return 0;
}
static void dxinterop_swap_buffers(MPGLContext *ctx)
{
struct priv *p = ctx->priv;
struct GL *gl = ctx->gl;
GL *gl = &p->gl;
HRESULT hr;
pump_message_loop();
// If the device is still lost, try to reset it again
if (p->lost_device)
dxinterop_reset(ctx);
dxgl_reset(ctx);
if (p->lost_device)
return;
@ -571,7 +530,7 @@ static void dxinterop_swap_buffers(MPGLContext *ctx)
case D3DERR_DEVICEHUNG:
MP_VERBOSE(ctx->vo, "Direct3D device lost! Resetting.\n");
p->lost_device = true;
dxinterop_reset(ctx);
dxgl_reset(ctx);
return;
default:
if (FAILED(hr))
@ -584,21 +543,75 @@ static void dxinterop_swap_buffers(MPGLContext *ctx)
}
}
static int dxinterop_control(MPGLContext *ctx, int *events, int request,
void *arg)
static bool dxgl_init(struct ra_ctx *ctx)
{
int r = vo_w32_control(ctx->vo, events, request, arg);
if (*events & VO_EVENT_RESIZE)
dxinterop_reset(ctx);
return r;
struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
GL *gl = &p->gl;
p->requested_swapinterval = 1;
if (!vo_w32_init(ctx->vo))
goto fail;
if (os_ctx_create(ctx) < 0)
goto fail;
// Create the shared framebuffer
gl->GenFramebuffers(1, &p->main_fb);
current_ctx = ctx;
gl->SwapInterval = dxgl_swap_interval;
gl->MPGetNativeDisplay = dxgl_get_native_display;
if (d3d_create(ctx) < 0)
goto fail;
if (d3d_size_dependent_create(ctx) < 0)
goto fail;
static const struct ra_swapchain_fns empty_swapchain_fns = {0};
struct ra_gl_ctx_params params = {
.swap_buffers = dxgl_swap_buffers,
.flipped = true,
.external_swapchain = &empty_swapchain_fns,
};
if (!ra_gl_ctx_init(ctx, gl, params))
goto fail;
DwmEnableMMCSS(TRUE);
return true;
fail:
dxgl_uninit(ctx);
return false;
}
const struct mpgl_driver mpgl_driver_dxinterop = {
static void resize(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
dxgl_reset(ctx);
ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, p->main_fb);
}
static bool dxgl_reconfig(struct ra_ctx *ctx)
{
vo_w32_config(ctx->vo);
resize(ctx);
return true;
}
static int dxgl_control(struct ra_ctx *ctx, int *events, int request,
void *arg)
{
int ret = vo_w32_control(ctx->vo, events, request, arg);
if (*events & VO_EVENT_RESIZE)
resize(ctx);
return ret;
}
const struct ra_ctx_fns ra_ctx_dxgl = {
.type = "opengl",
.name = "dxinterop",
.priv_size = sizeof(struct priv),
.init = dxinterop_init,
.reconfig = dxinterop_reconfig,
.swap_buffers = dxinterop_swap_buffers,
.control = dxinterop_control,
.uninit = dxinterop_uninit,
.init = dxgl_init,
.reconfig = dxgl_reconfig,
.control = dxgl_control,
.uninit = dxgl_uninit,
};

View File

@ -23,6 +23,7 @@
#include "video/out/w32_common.h"
#include "video/out/win32/exclusive_hack.h"
#include "context.h"
#include "utils.h"
#if !defined(WGL_CONTEXT_MAJOR_VERSION_ARB)
/* these are supposed to be defined in wingdi.h but mingw's is too old */
@ -37,7 +38,9 @@
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#endif
struct w32_context {
struct priv {
GL gl;
int opt_swapinterval;
int current_swapinterval;
@ -45,26 +48,25 @@ struct w32_context {
HGLRC context;
HDC hdc;
int flags;
};
static void w32_uninit(MPGLContext *ctx);
static void wgl_uninit(struct ra_ctx *ctx);
static __thread struct w32_context *current_w32_context;
static __thread struct priv *current_wgl_context;
static int GLAPIENTRY w32_swap_interval(int interval)
static int GLAPIENTRY wgl_swap_interval(int interval)
{
if (current_w32_context)
current_w32_context->opt_swapinterval = interval;
if (current_wgl_context)
current_wgl_context->opt_swapinterval = interval;
return 0;
}
static bool create_dc(struct MPGLContext *ctx, int flags)
static bool create_dc(struct ra_ctx *ctx)
{
struct w32_context *w32_ctx = ctx->priv;
struct priv *p = ctx->priv;
HWND win = vo_w32_hwnd(ctx->vo);
if (w32_ctx->hdc)
if (p->hdc)
return true;
HDC hdc = GetDC(win);
@ -90,11 +92,11 @@ static bool create_dc(struct MPGLContext *ctx, int flags)
SetPixelFormat(hdc, pf, &pfd);
w32_ctx->hdc = hdc;
p->hdc = hdc;
return true;
}
static void *w32gpa(const GLubyte *procName)
static void *wglgpa(const GLubyte *procName)
{
HMODULE oglmod;
void *res = wglGetProcAddress(procName);
@ -104,11 +106,11 @@ static void *w32gpa(const GLubyte *procName)
return GetProcAddress(oglmod, procName);
}
static bool create_context_w32_old(struct MPGLContext *ctx)
static bool create_context_wgl_old(struct ra_ctx *ctx)
{
struct w32_context *w32_ctx = ctx->priv;
struct priv *p = ctx->priv;
HDC windc = w32_ctx->hdc;
HDC windc = p->hdc;
bool res = false;
HGLRC context = wglCreateContext(windc);
@ -123,17 +125,15 @@ static bool create_context_w32_old(struct MPGLContext *ctx)
return res;
}
w32_ctx->context = context;
mpgl_load_functions(ctx->gl, w32gpa, NULL, ctx->vo->log);
p->context = context;
return true;
}
static bool create_context_w32_gl3(struct MPGLContext *ctx)
static bool create_context_wgl_gl3(struct ra_ctx *ctx)
{
struct w32_context *w32_ctx = ctx->priv;
struct priv *p = ctx->priv;
HDC windc = w32_ctx->hdc;
HDC windc = p->hdc;
HGLRC context = 0;
// A legacy context is needed to get access to the new functions.
@ -150,7 +150,7 @@ static bool create_context_w32_gl3(struct MPGLContext *ctx)
}
const char *(GLAPIENTRY *wglGetExtensionsStringARB)(HDC hdc)
= w32gpa((const GLubyte*)"wglGetExtensionsStringARB");
= wglgpa((const GLubyte*)"wglGetExtensionsStringARB");
if (!wglGetExtensionsStringARB)
goto unsupported;
@ -161,7 +161,7 @@ static bool create_context_w32_gl3(struct MPGLContext *ctx)
HGLRC (GLAPIENTRY *wglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext,
const int *attribList)
= w32gpa((const GLubyte*)"wglCreateContextAttribsARB");
= wglgpa((const GLubyte*)"wglCreateContextAttribsARB");
if (!wglCreateContextAttribsARB)
goto unsupported;
@ -197,11 +197,7 @@ static bool create_context_w32_gl3(struct MPGLContext *ctx)
return false;
}
w32_ctx->context = context;
/* update function pointers */
mpgl_load_functions(ctx->gl, w32gpa, NULL, ctx->vo->log);
p->context = context;
return true;
unsupported:
@ -214,79 +210,20 @@ out:
static void create_ctx(void *ptr)
{
struct MPGLContext *ctx = ptr;
struct w32_context *w32_ctx = ctx->priv;
struct ra_ctx *ctx = ptr;
struct priv *p = ctx->priv;
if (!create_dc(ctx, w32_ctx->flags))
if (!create_dc(ctx))
return;
create_context_w32_gl3(ctx);
if (!w32_ctx->context)
create_context_w32_old(ctx);
create_context_wgl_gl3(ctx);
if (!p->context)
create_context_wgl_old(ctx);
wglMakeCurrent(w32_ctx->hdc, NULL);
wglMakeCurrent(p->hdc, NULL);
}
static int w32_init(struct MPGLContext *ctx, int flags)
{
if (!vo_w32_init(ctx->vo))
goto fail;
struct w32_context *w32_ctx = ctx->priv;
w32_ctx->flags = flags;
vo_w32_run_on_thread(ctx->vo, create_ctx, ctx);
if (!w32_ctx->context)
goto fail;
if (!ctx->gl->SwapInterval)
MP_VERBOSE(ctx->vo, "WGL_EXT_swap_control missing.\n");
w32_ctx->real_wglSwapInterval = ctx->gl->SwapInterval;
ctx->gl->SwapInterval = w32_swap_interval;
w32_ctx->current_swapinterval = -1;
current_w32_context = w32_ctx;
wglMakeCurrent(w32_ctx->hdc, w32_ctx->context);
DwmEnableMMCSS(TRUE);
return 0;
fail:
w32_uninit(ctx);
return -1;
}
static int w32_reconfig(struct MPGLContext *ctx)
{
vo_w32_config(ctx->vo);
return 0;
}
static void destroy_gl(void *ptr)
{
struct MPGLContext *ctx = ptr;
struct w32_context *w32_ctx = ctx->priv;
if (w32_ctx->context)
wglDeleteContext(w32_ctx->context);
w32_ctx->context = 0;
if (w32_ctx->hdc)
ReleaseDC(vo_w32_hwnd(ctx->vo), w32_ctx->hdc);
w32_ctx->hdc = NULL;
current_w32_context = NULL;
}
static void w32_uninit(MPGLContext *ctx)
{
struct w32_context *w32_ctx = ctx->priv;
if (w32_ctx->context)
wglMakeCurrent(w32_ctx->hdc, 0);
vo_w32_run_on_thread(ctx->vo, destroy_gl, ctx);
DwmEnableMMCSS(FALSE);
vo_w32_uninit(ctx->vo);
}
static bool compositor_active(MPGLContext *ctx)
static bool compositor_active(struct ra_ctx *ctx)
{
// For Windows 7.
BOOL enabled = 0;
@ -308,13 +245,13 @@ static bool compositor_active(MPGLContext *ctx)
return true;
}
static void w32_swap_buffers(MPGLContext *ctx)
static void wgl_swap_buffers(struct ra_ctx *ctx)
{
struct w32_context *w32_ctx = ctx->priv;
SwapBuffers(w32_ctx->hdc);
struct priv *p = ctx->priv;
SwapBuffers(p->hdc);
// default if we don't DwmFLush
int new_swapinterval = w32_ctx->opt_swapinterval;
int new_swapinterval = p->opt_swapinterval;
int dwm_flush_opt;
mp_read_option_raw(ctx->global, "opengl-dwmflush", &m_option_type_choice,
@ -330,26 +267,103 @@ static void w32_swap_buffers(MPGLContext *ctx)
}
}
if (new_swapinterval != w32_ctx->current_swapinterval &&
w32_ctx->real_wglSwapInterval)
if (new_swapinterval != p->current_swapinterval &&
p->real_wglSwapInterval)
{
w32_ctx->real_wglSwapInterval(new_swapinterval);
p->real_wglSwapInterval(new_swapinterval);
MP_VERBOSE(ctx->vo, "set SwapInterval(%d)\n", new_swapinterval);
}
w32_ctx->current_swapinterval = new_swapinterval;
p->current_swapinterval = new_swapinterval;
}
static int w32_control(MPGLContext *ctx, int *events, int request, void *arg)
static bool wgl_init(struct ra_ctx *ctx)
{
return vo_w32_control(ctx->vo, events, request, arg);
struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
GL *gl = &p->gl;
if (!vo_w32_init(ctx->vo))
goto fail;
vo_w32_run_on_thread(ctx->vo, create_ctx, ctx);
if (!p->context)
goto fail;
current_wgl_context = p;
wglMakeCurrent(p->hdc, p->context);
mpgl_load_functions(gl, wglgpa, NULL, ctx->vo->log);
if (!gl->SwapInterval)
MP_VERBOSE(ctx->vo, "WGL_EXT_swap_control missing.\n");
p->real_wglSwapInterval = gl->SwapInterval;
gl->SwapInterval = wgl_swap_interval;
p->current_swapinterval = -1;
struct ra_gl_ctx_params params = {
.swap_buffers = wgl_swap_buffers,
};
if (!ra_gl_ctx_init(ctx, gl, params))
goto fail;
DwmEnableMMCSS(TRUE);
return true;
fail:
wgl_uninit(ctx);
return false;
}
const struct mpgl_driver mpgl_driver_w32 = {
static void resize(struct ra_ctx *ctx)
{
ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0);
}
static bool wgl_reconfig(struct ra_ctx *ctx)
{
vo_w32_config(ctx->vo);
resize(ctx);
return true;
}
static void destroy_gl(void *ptr)
{
struct ra_ctx *ctx = ptr;
struct priv *p = ctx->priv;
if (p->context)
wglDeleteContext(p->context);
p->context = 0;
if (p->hdc)
ReleaseDC(vo_w32_hwnd(ctx->vo), p->hdc);
p->hdc = NULL;
current_wgl_context = NULL;
}
static void wgl_uninit(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
ra_gl_ctx_uninit(ctx);
if (p->context)
wglMakeCurrent(p->hdc, 0);
vo_w32_run_on_thread(ctx->vo, destroy_gl, ctx);
DwmEnableMMCSS(FALSE);
vo_w32_uninit(ctx->vo);
}
static int wgl_control(struct ra_ctx *ctx, int *events, int request, void *arg)
{
int ret = vo_w32_control(ctx->vo, events, request, arg);
if (*events & VO_EVENT_RESIZE)
resize(ctx);
return ret;
}
const struct ra_ctx_fns ra_ctx_wgl = {
.type = "opengl",
.name = "win",
.priv_size = sizeof(struct w32_context),
.init = w32_init,
.reconfig = w32_reconfig,
.swap_buffers = w32_swap_buffers,
.control = w32_control,
.uninit = w32_uninit,
.init = wgl_init,
.reconfig = wgl_reconfig,
.control = wgl_control,
.uninit = wgl_uninit,
};

View File

@ -27,7 +27,7 @@
#include "common/common.h"
#include "osdep/timer.h"
#include "osdep/windows_utils.h"
#include "hwdec.h"
#include "video/out/gpu/hwdec.h"
#include "ra_gl.h"
#include "video/hwdec.h"
#include "video/decode/d3d.h"

View File

@ -27,7 +27,7 @@
#include "common/common.h"
#include "osdep/timer.h"
#include "osdep/windows_utils.h"
#include "hwdec.h"
#include "video/out/gpu/hwdec.h"
#include "ra_gl.h"
#include "video/hwdec.h"
#include "video/decode/d3d.h"

View File

@ -27,7 +27,7 @@
#include "common/common.h"
#include "osdep/timer.h"
#include "osdep/windows_utils.h"
#include "hwdec.h"
#include "video/out/gpu/hwdec.h"
#include "ra_gl.h"
#include "video/hwdec.h"
#include "video/decode/d3d.h"

View File

@ -20,7 +20,7 @@
#include "common/common.h"
#include "osdep/windows_utils.h"
#include "hwdec.h"
#include "video/out/gpu/hwdec.h"
#include "ra_gl.h"
#include "video/hwdec.h"
#include "video/decode/d3d.h"

View File

@ -400,25 +400,25 @@ def build(ctx):
( "video/out/opengl/utils.c", "gl" ),
( "video/out/opengl/ra_gl.c", "gl" ),
( "video/out/opengl/context.c", "gl" ),
# ( "video/out/opengl/context_angle.c", "egl-angle-win32" ),
# ( "video/out/opengl/context_cocoa.c", "gl-cocoa" ),
( "video/out/opengl/context_angle.c", "egl-angle-win32" ),
( "video/out/opengl/context_cocoa.c", "gl-cocoa" ),
( "video/out/opengl/context_drm_egl.c", "egl-drm" ),
# ( "video/out/opengl/context_dxinterop.c","gl-dxinterop" ),
( "video/out/opengl/context_dxinterop.c","gl-dxinterop" ),
( "video/out/opengl/context_mali_fbdev.c","mali-fbdev" ),
( "video/out/opengl/context_rpi.c", "rpi" ),
( "video/out/opengl/context_vdpau.c", "vdpau-gl-x11" ),
( "video/out/opengl/context_wayland.c", "gl-wayland" ),
# ( "video/out/opengl/context_w32.c", "gl-win32" ),
( "video/out/opengl/context_win.c", "gl-win32" ),
( "video/out/opengl/context_glx.c", "gl-x11" ),
( "video/out/opengl/context_x11egl.c", "egl-x11" ),
( "video/out/opengl/cuda_dynamic.c", "cuda-hwaccel" ),
# ( "video/out/opengl/d3d11_helpers.c", "egl-angle-win32" ),
( "video/out/opengl/d3d11_helpers.c", "egl-angle-win32" ),
( "video/out/opengl/egl_helpers.c", "egl-helpers" ),
( "video/out/opengl/hwdec_cuda.c", "cuda-hwaccel" ),
# ( "video/out/opengl/hwdec_d3d11egl.c", "d3d-hwaccel" ),
# ( "video/out/opengl/hwdec_d3d11eglrgb.c","d3d-hwaccel" ),
# ( "video/out/opengl/hwdec_dxva2gldx.c", "gl-dxinterop-d3d9" ),
# ( "video/out/opengl/hwdec_dxva2egl.c", "d3d9-hwaccel" ),
( "video/out/opengl/hwdec_d3d11egl.c", "d3d-hwaccel" ),
( "video/out/opengl/hwdec_d3d11eglrgb.c","d3d-hwaccel" ),
( "video/out/opengl/hwdec_dxva2gldx.c", "gl-dxinterop-d3d9" ),
( "video/out/opengl/hwdec_dxva2egl.c", "d3d9-hwaccel" ),
( "video/out/opengl/hwdec_osx.c", "videotoolbox-gl" ),
( "video/out/opengl/hwdec_ios.m", "ios-gl" ),
( "video/out/opengl/hwdec_rpi.c", "rpi" ),