diff options
author | Daniel Stone <daniels@collabora.com> | 2018-04-04 16:16:34 +0100 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2018-04-04 13:46:57 -0400 |
commit | 1b9fa3b64ca420eb54b5e5f28074c326e1fbe825 (patch) | |
tree | a4d88f01786ce20b2e5409dc8aca5c3d38a6ff75 | |
parent | 0e9504e10c4363e24a83f1a82e6a4b9f5fd8f846 (diff) |
glamor: Track if BO allocation used modifiers
Keep track of whether or not we fed modifiers into GBM when we allocated
a BO. We'll use this later inside Glamor, to reallocate buffer storage
if we allocate buffer storage using modifiers, and a non-modifier-aware
client requests an export of that pixmap.
This makes it possible to run a compositing manager on an old GLX/EGL
stack on top of an X server which allocates internal buffer storage
using exotic modifiers from modifier-aware GBM/EGL/KMS.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Reported-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | glamor/glamor.h | 3 | ||||
-rw-r--r-- | glamor/glamor_egl.c | 29 | ||||
-rw-r--r-- | glamor/glamor_priv.h | 1 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.c | 3 |
4 files changed, 25 insertions, 11 deletions
diff --git a/glamor/glamor.h b/glamor/glamor.h index 7b5676226..b0b23d3a3 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -391,7 +391,8 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap, */ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, - struct gbm_bo *bo); + struct gbm_bo *bo, + Bool used_modifiers); #endif diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index f82fa519b..0e771b6d2 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -150,7 +150,8 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride) } static void -glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image) +glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image, + Bool used_modifiers) { struct glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -165,6 +166,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image) eglDestroyImageKHR(glamor_egl->display, old); } pixmap_priv->image = image; + pixmap_priv->used_modifiers = used_modifiers; } Bool @@ -204,7 +206,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) Bool glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, - struct gbm_bo *bo) + struct gbm_bo *bo, + Bool used_modifiers) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); @@ -229,7 +232,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, glamor_create_texture_from_image(screen, image, &texture); glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_texture(pixmap, texture); - glamor_egl_set_pixmap_image(pixmap, image); + glamor_egl_set_pixmap_image(pixmap, image, used_modifiers); ret = TRUE; done: @@ -259,6 +262,7 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap) unsigned height = pixmap->drawable.height; uint32_t format; struct gbm_bo *bo; + Bool used_modifiers = FALSE; PixmapPtr exported; GCPtr scratch_gc; @@ -286,6 +290,8 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap) bo = gbm_bo_create_with_modifiers(glamor_egl->gbm, width, height, format, modifiers, num_modifiers); + if (bo) + used_modifiers = TRUE; free(modifiers); } else @@ -309,7 +315,8 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap) exported = screen->CreatePixmap(screen, 0, 0, pixmap->drawable.depth, 0); screen->ModifyPixmapHeader(exported, width, height, 0, 0, gbm_bo_get_stride(bo), NULL); - if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo)) { + if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo, + used_modifiers)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make %dx%dx%dbpp pixmap from GBM bo\n", width, height, pixmap->drawable.bitsPerPixel); @@ -452,7 +459,7 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap, screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL); - ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); + ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, FALSE); gbm_bo_destroy(bo); return ret; } @@ -509,7 +516,7 @@ glamor_pixmap_from_fds(ScreenPtr screen, bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data, 0); if (bo) { screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL); - ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); + ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, TRUE); gbm_bo_destroy(bo); } } else @@ -667,7 +674,8 @@ glamor_egl_destroy_pixmap(PixmapPtr pixmap) _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back) { - EGLImageKHR temp; + EGLImageKHR temp_img; + Bool temp_mod; struct glamor_pixmap_private *front_priv = glamor_get_pixmap_private(front); struct glamor_pixmap_private *back_priv = @@ -675,9 +683,12 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back) glamor_pixmap_exchange_fbos(front, back); - temp = back_priv->image; + temp_img = back_priv->image; + temp_mod = back_priv->used_modifiers; back_priv->image = front_priv->image; - front_priv->image = temp; + back_priv->used_modifiers = front_priv->used_modifiers; + front_priv->image = temp_img; + front_priv->used_modifiers = temp_mod; glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 3fff6396c..7d9a7d4fb 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -341,6 +341,7 @@ typedef struct glamor_pixmap_private { Bool prepared; #ifdef GLAMOR_HAS_GBM EGLImageKHR image; + Bool used_modifiers; #endif /** block width of this large pixmap. */ int block_w; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 4fe59d22e..930a2716f 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -2822,7 +2822,8 @@ drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo) if (!drmmode->glamor) return TRUE; - if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) { + if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm, + bo->used_modifiers)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create pixmap\n"); return FALSE; } |