mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
Handle multiple "pending" Present flips
The xserver Present code can submit a flip in response to notifying it that a vblank event arrived. This can happen before the completion event of the previous flip is processed. In that case, we were clearing the drmmode_crtc->flip_pending field prematurely. Prevent this by only clearing drmmode_crtc->flip_pending when it matches the framebuffer being scanned out since the flip whose completion event we're processing. Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Michel Dänzer
parent
e6d7dc2070
commit
7c10ee9c88
@@ -2403,6 +2403,7 @@ drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data)
|
||||
if (!flipdata->fe_crtc)
|
||||
flipdata->fe_crtc = crtc;
|
||||
flipdata->abort(flipdata->fe_crtc, flipdata->event_data);
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL);
|
||||
free(flipdata);
|
||||
}
|
||||
|
||||
@@ -2424,6 +2425,13 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even
|
||||
flipdata->fe_usec = usec;
|
||||
}
|
||||
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb,
|
||||
flipdata->fb);
|
||||
if (drmmode_crtc->flip_pending == flipdata->fb) {
|
||||
drmmode_fb_reference(pRADEONEnt->fd,
|
||||
&drmmode_crtc->flip_pending, NULL);
|
||||
}
|
||||
|
||||
if (--flipdata->flip_count == 0) {
|
||||
/* Deliver MSC & UST from reference/current CRTC to flip event
|
||||
* handler
|
||||
@@ -2434,13 +2442,9 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even
|
||||
else
|
||||
flipdata->handler(crtc, frame, usec, flipdata->event_data);
|
||||
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL);
|
||||
free(flipdata);
|
||||
}
|
||||
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb,
|
||||
drmmode_crtc->flip_pending);
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -2961,7 +2965,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0;
|
||||
drmmode_flipdata_ptr flipdata;
|
||||
uintptr_t drm_queue_seq = 0;
|
||||
struct drmmode_fb *fb;
|
||||
|
||||
flipdata = calloc(1, sizeof(drmmode_flipdata_rec));
|
||||
if (!flipdata) {
|
||||
@@ -2970,8 +2973,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
goto error;
|
||||
}
|
||||
|
||||
fb = radeon_pixmap_get_fb(new_front);
|
||||
if (!fb) {
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb,
|
||||
radeon_pixmap_get_fb(new_front));
|
||||
if (!flipdata->fb) {
|
||||
ErrorF("Failed to get FB for flip\n");
|
||||
goto error;
|
||||
}
|
||||
@@ -3013,7 +3017,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
if (crtc == ref_crtc) {
|
||||
if (drmmode_page_flip_target_absolute(pRADEONEnt,
|
||||
drmmode_crtc,
|
||||
fb->handle,
|
||||
flipdata->fb->handle,
|
||||
flip_flags,
|
||||
drm_queue_seq,
|
||||
target_msc) != 0)
|
||||
@@ -3021,14 +3025,14 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
|
||||
} else {
|
||||
if (drmmode_page_flip_target_relative(pRADEONEnt,
|
||||
drmmode_crtc,
|
||||
fb->handle,
|
||||
flipdata->fb->handle,
|
||||
flip_flags,
|
||||
drm_queue_seq, 0) != 0)
|
||||
goto flip_error;
|
||||
}
|
||||
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
|
||||
fb);
|
||||
flipdata->fb);
|
||||
drm_queue_seq = 0;
|
||||
}
|
||||
|
||||
@@ -3046,6 +3050,7 @@ error:
|
||||
drmmode_flip_abort(crtc, flipdata);
|
||||
else {
|
||||
abort(NULL, data);
|
||||
drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL);
|
||||
free(flipdata);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,9 @@ typedef struct {
|
||||
} drmmode_rec, *drmmode_ptr;
|
||||
|
||||
typedef struct {
|
||||
int flip_count;
|
||||
struct drmmode_fb *fb;
|
||||
void *event_data;
|
||||
int flip_count;
|
||||
unsigned int fe_frame;
|
||||
uint64_t fe_usec;
|
||||
xf86CrtcPtr fe_crtc;
|
||||
|
||||
Reference in New Issue
Block a user