wayland/dma-buf: Handle lack of gbm_device gracefully
In some configurations (e.g. NVIDIA driver 470) Xwayland may use DMA buffer for passing buffers around. When this is done, we might attempt to scanout these buffers when they are fullscreen, and to do so we import them using gbm. However, for the mentioned configuration, there is no gbm device available for importing. This was not handled, and resulted in a crash; avoid this crash by checking whether we have a gbm device and fail gracefully if we don't. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2098 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2318>
This commit is contained in:
parent
370de58868
commit
a09b99261f
1 changed files with 34 additions and 13 deletions
|
@ -471,11 +471,19 @@ static struct gbm_bo *
|
||||||
import_scanout_gbm_bo (MetaWaylandDmaBufBuffer *dma_buf,
|
import_scanout_gbm_bo (MetaWaylandDmaBufBuffer *dma_buf,
|
||||||
MetaGpuKms *gpu_kms,
|
MetaGpuKms *gpu_kms,
|
||||||
int n_planes,
|
int n_planes,
|
||||||
gboolean *use_modifier)
|
gboolean *use_modifier,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
struct gbm_device *gbm_device;
|
struct gbm_device *gbm_device;
|
||||||
|
struct gbm_bo *gbm_bo;
|
||||||
|
|
||||||
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
|
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
|
||||||
|
if (!gbm_device)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"No gbm_device available");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID ||
|
if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID ||
|
||||||
n_planes > 1 ||
|
n_planes > 1 ||
|
||||||
|
@ -501,7 +509,8 @@ import_scanout_gbm_bo (MetaWaylandDmaBufBuffer *dma_buf,
|
||||||
sizeof (import_with_modifier.offsets));
|
sizeof (import_with_modifier.offsets));
|
||||||
|
|
||||||
*use_modifier = TRUE;
|
*use_modifier = TRUE;
|
||||||
return gbm_bo_import (gbm_device, GBM_BO_IMPORT_FD_MODIFIER,
|
|
||||||
|
gbm_bo = gbm_bo_import (gbm_device, GBM_BO_IMPORT_FD_MODIFIER,
|
||||||
&import_with_modifier,
|
&import_with_modifier,
|
||||||
GBM_BO_USE_SCANOUT);
|
GBM_BO_USE_SCANOUT);
|
||||||
}
|
}
|
||||||
|
@ -518,10 +527,19 @@ import_scanout_gbm_bo (MetaWaylandDmaBufBuffer *dma_buf,
|
||||||
};
|
};
|
||||||
|
|
||||||
*use_modifier = FALSE;
|
*use_modifier = FALSE;
|
||||||
return gbm_bo_import (gbm_device, GBM_BO_IMPORT_FD,
|
gbm_bo = gbm_bo_import (gbm_device, GBM_BO_IMPORT_FD,
|
||||||
&import_legacy,
|
&import_legacy,
|
||||||
GBM_BO_USE_SCANOUT);
|
GBM_BO_USE_SCANOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gbm_bo)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
|
||||||
|
"gbm_bo_import failed: %s", g_strerror (errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gbm_bo;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -550,10 +568,12 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
|
||||||
|
|
||||||
device_file = meta_renderer_native_get_primary_device_file (renderer_native);
|
device_file = meta_renderer_native_get_primary_device_file (renderer_native);
|
||||||
gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
|
gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
|
||||||
gbm_bo = import_scanout_gbm_bo (dma_buf, gpu_kms, n_planes, &use_modifier);
|
gbm_bo = import_scanout_gbm_bo (dma_buf, gpu_kms, n_planes, &use_modifier,
|
||||||
|
&error);
|
||||||
if (!gbm_bo)
|
if (!gbm_bo)
|
||||||
{
|
{
|
||||||
g_debug ("Failed to import scanout gbm_bo: %s", g_strerror (errno));
|
meta_topic (META_DEBUG_WAYLAND,
|
||||||
|
"Failed to import scanout gbm_bo: %s", error->message);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +584,8 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
|
||||||
fb = meta_drm_buffer_gbm_new_take (device_file, gbm_bo, flags, &error);
|
fb = meta_drm_buffer_gbm_new_take (device_file, gbm_bo, flags, &error);
|
||||||
if (!fb)
|
if (!fb)
|
||||||
{
|
{
|
||||||
g_debug ("Failed to create scanout buffer: %s", error->message);
|
meta_topic (META_DEBUG_WAYLAND,
|
||||||
|
"Failed to create scanout buffer: %s", error->message);
|
||||||
gbm_bo_destroy (gbm_bo);
|
gbm_bo_destroy (gbm_bo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue