| @@ -1363,6 +1363,12 @@ static void format_table(void *data, · 1362 unmodified lines |
| 1363 | 1363 | { |
| 1364 | 1364 | struct vo_wayland_state *wl = data; |
| 1365 | 1365 | |
| 1366 | + if (wl->compositor_format_size) { |
| 1367 | + munmap(wl->compositor_format_map, wl->compositor_format_size); |
| 1368 | + wl->compositor_format_map = NULL; |
| 1369 | + wl->compositor_format_size = 0; |
| 1370 | + } |
| 1371 | + |
| 1366 | 1372 | void *map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); |
| 1367 | 1373 | close(fd); |
| 1368 | 1374 | |
| @@ -1377,32 +1383,62 @@ static void main_device(void *data, · 8 unmodified lines |
| 1377 | 1383 | struct wl_array *device) |
| 1378 | 1384 | { |
| 1379 | 1385 | struct vo_wayland_state *wl = data; |
| 1386 | + wl->add_tranche = true; |
| 1380 | 1387 | |
| 1381 | | − // Despite being an array, the protocol specifically states there can only be |
| 1382 | | − // one main device so break as soon as we get one. |
| 1383 | | − dev_t *id; |
| 1384 | | − wl_array_for_each(id, device) { |
| 1385 | | − memcpy(&wl->main_device_id, id, sizeof(dev_t)); |
| 1386 | | − break; |
| 1387 | | − } |
| 1388 | | − get_gpu_drm_formats(wl); |
| 1389 | 1388 | } |
| 1390 | 1389 | |
| 1391 | 1390 | static void tranche_done(void *data, |
| 1392 | 1391 | struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1) |
| 1393 | 1392 | { |
| 1393 | + struct vo_wayland_state *wl = data; |
| 1394 | + wl->add_tranche = false; |
| 1394 | 1395 | } |
| 1395 | 1396 | |
| 1396 | 1397 | static void tranche_target_device(void *data, |
| 1397 | 1398 | struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1, |
| 1398 | 1399 | struct wl_array *device) |
| 1399 | 1400 | { |
| 1401 | + struct vo_wayland_state *wl = data; |
| 1402 | + // Only use the first tranche device we get. |
| 1403 | + if (wl->add_tranche) { |
| 1404 | + dev_t *id; |
| 1405 | + wl_array_for_each(id, device) { |
| 1406 | + memcpy(&wl->target_device_id, id, sizeof(dev_t)); |
| 1407 | + break; |
| 1408 | + } |
| 1409 | + get_gpu_drm_formats(wl); |
| 1410 | + } |
| 1400 | 1411 | } |
| 1401 | 1412 | |
| 1402 | 1413 | static void tranche_formats(void *data, |
| 1403 | 1414 | struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1, |
| 1404 | 1415 | struct wl_array *indices) |
| 1405 | 1416 | { |
| 1417 | + struct vo_wayland_state *wl = data; |
| 1418 | + |
| 1419 | + // Only grab formats from the first tranche and ignore the rest. |
| 1420 | + if (!wl->add_tranche) |
| 1421 | + return; |
| 1422 | + |
| 1423 | + // Should never happen. |
| 1424 | + if (!wl->compositor_format_map) { |
| 1425 | + MP_WARN(wl, "Compositor did not send a format and modifier table!\n"); |
| 1426 | + return; |
| 1427 | + } |
| 1428 | + |
| 1429 | + const compositor_format *formats = wl->compositor_format_map; |
| 1430 | + MP_RESIZE_ARRAY(wl, wl->compositor_formats, indices->size); |
| 1431 | + wl->num_compositor_formats = 0; |
| 1432 | + uint16_t *index; |
| 1433 | + wl_array_for_each(index, indices) { |
| 1434 | + MP_TARRAY_APPEND(wl, wl->compositor_formats, wl->num_compositor_formats, |
| 1435 | + (struct drm_format) { |
| 1436 | + formats[*index].format, |
| 1437 | + formats[*index].modifier, |
| 1438 | + }); |
| 1439 | + MP_DBG(wl, "Compositor supports drm format: '%s(%016" PRIx64 ")'\n", |
| 1440 | + mp_tag_str(formats[*index].format), formats[*index].modifier); |
| 1441 | + } |
| 1406 | 1442 | } |
| 1407 | 1443 | |
| 1408 | 1444 | static void tranche_flags(void *data, |
| @@ -1799,7 +1835,7 @@ static void get_gpu_drm_formats(struct vo_wayland_state *wl) · 390 unmodified lines |
| 1799 | 1835 | drmModePlaneRes *res = NULL; |
| 1800 | 1836 | drmModePlane *plane = NULL; |
| 1801 | 1837 | |
| 1802 | | − if (drmGetDeviceFromDevId(wl->main_device_id, 0, &device) != 0) { |
| 1838 | + if (drmGetDeviceFromDevId(wl->target_device_id, 0, &device) != 0) { |
| 1803 | 1839 | MP_WARN(wl, "Unable to get drm device from device id: %s\n", mp_strerror(errno)); |
| 1804 | 1840 | goto done; |
| 1805 | 1841 | } |