On 04/28/2015 06:31 AM, Kenneth Graunke wrote:
On Tuesday, April 21, 2015 05:58:44 PM Kenneth Graunke wrote:
Based on code by Keith Packard, Eric Anholt, and Jason Ekstrand.
v2:
- Fix double free and flip_count underrun (caught by Mario Kleiner).
- Don't leak flip_vblank_event on the error_out path (Mario).
- Use the updated ms_flush_drm_events API (Mario, Ken).
v3: Hack around DPMS shenanigans. If all monitors are DPMS off, then
there is no active framebuffer; attempting to pageflip will hit the
error_undo paths, causing us to drmModeRmFB with no framebuffer,
which confuses the kernel into doing full modesets and generally
breaks things. To avoid this, make ms_present_check_flip check that
some CRTCs are enabled and DPMS on. This is an ugly hack that would
get better with atomic modesetting, or some core Present work.
v4:
- Don't do pageflipping if CRTCs are rotated (caught by Jason Ekstrand).
- Make pageflipping optional (Option "PageFlip" in xorg.conf.d), but
enabled by default.
Signed-off-by: Kenneth Graunke <[email protected]>
Upon further testing, there are still nasty DPMS bugs affecting this
patch. We no longer crash the X server, but clients appear to
occasionally get stuck.
I guess we just need to bite the bullet and unflip on DPMS off.
Or switch to atomic modesetting...
I retested v4 + the attached patch with some small improvements applied.
The patch adds async page flip cap support, fixes that missing zero init
which Michel also reported and fixes some small inconsistency in the
ms_present_unflip routine.
Everything worked nicely, except for the not quite resolved DPMS off
bug. No more crashes, but page-flipped clients reliably hang after DPMS
off -> on. KDE with composition on and page flipping on (Setting
"Tearing prevention" set to "Full scene repaints") hangs after each
off->on cycle, my own fullscreen app hangs reliably as well if
page-flipped swaps are used.
Looking at stack traces it seems to me as if somehow after a dpms
off/on, a present_event_notify() somehow doesn't get delivered to the
server / gets lost somewhere, so clients like mine which wait for swap
completion or vblank events hang, and KDE hangs in Mesa when Mesa tries
to get a new backbuffer for rendering, runs out of buffers and then
waits infinitely for a present notify event from the server in order to
reuse one of its busy buffers.
-mario
>From 3d1e2383d7bcd35cf0838f32f26b82b8118a17d5 Mon Sep 17 00:00:00 2001
From: Mario Kleiner <[email protected]>
Date: Fri, 1 May 2015 09:01:41 +0200
Subject: [PATCH 8/8] modesetting: Add async flip support, fix small bugs.
Detect if kms driver is async flip capable.
Add missing zero init for number of crtc's on counting.
Fix small inconsistency.
Signed-off-by: Mario Kleiner <[email protected]>
---
hw/xfree86/drivers/modesetting/present.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 0ec0f40..693d4f3 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -504,7 +504,7 @@ ms_present_check_flip(RRCrtcPtr crtc,
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int num_crtcs_on;
+ int num_crtcs_on = 0;
int i;
if (!ms->drmmode.pageflip)
@@ -579,7 +579,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
Bool ret;
- if (!ms_present_check_flip(NULL, screen->root, pixmap, FALSE))
+ if (!ms_present_check_flip(NULL, screen->root, pixmap, TRUE))
return;
ret = ms_do_pageflip(screen, pixmap, -1, FALSE, event_id);
@@ -609,5 +609,14 @@ static present_screen_info_rec ms_present_screen_info = {
Bool
ms_present_screen_init(ScreenPtr screen)
{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ modesettingPtr ms = modesettingPTR(scrn);
+ uint64_t value;
+ int ret;
+
+ ret = drmGetCap(ms->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
+ if (ret == 0 && value == 1)
+ ms_present_screen_info.capabilities |= PresentCapabilityAsync;
+
return present_screen_init(screen, &ms_present_screen_info);
}
--
1.9.1
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel