summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2018-02-28 01:19:44 +0000
committerAdam Jackson <ajax@redhat.com>2018-03-05 13:27:55 -0500
commitcef12efc15ca1444d6d8cd839116b318a4668692 (patch)
tree29d81005b1360e9ab029f09822b222f51fca394b /hw
parentc8c276c9569b3ca1e695682a5443f1b615c606bd (diff)
glamor: Implement GetSupportedModifiers
Implement function added in DRI3 v1.1. A newest version of libepoxy (>= 1.4.4) is required as earlier versions use a problematic version of Khronos EXT_image_dma_buf_import_modifiers spec. v4: Only send scanout-supported modifiers if flipping is possible v5: Fix memory corruption in XWayland (uninitialized pointer) Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Keith Packard <keithp@keithp.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/kdrive/ephyr/meson.build1
-rw-r--r--hw/xfree86/common/xf86Mode.c1
-rw-r--r--hw/xfree86/drivers/modesetting/driver.c12
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.c38
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.h1
-rw-r--r--hw/xwayland/xwayland-glamor.c135
-rw-r--r--hw/xwayland/xwayland.h9
7 files changed, 175 insertions, 22 deletions
diff --git a/hw/kdrive/ephyr/meson.build b/hw/kdrive/ephyr/meson.build
index 31e167387..b48afd612 100644
--- a/hw/kdrive/ephyr/meson.build
+++ b/hw/kdrive/ephyr/meson.build
@@ -30,6 +30,7 @@ if build_glamor
xephyr_glamor += glamor
xephyr_glamor += glamor_egl_stubs
xephyr_dep += dependency('x11-xcb')
+ xephyr_dep += epoxy_dep
endif
if build_xv
diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c
index 40d09a9f4..484cde7ab 100644
--- a/hw/xfree86/common/xf86Mode.c
+++ b/hw/xfree86/common/xf86Mode.c
@@ -86,6 +86,7 @@
#include <X11/X.h>
#include "xf86Modes.h"
+#include "xf86Crtc.h"
#include "os.h"
#include "servermd.h"
#include "globals.h"
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 88a42257c..f20284bb0 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1601,15 +1601,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, NULL, 0);
-#ifdef GLAMOR_HAS_GBM
- if (ms->drmmode.glamor) {
- if (!glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to initialize glamor at ScreenInit() time.\n");
- return FALSE;
- }
+ if (drmmode_init(pScrn, &ms->drmmode) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to initialize glamor at ScreenInit() time.\n");
+ return FALSE;
}
-#endif
if (ms->drmmode.shadow_enable && !msShadowInit(pScreen)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "shadow fb init failed\n");
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 1f7a9fd0a..1027e637a 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -45,6 +45,7 @@
#include <xf86drm.h>
#include "xf86Crtc.h"
#include "drmmode_display.h"
+#include "present.h"
#include <cursorstr.h>
@@ -175,6 +176,24 @@ get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **modifiers,
*modifiers = ret;
return count_modifiers;
}
+
+static Bool
+get_drawable_modifiers(DrawablePtr draw, uint32_t format,
+ uint32_t *num_modifiers, uint64_t **modifiers)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
+ modesettingPtr ms = modesettingPTR(scrn);
+
+ if (!present_can_window_flip((WindowPtr) draw) ||
+ !ms->drmmode.pageflip || ms->drmmode.dri2_flipping || !scrn->vtSema) {
+ *num_modifiers = 0;
+ *modifiers = NULL;
+ return TRUE;
+ }
+
+ *num_modifiers = get_modifiers_set(scrn, format, modifiers, TRUE, FALSE);
+ return TRUE;
+}
#endif
static Bool
@@ -3121,6 +3140,25 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
return TRUE;
}
+Bool
+drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+#ifdef GLAMOR_HAS_GBM
+ ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+
+ if (drmmode->glamor) {
+ if (!glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) {
+ return FALSE;
+ }
+#ifdef GBM_BO_WITH_MODIFIERS
+ glamor_set_drawable_modifiers_func(pScreen, get_drawable_modifiers);
+#endif
+ }
+#endif
+
+ return TRUE;
+}
+
void
drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y)
{
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 607fe8179..ee59711cb 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -263,6 +263,7 @@ Bool drmmode_SharedPixmapFlip(PixmapPtr frontTarget, xf86CrtcPtr crtc,
void drmmode_DisableSharedPixmapFlipping(xf86CrtcPtr crtc, drmmode_ptr drmmode);
extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
+extern Bool drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw);
extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 774a18893..72e2625fb 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -407,19 +407,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
@@ -446,6 +433,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)
@@ -470,6 +505,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, 3);
+ zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
return TRUE;
}
@@ -678,12 +714,85 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
#endif
}
+_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->dmabuf_capable || !xwl_screen->dmabuf)
+ return FALSE;
+
+ if (xwl_screen->num_formats == 0) {
+ *num_formats = 0;
+ return TRUE;
+ }
+
+ *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->dmabuf_capable || !xwl_screen->dmabuf)
+ return FALSE;
+
+ if (xwl_screen->num_formats == 0) {
+ *num_modifiers = 0;
+ return TRUE;
+ }
+
+ 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) {
+ *num_modifiers = 0;
+ return FALSE;
+ }
+
+ *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,
+ .get_drawable_modifiers = glamor_get_drawable_modifiers,
};
Bool
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index be95bab55..36ebeaa83 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -49,6 +49,12 @@
#include "xdg-output-unstable-v1-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;
@@ -100,7 +106,8 @@ struct xwl_screen {
int drm_authenticated;
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;