123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- From e98ab37481eb89284b95a84bdb01a43262841cce Mon Sep 17 00:00:00 2001
- From: Brendan King <Brendan.King@imgtec.com>
- Date: Fri, 21 Aug 2020 12:13:28 +0100
- Subject: [PATCH] gbm: add pbuffer support
- The EGL backend GLX provider for XWayland may get the EGL configs it
- uses to generate the GLX ones from GBM. That platform doesn't support
- pbuffers. When the client tries to match GLX configs with the DRI ones,
- a mismatch in the pbuffer attributes will result in the GLX config
- being rejected.
- Although support for creating pbuffers has been added, this isn't
- required when using the EGL backend GLX provider, as indirect GLX
- isn't supported.
- ---
- src/egl/drivers/dri2/egl_dri2.h | 3 +
- src/egl/drivers/dri2/platform_drm.c | 110 +++++++++++++++++++++++++---
- 2 files changed, 103 insertions(+), 10 deletions(-)
- diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
- index 27beae5..f8792ea 100644
- --- a/src/egl/drivers/dri2/egl_dri2.h
- +++ b/src/egl/drivers/dri2/egl_dri2.h
- @@ -468,6 +468,9 @@ struct dri2_egl_surface
- /* surfaceless and device */
- __DRIimage *front;
- unsigned int visual;
- +#ifdef HAVE_DRM_PLATFORM
- + struct gbm_bo *front_bo;
- +#endif
-
- #ifdef HAVE_WAYLAND_PLATFORM
- void *swrast_front;
- diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
- index 2b32943..258e8b6 100644
- --- a/src/egl/drivers/dri2/platform_drm.c
- +++ b/src/egl/drivers/dri2/platform_drm.c
- @@ -41,6 +41,38 @@
- #include "egl_dri2.h"
- #include "loader.h"
-
- +static bool
- +dri2_drm_alloc_front_image(struct dri2_egl_surface *dri2_surf)
- +{
- + if (!dri2_surf->front_bo) {
- + struct dri2_egl_display *dri2_dpy =
- + dri2_egl_display(dri2_surf->base.Resource.Display);
- +
- + struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
- +
- + dri2_surf->front_bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
- + surf->base.v0.width,
- + surf->base.v0.height,
- + surf->base.v0.format,
- + surf->base.v0.flags);
- + if (!dri2_surf->front_bo) {
- + _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
- + return false;
- + }
- + }
- +
- + return true;
- +}
- +
- +static void
- +dri2_drm_free_front_image(struct dri2_egl_surface *dri2_surf)
- +{
- + if (dri2_surf->front_bo) {
- + gbm_bo_destroy(dri2_surf->front_bo);
- + dri2_surf->front_bo = NULL;
- + }
- +}
- +
- static struct gbm_bo *
- lock_front_buffer(struct gbm_surface *_surf)
- {
- @@ -138,8 +170,8 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
- }
-
- static _EGLSurface *
- -dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
- - void *native_surface, const EGLint *attrib_list)
- +dri2_drm_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
- + void *native_surface, const EGLint *attrib_list)
- {
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
- @@ -154,11 +186,25 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
- return NULL;
- }
-
- - if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
- + if (!dri2_init_surface(&dri2_surf->base, disp, type, conf,
- attrib_list, false, native_surface))
- goto cleanup_surf;
-
- - config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
- + if (type == EGL_PBUFFER_BIT) {
- + struct gbm_device *gbm = disp->PlatformDisplay;
- + _EGLSurface *surf = &dri2_surf->base;
- +
- + assert(!surface);
- +
- + surface = gbm_surface_create(gbm, surf->Width, surf->Height,
- + conf->NativeVisualID, GBM_BO_USE_RENDERING);
- + if (!surface) {
- + _eglError(EGL_BAD_ALLOC, "Failed to allocate pbuffer GBM surface");
- + goto cleanup_surf;
- + }
- + }
- +
- + config = dri2_get_dri_config(dri2_conf, type,
- dri2_surf->base.GLColorspace);
-
- if (!config) {
- @@ -183,11 +229,22 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
- return &dri2_surf->base;
-
- cleanup_surf:
- + if (type == EGL_PBUFFER_BIT && surface != NULL)
- + gbm_surface_destroy(surface);
- +
- free(dri2_surf);
-
- return NULL;
- }
-
- +static _EGLSurface *
- +dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
- + void *native_surface, const EGLint *attrib_list)
- +{
- + return dri2_drm_create_surface(disp, EGL_WINDOW_BIT, conf,
- + native_surface, attrib_list);
- +}
- +
- static _EGLSurface *
- dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
- void *native_window, const EGLint *attrib_list)
- @@ -202,6 +259,14 @@ dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
- return NULL;
- }
-
- +static _EGLSurface *
- +dri2_drm_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
- + const EGLint *attrib_list)
- +{
- + return dri2_drm_create_surface(disp, EGL_PBUFFER_BIT, conf,
- + NULL, attrib_list);
- +}
- +
- static EGLBoolean
- dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
- {
- @@ -217,6 +282,11 @@ dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
-
- dri2_egl_surface_free_local_buffers(dri2_surf);
-
- + dri2_drm_free_front_image(dri2_surf);
- +
- + if (surf->Type == EGL_PBUFFER_BIT)
- + gbm_surface_destroy(&dri2_surf->gbm_surf->base);
- +
- dri2_fini_surface(surf);
- free(surf);
-
- @@ -402,12 +472,27 @@ dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
- struct dri2_egl_surface *dri2_surf = loaderPrivate;
- struct gbm_dri_bo *bo;
-
- - if (get_back_bo(dri2_surf) < 0)
- - return 0;
- + buffers->image_mask = 0;
- + buffers->front = NULL;
- + buffers->back = NULL;
-
- - bo = gbm_dri_bo(dri2_surf->back->bo);
- - buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
- - buffers->back = bo->image;
- + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
- + if (!dri2_drm_alloc_front_image(dri2_surf))
- + return 0;
- +
- + bo = gbm_dri_bo(dri2_surf->front_bo);
- + buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
- + buffers->front = bo->image;
- + }
- +
- + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
- + if (get_back_bo(dri2_surf) < 0)
- + return 0;
- +
- + bo = gbm_dri_bo(dri2_surf->back->bo);
- + buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
- + buffers->back = bo->image;
- + }
-
- return 1;
- }
- @@ -425,6 +510,9 @@ dri2_drm_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
-
- + if (dri2_surf->base.Type != EGL_WINDOW_BIT)
- + return EGL_TRUE;
- +
- if (!dri2_dpy->flush) {
- dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
- return EGL_TRUE;
- @@ -648,7 +736,8 @@ drm_add_configs_for_visuals(_EGLDisplay *disp)
- };
-
- dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- - config_count + 1, EGL_WINDOW_BIT, attr_list, NULL, NULL);
- + config_count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
- + attr_list, NULL, NULL);
- if (dri2_conf) {
- if (dri2_conf->base.ConfigID == config_count + 1)
- config_count++;
- @@ -672,6 +761,7 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
- .authenticate = dri2_drm_authenticate,
- .create_window_surface = dri2_drm_create_window_surface,
- .create_pixmap_surface = dri2_drm_create_pixmap_surface,
- + .create_pbuffer_surface = dri2_drm_create_pbuffer_surface,
- .destroy_surface = dri2_drm_destroy_surface,
- .create_image = dri2_drm_create_image_khr,
- .swap_buffers = dri2_drm_swap_buffers,
|