mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-22 06:35:57 +01:00
screencast: create gbm device
This is done by using the first device returned by getDRMDevices2 containing a render node (DRM_NODE_RENDER).
This commit is contained in:
parent
7c7cb88d8f
commit
9d620273e5
4 changed files with 62 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
|||
#ifndef SCREENCAST_COMMON_H
|
||||
#define SCREENCAST_COMMON_H
|
||||
|
||||
#include <gbm.h>
|
||||
#include <pipewire/pipewire.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
|
@ -103,6 +104,9 @@ struct xdpw_screencast_context {
|
|||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct wl_shm *shm;
|
||||
|
||||
// gbm
|
||||
struct gbm_device *gbm;
|
||||
|
||||
// sessions
|
||||
struct wl_list screencast_instances;
|
||||
};
|
||||
|
@ -158,6 +162,7 @@ struct xdpw_wlr_output {
|
|||
};
|
||||
|
||||
void randname(char *buf);
|
||||
struct gbm_device *xdpw_gbm_device_create(void);
|
||||
struct xdpw_buffer *xdpw_buffer_create(struct xdpw_screencast_instance *cast,
|
||||
enum buffer_type buffer_type, struct xdpw_screencopy_frame_info *frame_info);
|
||||
void xdpw_buffer_destroy(struct xdpw_buffer *buffer);
|
||||
|
|
|
@ -27,6 +27,8 @@ pipewire = dependency('libpipewire-0.3', version: '>= 0.3.41')
|
|||
wayland_client = dependency('wayland-client')
|
||||
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
|
||||
iniparser = dependency('inih')
|
||||
gbm = dependency('gbm')
|
||||
drm = dependency('libdrm')
|
||||
|
||||
epoll = dependency('', required: false)
|
||||
if (not cc.has_function('timerfd_create', prefix: '#include <sys/timerfd.h>') or
|
||||
|
@ -92,6 +94,8 @@ executable(
|
|||
pipewire,
|
||||
rt,
|
||||
iniparser,
|
||||
gbm,
|
||||
drm,
|
||||
epoll,
|
||||
],
|
||||
include_directories: [inc],
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
|
@ -20,6 +21,47 @@ void randname(char *buf) {
|
|||
}
|
||||
}
|
||||
|
||||
static char *gbm_find_render_node() {
|
||||
drmDevice *devices[64];
|
||||
char *render_node = NULL;
|
||||
|
||||
int n = drmGetDevices2(0, devices, sizeof(devices) / sizeof(devices[0]));
|
||||
for (int i = 0; i < n; ++i) {
|
||||
drmDevice *dev = devices[i];
|
||||
if (!(dev->available_nodes & (1 << DRM_NODE_RENDER)))
|
||||
continue;
|
||||
|
||||
render_node = strdup(dev->nodes[DRM_NODE_RENDER]);
|
||||
break;
|
||||
}
|
||||
|
||||
drmFreeDevices(devices, n);
|
||||
return render_node;
|
||||
}
|
||||
|
||||
struct gbm_device *xdpw_gbm_device_create(void) {
|
||||
struct gbm_device *gbm;
|
||||
char *render_node = NULL;
|
||||
|
||||
render_node = gbm_find_render_node();
|
||||
if (render_node == NULL) {
|
||||
logprint(ERROR, "xdpw: Could not find render node");
|
||||
return NULL;
|
||||
}
|
||||
logprint(INFO, "xdpw: Using render node %s", render_node);
|
||||
|
||||
int fd = open(render_node, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
logprint(ERROR, "xdpw: Could not open render node %s", render_node);
|
||||
free(render_node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(render_node);
|
||||
gbm = gbm_create_device(fd);
|
||||
return gbm;
|
||||
}
|
||||
|
||||
static int anonymous_shm_open(void) {
|
||||
char name[] = "/xdpw-shm-XXXXXX";
|
||||
int retries = 100;
|
||||
|
|
|
@ -641,6 +641,12 @@ int xdpw_wlr_screencopy_init(struct xdpw_state *state) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// make sure we have a gbm device
|
||||
ctx->gbm = xdpw_gbm_device_create();
|
||||
if (!ctx->gbm) {
|
||||
logprint(ERROR, "System doesn't support gbm!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -666,6 +672,11 @@ void xdpw_wlr_screencopy_finish(struct xdpw_screencast_context *ctx) {
|
|||
if (ctx->xdg_output_manager) {
|
||||
zxdg_output_manager_v1_destroy(ctx->xdg_output_manager);
|
||||
}
|
||||
if (ctx->gbm) {
|
||||
int fd = gbm_device_get_fd(ctx->gbm);
|
||||
gbm_device_destroy(ctx->gbm);
|
||||
close(fd);
|
||||
}
|
||||
if (ctx->registry) {
|
||||
wl_registry_destroy(ctx->registry);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue