[RFC v2 04/13] glamor: Implement GetSupportedFormats and GetSupportedModifiers
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Fri Jul 14 04:47:51 UTC 2017
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
dri3/dri3.c | 92 ++++++++++++++++++++++++++++++++
dri3/dri3.h | 12 +++++
glamor/glamor.h | 10 ++++
glamor/glamor_egl.c | 69 ++++++++++++++++++++++++
hw/xwayland/xwayland-glamor.c | 119 +++++++++++++++++++++++++++++++++++++-----
hw/xwayland/xwayland.h | 9 +++-
6 files changed, 297 insertions(+), 14 deletions(-)
diff --git a/dri3/dri3.c b/dri3/dri3.c
index d042b8b7d..221200cf0 100644
--- a/dri3/dri3.c
+++ b/dri3/dri3.c
@@ -26,6 +26,8 @@
#include "dri3_priv.h"
+#include <drm_fourcc.h>
+
static int dri3_request;
DevPrivateKeyRec dri3_screen_private_key;
@@ -99,3 +101,93 @@ dri3_extension_init(void)
bail:
FatalError("Cannot initialize DRI3 extension");
}
+
+const struct drm_format_info *
+drm_format_get_info(uint32_t format)
+{
+ static const struct drm_format_info formats[] = {
+ { .format = DRM_FORMAT_C8, .depth = 8, .bpp = 8 },
+ { .format = DRM_FORMAT_RGB332, .depth = 8, .bpp = 8 },
+ { .format = DRM_FORMAT_BGR233, .depth = 8, .bpp = 8 },
+ { .format = DRM_FORMAT_XRGB4444, .depth = 12, .bpp = 16 },
+ { .format = DRM_FORMAT_XBGR4444, .depth = 12, .bpp = 16 },
+ { .format = DRM_FORMAT_RGBX4444, .depth = 12, .bpp = 16 },
+ { .format = DRM_FORMAT_BGRX4444, .depth = 12, .bpp = 16 },
+ { .format = DRM_FORMAT_ARGB4444, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_ABGR4444, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_RGBA4444, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_BGRA4444, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_XRGB1555, .depth = 15, .bpp = 16 },
+ { .format = DRM_FORMAT_XBGR1555, .depth = 15, .bpp = 16 },
+ { .format = DRM_FORMAT_RGBX5551, .depth = 15, .bpp = 16 },
+ { .format = DRM_FORMAT_BGRX5551, .depth = 15, .bpp = 16 },
+ { .format = DRM_FORMAT_ARGB1555, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_ABGR1555, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_RGBA5551, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_BGRA5551, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_RGB565, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_BGR565, .depth = 16, .bpp = 16 },
+ { .format = DRM_FORMAT_RGB888, .depth = 24, .bpp = 24 },
+ { .format = DRM_FORMAT_BGR888, .depth = 24, .bpp = 24 },
+ { .format = DRM_FORMAT_XRGB8888, .depth = 24, .bpp = 32 },
+ { .format = DRM_FORMAT_XBGR8888, .depth = 24, .bpp = 32 },
+ { .format = DRM_FORMAT_RGBX8888, .depth = 24, .bpp = 32 },
+ { .format = DRM_FORMAT_BGRX8888, .depth = 24, .bpp = 32 },
+ { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .bpp = 32 },
+ { .format = DRM_FORMAT_ARGB8888, .depth = 32, .bpp = 32 },
+ { .format = DRM_FORMAT_ABGR8888, .depth = 32, .bpp = 32 },
+ { .format = DRM_FORMAT_RGBA8888, .depth = 32, .bpp = 32 },
+ { .format = DRM_FORMAT_BGRA8888, .depth = 32, .bpp = 32 },
+ };
+
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); ++i) {
+ if (formats[i].format == format)
+ return &formats[i];
+ }
+
+ return NULL;
+}
+
+uint32_t
+drm_format_for_depth(uint32_t bpp, uint32_t depth)
+{
+ uint32_t fmt;
+
+ switch (bpp) {
+ case 8:
+ fmt = DRM_FORMAT_C8;
+ break;
+ case 16:
+ if (depth == 15)
+ fmt = DRM_FORMAT_XRGB1555;
+ else
+ fmt = DRM_FORMAT_RGB565;
+ break;
+ case 24:
+ fmt = DRM_FORMAT_RGB888;
+ break;
+ case 32:
+ if (depth == 24)
+ fmt = DRM_FORMAT_XRGB8888;
+ else if (depth == 30)
+ fmt = DRM_FORMAT_XRGB2101010;
+ else
+ fmt = DRM_FORMAT_ARGB8888;
+ break;
+ default:
+ // XXX error
+ fmt = DRM_FORMAT_XRGB8888;
+ break;
+ }
+
+ return fmt;
+}
diff --git a/dri3/dri3.h b/dri3/dri3.h
index 67589c70c..93fdeacf5 100644
--- a/dri3/dri3.h
+++ b/dri3/dri3.h
@@ -103,6 +103,18 @@ dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info);
extern _X_EXPORT int
dri3_send_open_reply(ClientPtr client, int fd);
+struct drm_format_info {
+ uint32_t format;
+ uint32_t depth;
+ uint32_t bpp;
+};
+
+extern _X_EXPORT const struct drm_format_info *
+drm_format_get_info(uint32_t format);
+
+extern _X_EXPORT uint32_t
+drm_format_for_depth(uint32_t bpp, uint32_t depth);
+
#endif
#endif /* _DRI3_H_ */
diff --git a/glamor/glamor.h b/glamor/glamor.h
index f16f79c97..044480597 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -318,6 +318,16 @@ extern _X_EXPORT Bool glamor_back_pixmap_from_fd(PixmapPtr pixmap,
CARD16 stride,
CARD8 depth,
CARD8 bpp);
+
+extern _X_EXPORT Bool glamor_get_formats(ScreenPtr screen,
+ CARD32 *num_formats,
+ CARD32 **formats);
+
+extern _X_EXPORT Bool glamor_get_modifiers(ScreenPtr screen,
+ CARD32 format,
+ CARD32 *num_modifiers,
+ uint64_t **modifiers);
+
#ifdef GLAMOR_FOR_XORG
#define GLAMOR_EGL_MODULE_NAME "glamoregl"
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index d88d7cbcf..8bd050308 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -503,6 +503,75 @@ glamor_pixmap_from_fds(ScreenPtr screen,
return pixmap;
}
+_X_EXPORT Bool
+glamor_get_formats(ScreenPtr screen,
+ CARD32 *num_formats, CARD32 **formats)
+{
+ struct glamor_egl_screen_private *glamor_egl;
+ EGLint num;
+
+ glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+
+ if (!glamor_egl->modifiers_capable)
+ return FALSE;
+
+ if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, 0, NULL, &num)) {
+ *num_formats = 0;
+ return FALSE;
+ }
+
+ *formats = calloc(num, sizeof(CARD32));
+ if (*formats == NULL) {
+ *num_formats = 0;
+ return FALSE;
+ }
+
+ if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, num,
+ (EGLint *) *formats, &num)) {
+ *num_formats = 0;
+ free(*formats);
+ return FALSE;
+ }
+
+ *num_formats = num;
+ return TRUE;
+}
+
+_X_EXPORT Bool
+glamor_get_modifiers(ScreenPtr screen, CARD32 format,
+ CARD32 *num_modifiers, uint64_t **modifiers)
+{
+ struct glamor_egl_screen_private *glamor_egl;
+ EGLint num;
+
+ glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+
+ if (!glamor_egl->modifiers_capable)
+ return FALSE;
+
+ if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, 0, NULL,
+ NULL, &num)) {
+ *num_modifiers = 0;
+ return FALSE;
+ }
+
+ *modifiers = calloc(num, sizeof(uint64_t));
+ if (*modifiers == NULL) {
+ *num_modifiers = 0;
+ return FALSE;
+ }
+
+ if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, num,
+ (EGLuint64KHR *) *modifiers, NULL, &num)) {
+ *num_modifiers = 0;
+ free(*modifiers);
+ return FALSE;
+ }
+
+ *num_modifiers = num;
+ return TRUE;
+}
+
static Bool
glamor_egl_destroy_pixmap(PixmapPtr pixmap)
{
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index dbd119beb..78fe11103 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -462,19 +462,6 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
static void
xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
{
- struct xwl_screen *xwl_screen = data;
-
- switch (format) {
- case WL_DRM_FORMAT_ARGB8888:
- xwl_screen->formats |= XWL_FORMAT_ARGB8888;
- break;
- case WL_DRM_FORMAT_XRGB8888:
- xwl_screen->formats |= XWL_FORMAT_XRGB8888;
- break;
- case WL_DRM_FORMAT_RGB565:
- xwl_screen->formats |= XWL_FORMAT_RGB565;
- break;
- }
}
static void
@@ -501,6 +488,54 @@ static const struct wl_drm_listener xwl_drm_listener = {
xwl_drm_handle_capabilities
};
+static void
+xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+ uint32_t format)
+{
+}
+
+static void
+xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+ uint32_t format, uint32_t modifier_hi,
+ uint32_t modifier_lo)
+{
+ struct xwl_screen *xwl_screen = data;
+ struct xwl_format *xwl_format = NULL;
+ int i;
+
+ for (i = 0; i < xwl_screen->num_formats; i++) {
+ if (xwl_screen->formats[i].format == format) {
+ xwl_format = &xwl_screen->formats[i];
+ break;
+ }
+ }
+
+ if (xwl_format == NULL) {
+ xwl_screen->num_formats++;
+ xwl_screen->formats = realloc(xwl_screen->formats,
+ xwl_screen->num_formats * sizeof(*xwl_format));
+ if (!xwl_screen->formats)
+ return;
+ xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
+ xwl_format->format = format;
+ xwl_format->num_modifiers = 0;
+ xwl_format->modifiers = NULL;
+ }
+
+ xwl_format->num_modifiers++;
+ xwl_format->modifiers = realloc(xwl_format->modifiers,
+ xwl_format->num_modifiers * sizeof(uint64_t));
+ if (!xwl_format->modifiers)
+ return;
+ xwl_format->modifiers[xwl_format->num_modifiers - 1] = (uint64_t) modifier_lo;
+ xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
+}
+
+static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
+ .format = xwl_dmabuf_handle_format,
+ .modifier = xwl_dmabuf_handle_modifier
+};
+
Bool
xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version)
@@ -525,6 +560,7 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
xwl_screen->dmabuf =
wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 2);
+ zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
return TRUE;
}
@@ -711,12 +747,69 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
return xwl_pixmap->num_fds;
}
+_X_EXPORT Bool
+glamor_get_formats(ScreenPtr screen,
+ CARD32 *num_formats, CARD32 **formats)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ int i;
+
+ if (!xwl_screen->modifiers_capable || !xwl_screen->dmabuf)
+ return FALSE;
+
+ *formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
+ if (*formats == NULL) {
+ *num_formats = 0;
+ return FALSE;
+ }
+
+ for (i = 0; i < xwl_screen->num_formats; i++)
+ (*formats)[i] = xwl_screen->formats[i].format;
+ *num_formats = xwl_screen->num_formats;
+
+ return TRUE;
+}
+
+_X_EXPORT Bool
+glamor_get_modifiers(ScreenPtr screen, CARD32 format,
+ CARD32 *num_modifiers, uint64_t **modifiers)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ struct xwl_format *xwl_format = NULL;
+ int i;
+
+ if (!xwl_screen->modifiers_capable || !xwl_screen->dmabuf)
+ return FALSE;
+
+ for (i = 0; i < xwl_screen->num_formats; i++) {
+ if (xwl_screen->formats[i].format == format) {
+ xwl_format = &xwl_screen->formats[i];
+ break;
+ }
+ }
+
+ *modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
+ if (*modifiers == NULL) {
+ *num_modifiers = 0;
+ return FALSE;
+ }
+
+ for (i = 0; i < xwl_format->num_modifiers; i++)
+ (*modifiers)[i] = xwl_format->modifiers[i];
+ *num_modifiers = xwl_format->num_modifiers;
+
+ return TRUE;
+}
+
+
static dri3_screen_info_rec xwl_dri3_info = {
.version = 2,
.open = NULL,
.pixmap_from_fds = glamor_pixmap_from_fds,
.fds_from_pixmap = glamor_fds_from_pixmap,
.open_client = xwl_dri3_open_client,
+ .get_formats = glamor_get_formats,
+ .get_modifiers = glamor_get_modifiers,
};
Bool
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 784b14e8e..25fac5d6f 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -47,6 +47,12 @@
#include "tablet-unstable-v2-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
+struct xwl_format {
+ uint32_t format;
+ int num_modifiers;
+ uint64_t *modifiers;
+};
+
struct xwl_screen {
int width;
int height;
@@ -96,7 +102,8 @@ struct xwl_screen {
int fd_render_node;
struct wl_drm *drm;
struct zwp_linux_dmabuf_v1 *dmabuf;
- uint32_t formats;
+ uint32_t num_formats;
+ struct xwl_format *formats;
uint32_t capabilities;
void *egl_display, *egl_context;
struct gbm_device *gbm;
--
2.13.0
More information about the xorg-devel
mailing list