[RFC xserver v5 10/14] modesetting: Check if buffer format is supported when flipping
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Mon Nov 6 21:30:48 UTC 2017
Add support for 'check_flip2' so that the present core can know
why it is impossible to flip in that scenario. The core can then
let know the client that the buffer format/modifier is suboptimal.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
hw/xfree86/drivers/modesetting/drmmode_display.c | 42 ++++++++++++++++++++++++
hw/xfree86/drivers/modesetting/drmmode_display.h | 2 ++
hw/xfree86/drivers/modesetting/present.c | 39 +++++++++++++++++++---
3 files changed, 79 insertions(+), 4 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 6e48f23a1..8c65bc809 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -73,6 +73,48 @@ modifiers_ptr(struct drm_format_modifier_blob *blob)
#endif
+Bool
+drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format, uint64_t modifier)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c, i, j;
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ Bool found = FALSE;
+
+ if (!crtc->enabled)
+ continue;
+
+ for (i = 0; i < drmmode_crtc->num_formats; i++) {
+ drmmode_format_ptr iter = &drmmode_crtc->formats[i];
+
+ if (iter->format != format)
+ continue;
+
+ if (modifier == 0) {
+ found = TRUE;
+ break;
+ }
+
+ for (j = 0; j < iter->num_modifiers; j++) {
+ if (iter->modifiers[j] == modifier) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ break;
+ }
+
+ if (!found)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static uint32_t
get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **modifiers,
Bool enabled_crtc_only, Bool exclude_multiplane)
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 18e874ca9..3085b7c36 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -237,6 +237,8 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
#define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
+Bool drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format,
+ uint64_t modifier);
int drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
uint32_t *fb_id);
int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo);
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 4a01d19ea..c0425c09a 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -211,10 +211,11 @@ ms_present_flip_abort(modesettingPtr ms, void *data)
* Test to see if page flipping is possible on the target crtc
*/
static Bool
-ms_present_check_flip(RRCrtcPtr crtc,
- WindowPtr window,
- PixmapPtr pixmap,
- Bool sync_flip)
+ms_present_check_flip2(RRCrtcPtr crtc,
+ WindowPtr window,
+ PixmapPtr pixmap,
+ Bool sync_flip,
+ int *reason)
{
ScreenPtr screen = window->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -222,6 +223,9 @@ ms_present_check_flip(RRCrtcPtr crtc,
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int num_crtcs_on = 0;
int i;
+#ifdef GLAMOR_HAS_DRM_MODIFIERS
+ struct gbm_bo *gbm;
+#endif
if (!ms->drmmode.pageflip)
return FALSE;
@@ -252,6 +256,23 @@ ms_present_check_flip(RRCrtcPtr crtc,
pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
return FALSE;
+#ifdef GLAMOR_HAS_DRM_MODIFIERS
+ /* Check if buffer format/modifier is supported by all active CRTCs */
+ gbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
+ if (gbm) {
+ uint32_t format;
+ uint64_t modifier;
+
+ format = gbm_bo_get_format(gbm);
+ modifier = gbm_bo_get_modifier(gbm);
+ if (!drmmode_is_format_supported(scrn, format, modifier)) {
+ if (reason)
+ *reason = PresentFlipReasonBufferFormat;
+ return FALSE;
+ }
+ }
+#endif
+
/* Make sure there's a bo we can get to */
/* XXX: actually do this. also...is it sufficient?
* if (!glamor_get_pixmap_private(pixmap))
@@ -261,6 +282,15 @@ ms_present_check_flip(RRCrtcPtr crtc,
return TRUE;
}
+static Bool
+ms_present_check_flip(RRCrtcPtr crtc,
+ WindowPtr window,
+ PixmapPtr pixmap,
+ Bool sync_flip)
+{
+ return ms_present_check_flip2(crtc, window, pixmap, sync_flip, NULL);
+}
+
/*
* Queue a flip on 'crtc' to 'pixmap' at 'target_msc'. If 'sync_flip' is true,
* then wait for vblank. Otherwise, flip immediately
@@ -369,6 +399,7 @@ static present_screen_info_rec ms_present_screen_info = {
.capabilities = PresentCapabilityNone,
#ifdef GLAMOR_HAS_GBM
.check_flip = ms_present_check_flip,
+ .check_flip2 = ms_present_check_flip2,
.flip = ms_present_flip,
.unflip = ms_present_unflip,
#endif
--
2.13.0
More information about the xorg-devel
mailing list