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 <l...@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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel