summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
Diffstat (limited to 'video/out')
-rw-r--r--video/out/cocoa_cb_common.swift88
-rw-r--r--video/out/d3d11/context.c1
-rw-r--r--video/out/d3d11/ra_d3d11.c89
-rw-r--r--video/out/drm_atomic.c54
-rw-r--r--video/out/drm_common.c2
-rw-r--r--video/out/drm_prime.c14
-rw-r--r--video/out/gpu/context.c208
-rw-r--r--video/out/gpu/context.h5
-rw-r--r--video/out/gpu/d3d11_helpers.c44
-rw-r--r--video/out/gpu/d3d11_helpers.h13
-rw-r--r--video/out/gpu/video.c25
-rw-r--r--video/out/gpu/video.h1
-rw-r--r--video/out/hwdec/hwdec_cuda.c47
-rw-r--r--video/out/hwdec/hwdec_cuda.h9
-rw-r--r--video/out/hwdec/hwdec_cuda_gl.c32
-rw-r--r--video/out/hwdec/hwdec_cuda_vk.c48
-rw-r--r--video/out/hwdec/hwdec_drmprime_overlay.c2
-rw-r--r--video/out/hwdec/hwdec_vaapi.c3
-rw-r--r--video/out/mac/common.swift115
-rw-r--r--video/out/mac/gl_layer.swift41
-rw-r--r--video/out/mac/metal_layer.swift1
-rw-r--r--video/out/mac/title_bar.swift45
-rw-r--r--video/out/mac/view.swift18
-rw-r--r--video/out/mac/window.swift97
-rw-r--r--video/out/mac_common.swift41
-rw-r--r--video/out/opengl/common.c1
-rw-r--r--video/out/opengl/context_android.c1
-rw-r--r--video/out/opengl/context_angle.c1
-rw-r--r--video/out/opengl/context_drm_egl.c4
-rw-r--r--video/out/opengl/context_dxinterop.c1
-rw-r--r--video/out/opengl/context_glx.c1
-rw-r--r--video/out/opengl/context_wayland.c1
-rw-r--r--video/out/opengl/context_win.c1
-rw-r--r--video/out/opengl/context_x11egl.c1
-rw-r--r--video/out/vo.h4
-rw-r--r--video/out/vo_dmabuf_wayland.c17
-rw-r--r--video/out/vo_gpu.c5
-rw-r--r--video/out/vo_gpu_next.c25
-rw-r--r--video/out/vo_kitty.c2
-rw-r--r--video/out/vo_sdl.c1
-rw-r--r--video/out/vo_sixel.c6
-rw-r--r--video/out/vo_tct.c157
-rw-r--r--video/out/vo_xv.c2
-rw-r--r--video/out/vulkan/context.c95
-rw-r--r--video/out/vulkan/context.h6
-rw-r--r--video/out/vulkan/context_android.c1
-rw-r--r--video/out/vulkan/context_display.c42
-rw-r--r--video/out/vulkan/context_mac.m10
-rw-r--r--video/out/vulkan/context_wayland.c1
-rw-r--r--video/out/vulkan/context_win.c1
-rw-r--r--video/out/vulkan/context_xlib.c1
-rw-r--r--video/out/w32_common.c141
-rw-r--r--video/out/wayland_common.c225
-rw-r--r--video/out/wayland_common.h3
-rw-r--r--video/out/win32/menu.c246
-rw-r--r--video/out/win32/menu.h32
-rw-r--r--video/out/wldmabuf/context_wldmabuf.c2
-rw-r--r--video/out/x11_common.c26
58 files changed, 1432 insertions, 674 deletions
diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift
index 3426ca6cf8..b2910dba85 100644
--- a/video/out/cocoa_cb_common.swift
+++ b/video/out/cocoa_cb_common.swift
@@ -30,12 +30,11 @@ class CocoaCB: Common, EventSubscriber {
}
var backendState: State = .uninitialized
-
- @objc init(_ mpvHandle: OpaquePointer) {
- let newlog = mp_log_new(UnsafeMutablePointer(mpvHandle), mp_client_get_log(mpvHandle), "cocoacb")
- let option = OptionHelper(UnsafeMutablePointer(mpvHandle), mp_client_get_global(mpvHandle))
- libmpv = LibmpvHelper(mpvHandle, newlog)
- super.init(option, newlog)
+ init(_ mpv: OpaquePointer) {
+ let log = LogHelper(mp_log_new(UnsafeMutablePointer(mpv), mp_client_get_log(mpv), "cocoacb"))
+ let option = OptionHelper(UnsafeMutablePointer(mpv), mp_client_get_global(mpv))
+ libmpv = LibmpvHelper(mpv, log)
+ super.init(option, log)
layer = GLLayer(cocoaCB: self)
AppHub.shared.event?.subscribe(self, event: .init(name: "MPV_EVENT_SHUTDOWN"))
}
@@ -48,7 +47,7 @@ class CocoaCB: Common, EventSubscriber {
backendState = .needsInit
guard let layer = self.layer else {
- log.sendError("Something went wrong, no GLLayer was initialized")
+ log.error("Something went wrong, no GLLayer was initialized")
exit(1)
}
@@ -88,9 +87,8 @@ class CocoaCB: Common, EventSubscriber {
}
func updateWindowSize(_ vo: UnsafeMutablePointer<vo>) {
- guard let targetScreen = getTargetScreen(forFullscreen: false) ?? NSScreen.main else
- {
- log.sendWarning("Couldn't update Window size, no Screen available")
+ guard let targetScreen = getTargetScreen(forFullscreen: false) ?? NSScreen.main else {
+ log.warning("Couldn't update Window size, no Screen available")
return
}
@@ -103,11 +101,10 @@ class CocoaCB: Common, EventSubscriber {
}
override func displayLinkCallback(_ displayLink: CVDisplayLink,
- _ inNow: UnsafePointer<CVTimeStamp>,
- _ inOutputTime: UnsafePointer<CVTimeStamp>,
- _ flagsIn: CVOptionFlags,
- _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn
- {
+ _ inNow: UnsafePointer<CVTimeStamp>,
+ _ inOutputTime: UnsafePointer<CVTimeStamp>,
+ _ flagsIn: CVOptionFlags,
+ _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn {
libmpv.reportRenderFlip()
return kCVReturnSuccess
}
@@ -118,12 +115,60 @@ class CocoaCB: Common, EventSubscriber {
override func updateICCProfile() {
guard let colorSpace = window?.screen?.colorSpace else {
- log.sendWarning("Couldn't update ICC Profile, no color space available")
+ log.warning("Couldn't update ICC Profile, no color space available")
return
}
libmpv.setRenderICCProfile(colorSpace)
- layer?.colorspace = colorSpace.cgColorSpace
+ layer?.colorspace = getColorSpace()
+ }
+
+ func getColorSpace() -> CGColorSpace? {
+ guard let colorSpace = window?.screen?.colorSpace?.cgColorSpace else {
+ log.warning("Couldn't retrieve ICC Profile, no color space available")
+ return nil
+ }
+
+ let outputCsp = Int(option.mac.cocoa_cb_output_csp)
+
+ switch outputCsp {
+ case MAC_CSP_AUTO: return colorSpace
+ case MAC_CSP_DISPLAY_P3: return CGColorSpace(name: CGColorSpace.displayP3)
+ case MAC_CSP_DISPLAY_P3_HLG: return CGColorSpace(name: CGColorSpace.displayP3_HLG)
+ case MAC_CSP_DISPLAY_P3_PQ: return CGColorSpace(name: CGColorSpace.displayP3_PQ)
+ case MAC_CSP_DCI_P3: return CGColorSpace(name: CGColorSpace.dcip3)
+ case MAC_CSP_BT_2020: return CGColorSpace(name: CGColorSpace.itur_2020)
+ case MAC_CSP_BT_709: return CGColorSpace(name: CGColorSpace.itur_709)
+ case MAC_CSP_SRGB: return CGColorSpace(name: CGColorSpace.sRGB)
+ case MAC_CSP_SRGB_LINEAR: return CGColorSpace(name: CGColorSpace.linearSRGB)
+ case MAC_CSP_RGB_LINEAR: return CGColorSpace(name: CGColorSpace.genericRGBLinear)
+ case MAC_CSP_ADOBE: return CGColorSpace(name: CGColorSpace.adobeRGB1998)
+ default: break
+ }
+
+#if HAVE_MACOS_11_FEATURES
+ if #available(macOS 11.0, *) {
+ switch outputCsp {
+ case MAC_CSP_BT_2100_HLG: return CGColorSpace(name: CGColorSpace.itur_2100_HLG)
+ case MAC_CSP_BT_2100_PQ: return CGColorSpace(name: CGColorSpace.itur_2100_PQ)
+ default: break
+ }
+ }
+#endif
+
+#if HAVE_MACOS_12_FEATURES
+ if #available(macOS 12.0, *) {
+ switch outputCsp {
+ case MAC_CSP_DISPLAY_P3_LINEAR: return CGColorSpace(name: CGColorSpace.linearDisplayP3)
+ case MAC_CSP_BT_2020_LINEAR: return CGColorSpace(name: CGColorSpace.linearITUR_2020)
+ default: break
+ }
+ }
+#endif
+
+ log.warning("Couldn't retrieve configured color space, falling back to auto")
+
+ return colorSpace
}
override func windowDidEndAnimation() {
@@ -171,7 +216,7 @@ class CocoaCB: Common, EventSubscriber {
let ccb = unsafeBitCast(ctx, to: CocoaCB.self)
guard let vo = v, let events = e else {
- ccb.log.sendWarning("Unexpected nil value in Control Callback")
+ ccb.log.warning("Unexpected nil value in Control Callback")
return VO_FALSE
}
@@ -179,10 +224,9 @@ class CocoaCB: Common, EventSubscriber {
}
override func control(_ vo: UnsafeMutablePointer<vo>,
- events: UnsafeMutablePointer<Int32>,
- request: UInt32,
- data: UnsafeMutableRawPointer?) -> Int32
- {
+ events: UnsafeMutablePointer<Int32>,
+ request: UInt32,
+ data: UnsafeMutableRawPointer?) -> Int32 {
switch mp_voctrl(request) {
case VOCTRL_PREINIT:
DispatchQueue.main.sync { self.preinit(vo) }
diff --git a/video/out/d3d11/context.c b/video/out/d3d11/context.c
index c563b5fa15..f183ae8be5 100644
--- a/video/out/d3d11/context.c
+++ b/video/out/d3d11/context.c
@@ -547,6 +547,7 @@ bool ra_d3d11_ctx_prefer_8bit_output_format(struct ra_ctx *ra)
const struct ra_ctx_fns ra_ctx_d3d11 = {
.type = "d3d11",
.name = "d3d11",
+ .description = "Direct3D 11",
.reconfig = d3d11_reconfig,
.control = d3d11_control,
.update_render_opts = d3d11_update_render_opts,
diff --git a/video/out/d3d11/ra_d3d11.c b/video/out/d3d11/ra_d3d11.c
index 84fd004adc..4438b2083c 100644
--- a/video/out/d3d11/ra_d3d11.c
+++ b/video/out/d3d11/ra_d3d11.c
@@ -13,6 +13,7 @@
#include "osdep/windows_utils.h"
#include "video/out/gpu/spirv.h"
#include "video/out/gpu/utils.h"
+#include "video/out/gpu/d3d11_helpers.h"
#include "ra_d3d11.h"
@@ -43,9 +44,11 @@ struct ra_d3d11 {
struct dll_version d3d_compiler_ver;
+#if HAVE_DXGI_DEBUG
// Debug interfaces (--gpu-debug)
- ID3D11Debug *debug;
- ID3D11InfoQueue *iqueue;
+ IDXGIDebug *debug;
+ IDXGIInfoQueue *iqueue;
+#endif
// Device capabilities
D3D_FEATURE_LEVEL fl;
@@ -2094,24 +2097,25 @@ static uint64_t timer_stop(struct ra *ra, ra_timer *ratimer)
return timer->result;
}
-static int map_msg_severity(D3D11_MESSAGE_SEVERITY sev)
+#if HAVE_DXGI_DEBUG
+static int map_msg_severity(DXGI_INFO_QUEUE_MESSAGE_SEVERITY sev)
{
switch (sev) {
- case D3D11_MESSAGE_SEVERITY_CORRUPTION:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION:
return MSGL_FATAL;
- case D3D11_MESSAGE_SEVERITY_ERROR:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR:
return MSGL_ERR;
- case D3D11_MESSAGE_SEVERITY_WARNING:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING:
return MSGL_WARN;
default:
- case D3D11_MESSAGE_SEVERITY_INFO:
- case D3D11_MESSAGE_SEVERITY_MESSAGE:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_INFO:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_MESSAGE:
return MSGL_DEBUG;
}
}
static int map_msg_severity_by_id(D3D11_MESSAGE_ID id,
- D3D11_MESSAGE_SEVERITY sev)
+ DXGI_INFO_QUEUE_MESSAGE_SEVERITY sev)
{
switch (id) {
// These are normal. The RA timer queue habitually reuses timer objects
@@ -2168,9 +2172,11 @@ static int map_msg_severity_by_id(D3D11_MESSAGE_ID id,
return map_msg_severity(sev);
}
}
+#endif
static void debug_marker(struct ra *ra, const char *msg)
{
+#if HAVE_DXGI_DEBUG
struct ra_d3d11 *p = ra->priv;
void *talloc_ctx = talloc_new(NULL);
HRESULT hr;
@@ -2180,33 +2186,38 @@ static void debug_marker(struct ra *ra, const char *msg)
// Copy debug-layer messages to mpv's log output
bool printed_header = false;
- uint64_t messages = ID3D11InfoQueue_GetNumStoredMessages(p->iqueue);
+ uint64_t messages = IDXGIInfoQueue_GetNumStoredMessages(p->iqueue,
+ DXGI_DEBUG_ALL);
for (uint64_t i = 0; i < messages; i++) {
SIZE_T len;
- hr = ID3D11InfoQueue_GetMessage(p->iqueue, i, NULL, &len);
+ hr = IDXGIInfoQueue_GetMessage(p->iqueue, DXGI_DEBUG_ALL, i, NULL, &len);
if (FAILED(hr) || !len)
goto done;
- D3D11_MESSAGE *d3dmsg = talloc_size(talloc_ctx, len);
- hr = ID3D11InfoQueue_GetMessage(p->iqueue, i, d3dmsg, &len);
+ DXGI_INFO_QUEUE_MESSAGE *dxgimsg = talloc_size(talloc_ctx, len);
+ hr = IDXGIInfoQueue_GetMessage(p->iqueue, DXGI_DEBUG_ALL, i, dxgimsg, &len);
if (FAILED(hr))
goto done;
- int msgl = map_msg_severity_by_id(d3dmsg->ID, d3dmsg->Severity);
+ int msgl = IsEqualGUID(&dxgimsg->Producer, &DXGI_DEBUG_D3D11)
+ ? map_msg_severity_by_id(dxgimsg->ID, dxgimsg->Severity)
+ : map_msg_severity(dxgimsg->Severity);
+
if (mp_msg_test(ra->log, msgl)) {
if (!printed_header)
MP_INFO(ra, "%s:\n", msg);
printed_header = true;
- MP_MSG(ra, msgl, "%d: %.*s\n", (int)d3dmsg->ID,
- (int)d3dmsg->DescriptionByteLength, d3dmsg->pDescription);
- talloc_free(d3dmsg);
+ MP_MSG(ra, msgl, "%d: %.*s\n", (int)dxgimsg->ID,
+ (int)dxgimsg->DescriptionByteLength, dxgimsg->pDescription);
+ talloc_free(dxgimsg);
}
}
- ID3D11InfoQueue_ClearStoredMessages(p->iqueue);
+ IDXGIInfoQueue_ClearStoredMessages(p->iqueue, DXGI_DEBUG_ALL);
done:
talloc_free(talloc_ctx);
+#endif
}
static void destroy(struct ra *ra)
@@ -2237,16 +2248,18 @@ static void destroy(struct ra *ra)
}
SAFE_RELEASE(p->ctx);
+#if HAVE_DXGI_DEBUG
if (p->debug) {
// Report any leaked objects
debug_marker(ra, "after destroy");
- ID3D11Debug_ReportLiveDeviceObjects(p->debug, D3D11_RLDO_DETAIL);
+ IDXGIDebug_ReportLiveObjects(p->debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_DETAIL);
debug_marker(ra, "after leak check");
- ID3D11Debug_ReportLiveDeviceObjects(p->debug, D3D11_RLDO_SUMMARY);
+ IDXGIDebug_ReportLiveObjects(p->debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_SUMMARY);
debug_marker(ra, "after leak summary");
}
SAFE_RELEASE(p->debug);
SAFE_RELEASE(p->iqueue);
+#endif
talloc_free(ra);
}
@@ -2280,34 +2293,6 @@ void ra_d3d11_flush(struct ra *ra)
ID3D11DeviceContext_Flush(p->ctx);
}
-static void init_debug_layer(struct ra *ra)
-{
- struct ra_d3d11 *p = ra->priv;
- HRESULT hr;
-
- hr = ID3D11Device_QueryInterface(p->dev, &IID_ID3D11Debug,
- (void**)&p->debug);
- if (FAILED(hr)) {
- MP_ERR(ra, "Failed to get debug device: %s\n", mp_HRESULT_to_str(hr));
- return;
- }
-
- hr = ID3D11Device_QueryInterface(p->dev, &IID_ID3D11InfoQueue,
- (void**)&p->iqueue);
- if (FAILED(hr)) {
- MP_ERR(ra, "Failed to get info queue: %s\n", mp_HRESULT_to_str(hr));
- return;
- }
-
- // Store an unlimited amount of messages in the buffer. This is fine
- // because we flush stored messages regularly (in debug_marker.)
- ID3D11InfoQueue_SetMessageCountLimit(p->iqueue, -1);
-
- // Push empty filter to get everything
- D3D11_INFO_QUEUE_FILTER filter = {0};
- ID3D11InfoQueue_PushStorageFilter(p->iqueue, &filter);
-}
-
static struct dll_version get_dll_version(HMODULE dll)
{
void *ctx = talloc_new(NULL);
@@ -2466,8 +2451,10 @@ struct ra *ra_d3d11_create(ID3D11Device *dev, struct mp_log *log,
p->max_uavs = D3D11_PS_CS_UAV_REGISTER_COUNT;
}
+#if HAVE_DXGI_DEBUG
if (ID3D11Device_GetCreationFlags(p->dev) & D3D11_CREATE_DEVICE_DEBUG)
- init_debug_layer(ra);
+ mp_d3d11_get_debug_interfaces(ra->log, &p->debug, &p->iqueue);
+#endif
// Some level 9_x devices don't have timestamp queries
hr = ID3D11Device_CreateQuery(p->dev,
@@ -2481,9 +2468,11 @@ struct ra *ra_d3d11_create(ID3D11Device *dev, struct mp_log *log,
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476874.aspx
find_max_texture_dimension(ra);
+#if HAVE_DXGI_DEBUG
// Ignore any messages during find_max_texture_dimension
if (p->iqueue)
- ID3D11InfoQueue_ClearStoredMessages(p->iqueue);
+ IDXGIInfoQueue_ClearStoredMessages(p->iqueue, DXGI_DEBUG_ALL);
+#endif
MP_VERBOSE(ra, "Maximum Texture2D size: %dx%d\n", ra->max_texture_wh,
ra->max_texture_wh);
diff --git a/video/out/drm_atomic.c b/video/out/drm_atomic.c
index 5754504e98..c1a15fa75f 100644
--- a/video/out/drm_atomic.c
+++ b/video/out/drm_atomic.c
@@ -43,7 +43,7 @@ int drm_object_create_properties(struct mp_log *log, int fd,
return 0;
- fail:
+fail:
drm_object_free_properties(object);
return -1;
}
@@ -68,43 +68,43 @@ void drm_object_free_properties(struct drm_object *object)
int drm_object_get_property(struct drm_object *object, char *name, uint64_t *value)
{
- for (int i = 0; i < object->props->count_props; i++) {
- if (strcasecmp(name, object->props_info[i]->name) == 0) {
- *value = object->props->prop_values[i];
- return 0;
- }
- }
-
- return -EINVAL;
+ for (int i = 0; i < object->props->count_props; i++) {
+ if (strcasecmp(name, object->props_info[i]->name) == 0) {
+ *value = object->props->prop_values[i];
+ return 0;
+ }
+ }
+
+ return -EINVAL;
}
drmModePropertyBlobPtr drm_object_get_property_blob(struct drm_object *object, char *name)
{
- uint64_t blob_id;
+ uint64_t blob_id;
- if (!drm_object_get_property(object, name, &blob_id)) {
- return drmModeGetPropertyBlob(object->fd, blob_id);
- }
+ if (!drm_object_get_property(object, name, &blob_id)) {
+ return drmModeGetPropertyBlob(object->fd, blob_id);
+ }
- return NULL;
+ return NULL;
}
int drm_object_set_property(drmModeAtomicReq *request, struct drm_object *object,
char *name, uint64_t value)
{
- for (int i = 0; i < object->props->count_props; i++) {
- if (strcasecmp(name, object->props_info[i]->name) == 0) {
- if (object->props_info[i]->flags & DRM_MODE_PROP_IMMUTABLE) {
- /* Do not try to set immutable values, as this might cause the
- * atomic commit operation to fail. */
- return -EINVAL;
- }
- return drmModeAtomicAddProperty(request, object->id,
- object->props_info[i]->prop_id, value);
- }
- }
-
- return -EINVAL;
+ for (int i = 0; i < object->props->count_props; i++) {
+ if (strcasecmp(name, object->props_info[i]->name) == 0) {
+ if (object->props_info[i]->flags & DRM_MODE_PROP_IMMUTABLE) {
+ /* Do not try to set immutable values, as this might cause the
+ * atomic commit operation to fail. */
+ return -EINVAL;
+ }
+ return drmModeAtomicAddProperty(request, object->id,
+ object->props_info[i]->prop_id, value);
+ }
+ }
+
+ return -EINVAL;
}
struct drm_object *drm_object_create(struct mp_log *log, int fd,
diff --git a/video/out/drm_common.c b/video/out/drm_common.c
index e47de7df86..0f65a8426a 100644
--- a/video/out/drm_common.c
+++ b/video/out/drm_common.c
@@ -583,7 +583,7 @@ static bool setup_crtc(struct vo_drm_state *drm, const drmModeRes *res)
drm->connector->connector_id);
return false;
- success:
+success:
MP_VERBOSE(drm, "Selected Encoder %u with CRTC %u\n",
drm->encoder->encoder_id, drm->crtc_id);
return true;
diff --git a/video/out/drm_prime.c b/video/out/drm_prime.c
index 9335fa8e02..581eb717bb 100644
--- a/video/out/drm_prime.c
+++ b/video/out/drm_prime.c
@@ -86,13 +86,13 @@ int drm_prime_create_framebuffer(struct mp_log *log, int fd,
for (int plane = 0; plane < AV_DRM_MAX_PLANES; plane++) {
drm_prime_add_handle_ref(handle_refs, framebuffer->gem_handles[plane]);
}
- }
+ }
- return 0;
+ return 0;
fail:
- memset(framebuffer, 0, sizeof(*framebuffer));
- return -1;
+ memset(framebuffer, 0, sizeof(*framebuffer));
+ return -1;
}
void drm_prime_destroy_framebuffer(struct mp_log *log, int fd,
@@ -129,9 +129,11 @@ void drm_prime_add_handle_ref(struct drm_prime_handle_refs *handle_refs,
{
if (handle) {
if (handle > handle_refs->size) {
- handle_refs->size = handle;
MP_TARRAY_GROW(handle_refs->ctx, handle_refs->handle_ref_count,
- handle_refs->size);
+ handle - 1);
+ uint32_t *p = handle_refs->handle_ref_count;
+ memset(&p[handle_refs->size], 0, (handle - handle_refs->size) * sizeof(p[0]));
+ handle_refs->size = handle;
}
handle_refs->handle_ref_count[handle - 1]++;
}
diff --git a/video/out/gpu/context.c b/video/out/gpu/context.c
index 88d4f4232d..3202729741 100644
--- a/video/out/gpu/context.c
+++ b/video/out/gpu/context.c
@@ -57,7 +57,27 @@ extern const struct ra_ctx_fns ra_ctx_d3d11;
/* No API */
extern const struct ra_ctx_fns ra_ctx_wldmabuf;
+/* Autoprobe dummy. Always fails to create. */
+static bool dummy_init(struct ra_ctx *ctx)
+{
+ return false;
+}
+
+static void dummy_uninit(struct ra_ctx *ctx)
+{
+}
+
+static const struct ra_ctx_fns ra_ctx_dummy = {
+ .type = "auto",
+ .name = "auto",
+ .description = "Auto detect",
+ .init = dummy_init,
+ .uninit = dummy_uninit,
+};
+
static const struct ra_ctx_fns *contexts[] = {
+ &ra_ctx_dummy,
+// Direct3D contexts:
#if HAVE_D3D11
&ra_ctx_d3d11,
#endif
@@ -110,21 +130,53 @@ static const struct ra_ctx_fns *contexts[] = {
&ra_ctx_vulkan_mac,
#endif
#endif
+};
+static const struct ra_ctx_fns *no_api_contexts[] = {
+ &ra_ctx_dummy,
/* No API contexts: */
#if HAVE_DMABUF_WAYLAND
&ra_ctx_wldmabuf,
#endif
};
+static bool get_desc(struct m_obj_desc *dst, int index)
+{
+ if (index >= MP_ARRAY_SIZE(contexts))
+ return false;
+ const struct ra_ctx_fns *ctx = contexts[index];
+ *dst = (struct m_obj_desc) {
+ .name = ctx->name,
+ .description = ctx->description,
+ };
+ return true;
+}
+
+static bool check_unknown_entry(const char *name)
+{
+ struct bstr param = bstr0(name);
+ for (int i = 0; i < MP_ARRAY_SIZE(contexts); i++) {
+ if (bstr_equals0(param, contexts[i]->name))
+ return true;
+ }
+ return false;
+}
+
+const struct m_obj_list ra_ctx_obj_list = {
+ .get_desc = get_desc,
+ .check_unknown_entry = check_unknown_entry,
+ .description = "GPU contexts",
+ .allow_trailer = true,
+ .disallow_positional_parameters = true,
+ .use_global_options = true,
+};
+
static int ra_ctx_api_help(struct mp_log *log, const struct m_option *opt,
struct bstr name)
{
mp_info(log, "GPU APIs (contexts):\n");
- mp_info(log, " auto (autodetect)\n");
for (int n = 0; n < MP_ARRAY_SIZE(contexts); n++) {
- if (!contexts[n]->hidden)
- mp_info(log, " %s (%s)\n", contexts[n]->type, contexts[n]->name);
+ mp_info(log, " %s (%s)\n", contexts[n]->type, contexts[n]->name);
}
return M_OPT_EXIT;
}
@@ -132,37 +184,63 @@ static int ra_ctx_api_help(struct mp_log *log, const struct m_option *opt,
static inline OPT_STRIN