Fix pipewire capture on amd (fallback to no drm modifiers if eglCreateImage fails), might happen because of a buggy desktop portal/pipewire implementation

This commit is contained in:
dec05eba
2024-07-22 17:20:09 +02:00
parent 28eef4619f
commit e9343cce91
4 changed files with 39 additions and 6 deletions

2
TODO
View File

@@ -157,3 +157,5 @@ HDR support on x11?
Move most kms data to kms client. We dont need root access for everything that is server from kms server right now, such as hdr metadata and drm plane properties. Only the drm plane fd really needs root access.
Show rotated window size in monitor list when using incorrect monitor name.
Desktop portal capture on kde plasma makes notifications not show up unless the notification is set as urgent. How to fix this? do we have to make our own notification system?

View File

@@ -84,6 +84,7 @@ typedef struct {
bool started;
bool stopped;
bool no_modifiers_fallback;
uint64_t modifiers[GSR_PIPEWIRE_MAX_MODIFIERS];
size_t num_modifiers;

View File

@@ -43,6 +43,8 @@ typedef struct {
unsigned int input_texture_id;
unsigned int cursor_texture_id;
bool no_modifiers_fallback;
} gsr_capture_kms;
static void gsr_capture_kms_cleanup_kms_fds(gsr_capture_kms *self) {
@@ -399,11 +401,23 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVStream *video_stream, AVF
modifiers[i] = drm_fd->modifier;
}
EGLImage image = NULL;
intptr_t img_attr[44];
setup_dma_buf_attrs(img_attr, drm_fd->pixel_format, drm_fd->width, drm_fd->height,
fds, offsets, pitches, modifiers, drm_fd->num_dma_bufs, true);
EGLImage image = self->params.egl->eglCreateImage(self->params.egl->egl_display, 0, EGL_LINUX_DMA_BUF_EXT, NULL, img_attr);
if(self->no_modifiers_fallback) {
setup_dma_buf_attrs(img_attr, drm_fd->pixel_format, drm_fd->width, drm_fd->height, fds, offsets, pitches, modifiers, drm_fd->num_dma_bufs, false);
} else {
setup_dma_buf_attrs(img_attr, drm_fd->pixel_format, drm_fd->width, drm_fd->height, fds, offsets, pitches, modifiers, drm_fd->num_dma_bufs, true);
while(self->params.egl->eglGetError() != EGL_SUCCESS){}
image = self->params.egl->eglCreateImage(self->params.egl->egl_display, 0, EGL_LINUX_DMA_BUF_EXT, NULL, img_attr);
if(!image || self->params.egl->eglGetError() != EGL_SUCCESS) {
fprintf(stderr, "gsr error: gsr_capture_kms_capture: failed to create egl image with modifiers, trying without modifiers\n");
self->no_modifiers_fallback = true;
setup_dma_buf_attrs(img_attr, drm_fd->pixel_format, drm_fd->width, drm_fd->height, fds, offsets, pitches, modifiers, drm_fd->num_dma_bufs, false);
image = self->params.egl->eglCreateImage(self->params.egl->egl_display, 0, EGL_LINUX_DMA_BUF_EXT, NULL, img_attr);
}
}
self->params.egl->glBindTexture(GL_TEXTURE_2D, self->input_texture_id);
self->params.egl->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
self->params.egl->eglDestroyImage(self->params.egl->egl_display, image);

View File

@@ -643,11 +643,27 @@ bool gsr_pipewire_map_texture(gsr_pipewire *self, unsigned int texture_id, unsig
modifiers[i] = self->format.info.raw.modifier;
}
EGLImage image = NULL;
intptr_t img_attr[44];
if(self->no_modifiers_fallback) {
setup_dma_buf_attrs(img_attr, spa_video_format_to_drm_format(self->format.info.raw.format), self->format.info.raw.size.width, self->format.info.raw.size.height,
fds, offsets, pitches, modifiers, self->dmabuf_num_planes, false);
} else {
setup_dma_buf_attrs(img_attr, spa_video_format_to_drm_format(self->format.info.raw.format), self->format.info.raw.size.width, self->format.info.raw.size.height,
fds, offsets, pitches, modifiers, self->dmabuf_num_planes, true);
EGLImage image = self->egl->eglCreateImage(self->egl->egl_display, 0, EGL_LINUX_DMA_BUF_EXT, NULL, img_attr);
while(self->egl->eglGetError() != EGL_SUCCESS){}
image = self->egl->eglCreateImage(self->egl->egl_display, 0, EGL_LINUX_DMA_BUF_EXT, NULL, img_attr);
if(!image || self->egl->eglGetError() != EGL_SUCCESS) {
fprintf(stderr, "gsr error: gsr_pipewire_map_texture: failed to create egl image with modifiers, trying without modifiers\n");
self->no_modifiers_fallback = true;
setup_dma_buf_attrs(img_attr, spa_video_format_to_drm_format(self->format.info.raw.format), self->format.info.raw.size.width, self->format.info.raw.size.height,
fds, offsets, pitches, modifiers, self->dmabuf_num_planes, false);
image = self->egl->eglCreateImage(self->egl->egl_display, 0, EGL_LINUX_DMA_BUF_EXT, NULL, img_attr);
}
}
self->egl->glBindTexture(GL_TEXTURE_2D, texture_id);
self->egl->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
self->egl->eglDestroyImage(self->egl->egl_display, image);