diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2018-02-28 01:19:42 +0000 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2018-03-05 13:27:47 -0500 |
commit | 9d147305b4048dcec7ea4eda3eeea83f843f7788 (patch) | |
tree | 6634e9a46177b30c1f2e28337e15b34930196520 | |
parent | e375f29662ad7589cc6d8d179846da9b8a897122 (diff) |
modesetting: Check if buffer format is supported when flipping
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@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.c | 42 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.h | 2 | ||||
-rw-r--r-- | 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 6fa22da56..1f7a9fd0a 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; +} + #ifdef GBM_BO_WITH_MODIFIERS static uint32_t get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **modifiers, diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 75e4b8499..607fe8179 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -241,6 +241,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 |