[RFC xserver v4 12/14] glamor: Implement GetSupportedModifiers
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Mon Oct 16 05:02:59 UTC 2017
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
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
configure.ac | 4 +
glamor/glamor.c | 24 ++++
glamor/glamor.h | 23 ++++
glamor/glamor_egl.c | 92 +++++++++++++++
glamor/glamor_priv.h | 1 +
glamor/meson.build | 2 +-
hw/xfree86/common/xf86Mode.c | 1 +
hw/xfree86/drivers/modesetting/driver.c | 12 +-
hw/xfree86/drivers/modesetting/drmmode_display.c | 36 ++++++
hw/xfree86/drivers/modesetting/drmmode_display.h | 1 +
hw/xwayland/xwayland-glamor.c | 135 ++++++++++++++++++++---
hw/xwayland/xwayland.h | 9 +-
include/dix-config.h.in | 3 +
include/meson.build | 2 +
meson.build | 4 +-
present/present.c | 38 +++++++
present/present.h | 3 +
17 files changed, 366 insertions(+), 24 deletions(-)
diff --git a/configure.ac b/configure.ac
index 4fc4096a2..435daf71f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2087,6 +2087,10 @@ if test "x$GLAMOR" = xyes; then
AC_DEFINE(GLAMOR, 1, [Build glamor])
PKG_CHECK_MODULES([GLAMOR], [epoxy])
+ PKG_CHECK_EXISTS(epoxy >= 1.4.4,
+ [AC_DEFINE(GLAMOR_HAS_EGL_QUERY_DMABUF, 1, [Have GLAMOR_HAS_EGL_QUERY_DMABUF])],
+ [])
+
PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no])
if test "x$GBM" = xyes; then
AC_DEFINE(GLAMOR_HAS_GBM, 1,
diff --git a/glamor/glamor.c b/glamor/glamor.c
index def55bcb1..7c8a12e2f 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -806,6 +806,30 @@ glamor_supports_pixmap_import_export(ScreenPtr screen)
return glamor_priv->dri3_enabled;
}
+_X_EXPORT void
+glamor_set_drawable_modifiers_func(ScreenPtr screen,
+ GetDrawableModifiersFuncPtr func)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_priv->get_drawable_modifiers = func;
+}
+
+_X_EXPORT Bool
+glamor_get_drawable_modifiers(DrawablePtr draw, CARD32 format,
+ CARD32 *num_modifiers, uint64_t **modifiers)
+{
+ struct glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(draw->pScreen);
+
+ if (glamor_priv->get_drawable_modifiers) {
+ return glamor_priv->get_drawable_modifiers(draw, format,
+ num_modifiers, modifiers);
+ }
+ *num_modifiers = 0;
+ return TRUE;
+}
+
_X_EXPORT int
glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
uint32_t *strides, uint32_t *offsets,
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 8f8c31b45..5475aedbb 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -60,6 +60,11 @@ typedef enum glamor_pixmap_type {
GLAMOR_TEXTURE_ONLY,
} glamor_pixmap_type_t;
+typedef Bool (*GetDrawableModifiersFuncPtr) (DrawablePtr draw,
+ CARD32 format,
+ CARD32 *num_modifiers,
+ uint64_t **modifiers);
+
#define GLAMOR_EGL_EXTERNAL_BUFFER 3
#define GLAMOR_USE_EGL_SCREEN (1 << 0)
#define GLAMOR_NO_DRI3 (1 << 1)
@@ -272,6 +277,24 @@ 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);
+
+extern _X_EXPORT Bool glamor_get_drawable_modifiers(DrawablePtr draw,
+ CARD32 format,
+ CARD32 *num_modifiers,
+ uint64_t **modifiers);
+
+extern _X_EXPORT void glamor_set_drawable_modifiers_func(ScreenPtr screen,
+ GetDrawableModifiersFuncPtr func);
+
#ifdef GLAMOR_FOR_XORG
#define GLAMOR_EGL_MODULE_NAME "glamoregl"
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index cb1f03dc9..4e60569a1 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -488,6 +488,95 @@ glamor_pixmap_from_fds(ScreenPtr screen,
return pixmap;
}
+_X_EXPORT Bool
+glamor_get_formats(ScreenPtr screen,
+ CARD32 *num_formats, CARD32 **formats)
+{
+#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
+ struct glamor_egl_screen_private *glamor_egl;
+ EGLint num;
+
+ glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+
+ if (!glamor_egl->dmabuf_capable)
+ return FALSE;
+
+ if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, 0, NULL, &num)) {
+ *num_formats = 0;
+ return FALSE;
+ }
+
+ if (num == 0) {
+ *num_formats = 0;
+ return TRUE;
+ }
+
+ *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;
+#else
+ *num_formats = 0;
+ return TRUE;
+#endif
+}
+
+_X_EXPORT Bool
+glamor_get_modifiers(ScreenPtr screen, CARD32 format,
+ CARD32 *num_modifiers, uint64_t **modifiers)
+{
+#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
+ struct glamor_egl_screen_private *glamor_egl;
+ EGLint num;
+
+ glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+
+ if (!glamor_egl->dmabuf_capable)
+ return FALSE;
+
+ if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, 0, NULL,
+ NULL, &num)) {
+ *num_modifiers = 0;
+ return FALSE;
+ }
+
+ if (num == 0) {
+ *num_modifiers = 0;
+ return TRUE;
+ }
+
+ *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;
+#else
+ *num_modifiers = 0;
+ return TRUE;
+#endif
+}
+
static Bool
glamor_egl_destroy_pixmap(PixmapPtr pixmap)
{
@@ -609,6 +698,9 @@ static dri3_screen_info_rec glamor_dri3_info = {
.open_client = glamor_dri3_open_client,
.pixmap_from_fds = glamor_pixmap_from_fds,
.fds_from_pixmap = glamor_egl_fds_from_pixmap,
+ .get_formats = glamor_get_formats,
+ .get_modifiers = glamor_get_modifiers,
+ .get_drawable_modifiers = glamor_get_drawable_modifiers,
};
#endif /* DRI3 */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 7050df526..b80942800 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -283,6 +283,7 @@ typedef struct glamor_screen_private {
int radial_max_nstops;
struct glamor_saved_procs saved_procs;
+ GetDrawableModifiersFuncPtr get_drawable_modifiers;
int flags;
ScreenPtr screen;
int dri3_enabled;
diff --git a/glamor/meson.build b/glamor/meson.build
index 0b963275e..81087d7d3 100644
--- a/glamor/meson.build
+++ b/glamor/meson.build
@@ -43,7 +43,7 @@ glamor = static_library('glamor',
include_directories: inc,
dependencies: [
common_dep,
- dependency('epoxy'),
+ epoxy_dep,
],
)
diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c
index 3053e53f1..f11c545e2 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 b4f398934..fbdeb2f92 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1608,15 +1608,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 f6ec44f64..0e1a81561 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>
@@ -176,6 +177,24 @@ get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **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;
+}
+
+static Bool
drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name)
{
int i = 0;
@@ -2905,6 +2924,23 @@ 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;
+ }
+ glamor_set_drawable_modifiers_func(pScreen, get_drawable_modifiers);
+ }
+#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 3085b7c36..b3279835a 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -259,6 +259,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 857ed77a1..e3a7f6b5b 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -410,19 +410,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
@@ -449,6 +436,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)
@@ -473,6 +508,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;
}
@@ -683,12 +719,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 138f55c80..09792a0b1 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -48,6 +48,12 @@
#include "xwayland-keyboard-grab-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;
@@ -98,7 +104,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;
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 20f784920..c1a9eaa85 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -509,6 +509,9 @@
/* Glamor can retrieve supported DRM formats/modifiers */
#undef GLAMOR_HAS_DRM_MODIFIERS
+/* Glamor can use eglQueryDmaBuf* functions */
+#undef GLAMOR_HAS_EGL_QUERY_DMABUF
+
/* byte order */
#undef X_BYTE_ORDER
diff --git a/include/meson.build b/include/meson.build
index 610dfb653..23db6901a 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -80,6 +80,8 @@ conf_data.set('GLAMOR_HAS_DRM_NAME_FROM_FD_2',
libdrm_dep.found() and libdrm_dep.version().version_compare('>= 2.4.74'))
conf_data.set('GLAMOR_HAS_DRM_MODIFIERS',
libdrm_dep.found() and libdrm_dep.version().version_compare('>= 2.4.83'))
+conf_data.set('GLAMOR_HAS_EGL_QUERY_DMABUF',
+ epoxy_dep.found() and epoxy_dep.version().version_compare('>= 1.4.4'))
conf_data.set('GLXEXT', build_glx)
conf_data.set('GLAMOR', build_glamor)
conf_data.set('GLAMOR_HAS_GBM', gbm_dep.found())
diff --git a/meson.build b/meson.build
index 485bf7af8..c2c1461a9 100644
--- a/meson.build
+++ b/meson.build
@@ -256,9 +256,11 @@ else
build_glamor = get_option('glamor') == 'yes'
endif
-gbm_dep = dependency('', required:false)
+gbm_dep = dependency('', required: false)
+epoxy_dep = dependency('', required: false)
if build_glamor
gbm_dep = dependency('gbm', version: '>= 10.2', required: false)
+ epoxy_dep = dependency('epoxy', required: false)
endif
# XXX: Add more sha1 options, because Linux is about choice
diff --git a/present/present.c b/present/present.c
index 4d38d2d84..3efae348b 100644
--- a/present/present.c
+++ b/present/present.c
@@ -611,6 +611,44 @@ present_check_flip_window (WindowPtr window)
}
}
+Bool
+present_can_window_flip(WindowPtr window)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ PixmapPtr window_pixmap;
+ WindowPtr root = screen->root;
+ present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+
+ if (!screen_priv)
+ return FALSE;
+
+ if (!screen_priv->info)
+ return FALSE;
+
+ /* Check to see if the driver supports flips at all */
+ if (!screen_priv->info->flip)
+ return FALSE;
+
+ /* Make sure the window hasn't been redirected with Composite */
+ window_pixmap = screen->GetWindowPixmap(window);
+ if (window_pixmap != screen->GetScreenPixmap(screen) &&
+ window_pixmap != screen_priv->flip_pixmap &&
+ window_pixmap != present_flip_pending_pixmap(screen))
+ return FALSE;
+
+ /* Check for full-screen window */
+ if (!RegionEqual(&window->clipList, &root->winSize)) {
+ return FALSE;
+ }
+
+ /* Does the window match the pixmap exactly? */
+ if (window->drawable.x != 0 || window->drawable.y != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/*
* Called when the wait fence is triggered; just gets the current msc/ust and
* calls present_execute again. That will re-check the fence and pend the
diff --git a/present/present.h b/present/present.h
index 094946a7c..be41e8412 100644
--- a/present/present.h
+++ b/present/present.h
@@ -133,4 +133,7 @@ typedef void (*present_complete_notify_proc)(WindowPtr window,
extern _X_EXPORT void
present_register_complete_notify(present_complete_notify_proc proc);
+extern _X_EXPORT Bool
+present_can_window_flip(WindowPtr window);
+
#endif /* _PRESENT_H_ */
--
2.13.0
More information about the xorg-devel
mailing list