[RFC v2 06/13] glamor: Use gbm_bo_create_with_modifiers for internal pixmap allocation
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Fri Jul 14 04:47:53 UTC 2017
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
configure.ac | 4 +++
glamor/glamor_egl.c | 73 +++++++++++++++++++++++++++++++++++++------
hw/xwayland/xwayland-glamor.c | 22 +++++++++++--
include/dix-config.h.in | 3 ++
4 files changed, 90 insertions(+), 12 deletions(-)
diff --git a/configure.ac b/configure.ac
index fbee76211..7587f311e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2095,6 +2095,10 @@ if test "x$GLAMOR" = xyes; then
[AC_DEFINE(GLAMOR_HAS_GBM_LINEAR, 1, [Have GBM_BO_USE_LINEAR])], [],
[#include <stdlib.h>
#include <gbm.h>])
+ dnl 17.1.0 is required for gbm_bo_create_with_modifiers
+ PKG_CHECK_EXISTS(gbm >= 17.1.0,
+ [AC_DEFINE(GBM_BO_WITH_MODIFIERS, 1, [Have gbm_bo_create_with_modifiers])],
+ [])
else
if test "x$XORG" = xyes; then
AC_MSG_ERROR([Glamor for Xorg requires $LIBGBM])
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 8bd050308..af956a05d 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -294,9 +294,11 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap)
glamor_get_pixmap_private(pixmap);
unsigned width = pixmap->drawable.width;
unsigned height = pixmap->drawable.height;
+ uint64_t modifier = 0;
struct gbm_bo *bo;
PixmapPtr exported;
GCPtr scratch_gc;
+ Bool ret = FALSE;
if (pixmap_priv->image)
return TRUE;
@@ -308,13 +310,31 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap)
return FALSE;
}
- bo = gbm_bo_create(glamor_egl->gbm, width, height,
- GBM_FORMAT_ARGB8888,
+#ifdef GBM_BO_WITH_MODIFIERS
+ if (glamor_egl->modifiers_capable) {
+ uint32_t num_modifiers;
+ uint64_t *modifiers = NULL;
+
+ glamor_get_modifiers(screen, DRM_FORMAT_ARGB8888,
+ &num_modifiers, &modifiers);
+ bo = gbm_bo_create_with_modifiers(glamor_egl->gbm, width, height,
+ GBM_FORMAT_ARGB8888,
+ modifiers, num_modifiers);
+ modifier = gbm_bo_get_modifier(bo);
+ free(modifiers);
+ }
+ else
+#endif
+ {
+ bo = gbm_bo_create(glamor_egl->gbm, width, height,
+ GBM_FORMAT_ARGB8888,
#ifdef GLAMOR_HAS_GBM_LINEAR
- (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
- GBM_BO_USE_LINEAR : 0) |
+ (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
+ GBM_BO_USE_LINEAR : 0) |
#endif
- GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+ GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+ }
+
if (!bo) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to make %dx%dx%dbpp GBM bo\n",
@@ -325,15 +345,45 @@ 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 (modifier) {
+#ifdef GBM_BO_WITH_MODIFIERS
+ // XXX Check if multi planes is supported
+ int i, num_fds, fds[4];
+ uint32_t strides[4], offsets[4];
+ uint32_t format;
+
+ format = drm_format_for_depth(pixmap->drawable.bitsPerPixel,
+ pixmap->drawable.depth);
+ num_fds = gbm_bo_get_plane_count(bo);
+ for (i = 0; i < num_fds; i++) {
+ fds[i] = gbm_bo_get_fd(bo); // All planes use same fd
+ strides[i] = gbm_bo_get_stride_for_plane(bo, i);
+ offsets[i] = gbm_bo_get_offset(bo, i);
+ }
+ ret = glamor_egl_create_textured_pixmap_from_dmabuf(exported,
+ num_fds, fds,
+ width, height,
+ strides, offsets,
+ format, modifier);
+ if (!ret) {
+ for (i = 0; i < num_fds; i++)
+ close(fds[i]);
+ }
+#endif
+ } else {
+ ret = glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo);
+ }
+
+ gbm_bo_destroy(bo);
+
+ if (!ret) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
width, height, pixmap->drawable.bitsPerPixel);
screen->DestroyPixmap(exported);
- gbm_bo_destroy(bo);
return FALSE;
}
- gbm_bo_destroy(bo);
scratch_gc = GetScratchGC(pixmap->drawable.depth, screen);
ValidateGC(&pixmap->drawable, scratch_gc);
@@ -484,7 +534,7 @@ glamor_pixmap_from_fds(ScreenPtr screen,
pixmap = screen->CreatePixmap(screen, 0, 0, info->depth, 0);
if (glamor_egl->dmabuf_capable) {
- screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL); // XXX what is the stride used for?
+ screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
ret = glamor_egl_create_textured_pixmap_from_dmabuf(pixmap, num_fds, fds,
width, height,
strides, offsets,
@@ -608,6 +658,7 @@ _X_EXPORT void
glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
{
EGLImageKHR temp;
+ struct glamor_pixmap_dmabuf *tmp_dmabuf;
struct glamor_pixmap_private *front_priv =
glamor_get_pixmap_private(front);
struct glamor_pixmap_private *back_priv =
@@ -619,6 +670,10 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
back_priv->image = front_priv->image;
front_priv->image = temp;
+ tmp_dmabuf = back_priv->dmabuf;
+ back_priv->dmabuf = front_priv->dmabuf;
+ front_priv->dmabuf = tmp_dmabuf;
+
glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
}
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 78fe11103..e1d96a42e 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -277,14 +277,30 @@ xwl_glamor_create_pixmap(ScreenPtr screen,
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct gbm_bo *bo;
+ uint32_t format;
if (width > 0 && height > 0 && depth >= 15 &&
(hint == 0 ||
hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP ||
hint == CREATE_PIXMAP_USAGE_SHARED)) {
- bo = gbm_bo_create(xwl_screen->gbm, width, height,
- gbm_format_for_depth(depth),
- GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ format = gbm_format_for_depth(depth);
+
+#ifdef GBM_BO_WITH_MODIFIERS
+ if (xwl_screen->modifiers_capable) {
+ uint32_t num_modifiers;
+ uint64_t *modifiers = NULL;
+
+ glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
+ bo = gbm_bo_create_with_modifiers(xwl_screen->gbm, width, height,
+ format, modifiers, num_modifiers);
+ free(modifiers);
+ }
+ else
+#endif
+ {
+ bo = gbm_bo_create(xwl_screen->gbm, width, height, format,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ }
if (bo)
return xwl_glamor_create_pixmap_for_bo(screen, bo, depth, format);
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index ad1ab20a6..57aee61fd 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -497,6 +497,9 @@
/* Build glamor/gbm has linear support */
#undef GLAMOR_HAS_GBM_LINEAR
+/* GBM has modifiers support */
+#undef GBM_BO_WITH_MODIFIERS
+
/* Build glamor use new drmGetDeviceNameFromFD2 */
#undef GLAMOR_HAS_DRM_NAME_FROM_FD_2
--
2.13.0
More information about the xorg-devel
mailing list