[RFC xserver v6 10/14] modesetting: Check if buffer format is supported when flipping

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Fri Feb 16 04:15:43 UTC 2018


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.

v2: No longer need to implement 'check_flip'

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Reviewed-by: Daniel Stone <daniels 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         | 30 ++++++++++++++---
 3 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 7f0d1d2ea..106cf64f7 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 ce36e9092..52015c5df 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -234,6 +234,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..71ef2f7f1 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -214,7 +214,8 @@ static Bool
 ms_present_check_flip(RRCrtcPtr crtc,
                       WindowPtr window,
                       PixmapPtr pixmap,
-                      Bool sync_flip)
+                      Bool sync_flip,
+                      PresentFlipReason *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 = PRESENT_FLIP_REASON_BUFFER_FORMAT;
+            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))
@@ -280,7 +301,7 @@ ms_present_flip(RRCrtcPtr crtc,
     Bool ret;
     struct ms_present_vblank_event *event;
 
-    if (!ms_present_check_flip(crtc, screen->root, pixmap, sync_flip))
+    if (!ms_present_check_flip(crtc, screen->root, pixmap, sync_flip, NULL))
         return FALSE;
 
     event = calloc(1, sizeof(struct ms_present_vblank_event));
@@ -323,7 +344,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
     event->event_id = event_id;
     event->unflip = TRUE;
 
-    if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE) &&
+    if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE, NULL) &&
         ms_do_pageflip(screen, pixmap, event, -1, FALSE,
                        ms_present_flip_handler, ms_present_flip_abort)) {
         return;
@@ -368,7 +389,8 @@ static present_screen_info_rec ms_present_screen_info = {
 
     .capabilities = PresentCapabilityNone,
 #ifdef GLAMOR_HAS_GBM
-    .check_flip = ms_present_check_flip,
+    .check_flip = NULL,
+    .check_flip2 = ms_present_check_flip,
     .flip = ms_present_flip,
     .unflip = ms_present_unflip,
 #endif
-- 
2.14.3



More information about the xorg-devel mailing list