modesetting: add DRI2 page flip support
Signed-off-by: Qiang Yu <Qiang.Yu@amd.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
4a839da627
commit
f06aef31c0
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
enum ms_dri2_frame_event_type {
|
enum ms_dri2_frame_event_type {
|
||||||
MS_DRI2_QUEUE_SWAP,
|
MS_DRI2_QUEUE_SWAP,
|
||||||
|
MS_DRI2_QUEUE_FLIP,
|
||||||
MS_DRI2_WAIT_MSC,
|
MS_DRI2_WAIT_MSC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -399,6 +400,197 @@ ms_dri2_blit_swap(DrawablePtr drawable,
|
||||||
ms_dri2_copy_region(drawable, ®ion, dst, src);
|
ms_dri2_copy_region(drawable, ®ion, dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ms_dri2_vblank_event {
|
||||||
|
XID drawable_id;
|
||||||
|
ClientPtr client;
|
||||||
|
DRI2SwapEventPtr event_complete;
|
||||||
|
void *event_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ms_dri2_flip_abort(modesettingPtr ms, void *data)
|
||||||
|
{
|
||||||
|
struct ms_present_vblank_event *event = data;
|
||||||
|
|
||||||
|
ms->drmmode.dri2_flipping = FALSE;
|
||||||
|
free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ms_dri2_flip_handler(modesettingPtr ms, uint64_t msc,
|
||||||
|
uint64_t ust, void *data)
|
||||||
|
{
|
||||||
|
struct ms_dri2_vblank_event *event = data;
|
||||||
|
uint32_t frame = msc;
|
||||||
|
uint32_t tv_sec = ust / 1000000;
|
||||||
|
uint32_t tv_usec = ust % 1000000;
|
||||||
|
DrawablePtr drawable;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = dixLookupDrawable(&drawable, event->drawable_id, serverClient,
|
||||||
|
M_ANY, DixWriteAccess);
|
||||||
|
if (status == Success)
|
||||||
|
DRI2SwapComplete(event->client, drawable, frame, tv_sec, tv_usec,
|
||||||
|
DRI2_FLIP_COMPLETE, event->event_complete,
|
||||||
|
event->event_data);
|
||||||
|
|
||||||
|
ms->drmmode.dri2_flipping = FALSE;
|
||||||
|
free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
ms_dri2_schedule_flip(ms_dri2_frame_event_ptr info)
|
||||||
|
{
|
||||||
|
DrawablePtr draw = info->drawable;
|
||||||
|
ScreenPtr screen = draw->pScreen;
|
||||||
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
|
ms_dri2_buffer_private_ptr back_priv = info->back->driverPrivate;
|
||||||
|
struct ms_dri2_vblank_event *event;
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = info->crtc->driver_private;
|
||||||
|
|
||||||
|
event = calloc(1, sizeof(struct ms_dri2_vblank_event));
|
||||||
|
if (!event)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
event->drawable_id = draw->id;
|
||||||
|
event->client = info->client;
|
||||||
|
event->event_complete = info->event_complete;
|
||||||
|
event->event_data = info->event_data;
|
||||||
|
|
||||||
|
if (ms_do_pageflip(screen, back_priv->pixmap, event,
|
||||||
|
drmmode_crtc->vblank_pipe, FALSE,
|
||||||
|
ms_dri2_flip_handler,
|
||||||
|
ms_dri2_flip_abort)) {
|
||||||
|
ms->drmmode.dri2_flipping = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
update_front(DrawablePtr draw, DRI2BufferPtr front)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = draw->pScreen;
|
||||||
|
PixmapPtr pixmap = get_drawable_pixmap(draw);
|
||||||
|
ms_dri2_buffer_private_ptr priv = front->driverPrivate;
|
||||||
|
CARD32 size;
|
||||||
|
CARD16 pitch;
|
||||||
|
|
||||||
|
front->name = glamor_name_from_pixmap(pixmap, &pitch, &size);
|
||||||
|
if (front->name < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
(*screen->DestroyPixmap) (priv->pixmap);
|
||||||
|
front->pitch = pixmap->devKind;
|
||||||
|
front->cpp = pixmap->drawable.bitsPerPixel / 8;
|
||||||
|
priv->pixmap = pixmap;
|
||||||
|
pixmap->refcnt++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
can_exchange(ScrnInfoPtr scrn, DrawablePtr draw,
|
||||||
|
DRI2BufferPtr front, DRI2BufferPtr back)
|
||||||
|
{
|
||||||
|
ms_dri2_buffer_private_ptr front_priv = front->driverPrivate;
|
||||||
|
ms_dri2_buffer_private_ptr back_priv = back->driverPrivate;
|
||||||
|
PixmapPtr front_pixmap;
|
||||||
|
PixmapPtr back_pixmap = back_priv->pixmap;
|
||||||
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||||
|
int num_crtcs_on = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < config->num_crtc; i++) {
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = config->crtc[i]->driver_private;
|
||||||
|
|
||||||
|
/* Don't do pageflipping if CRTCs are rotated. */
|
||||||
|
#ifdef GLAMOR_HAS_GBM
|
||||||
|
if (drmmode_crtc->rotate_bo.gbm)
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ms_crtc_on(config->crtc[i]))
|
||||||
|
num_crtcs_on++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can't do pageflipping if all the CRTCs are off. */
|
||||||
|
if (num_crtcs_on == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!update_front(draw, front))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
front_pixmap = front_priv->pixmap;
|
||||||
|
|
||||||
|
if (front_pixmap->drawable.width != back_pixmap->drawable.width)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (front_pixmap->drawable.height != back_pixmap->drawable.height)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (front_pixmap->drawable.bitsPerPixel !=
|
||||||
|
back_pixmap->drawable.bitsPerPixel)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (front_pixmap->devKind != back_pixmap->devKind)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
can_flip(ScrnInfoPtr scrn, DrawablePtr draw,
|
||||||
|
DRI2BufferPtr front, DRI2BufferPtr back)
|
||||||
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
|
|
||||||
|
return draw->type == DRAWABLE_WINDOW &&
|
||||||
|
ms->drmmode.pageflip &&
|
||||||
|
!ms->drmmode.present_flipping &&
|
||||||
|
scrn->vtSema &&
|
||||||
|
DRI2CanFlip(draw) && can_exchange(scrn, draw, front, back);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ms_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front,
|
||||||
|
DRI2BufferPtr back)
|
||||||
|
{
|
||||||
|
ms_dri2_buffer_private_ptr front_priv = front->driverPrivate;
|
||||||
|
ms_dri2_buffer_private_ptr back_priv = back->driverPrivate;
|
||||||
|
ScreenPtr screen = draw->pScreen;
|
||||||
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
|
msPixmapPrivPtr front_pix = msGetPixmapPriv(&ms->drmmode, front_priv->pixmap);
|
||||||
|
msPixmapPrivPtr back_pix = msGetPixmapPriv(&ms->drmmode, back_priv->pixmap);
|
||||||
|
msPixmapPrivRec tmp_pix;
|
||||||
|
RegionRec region;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
/* Swap BO names so DRI works */
|
||||||
|
tmp = front->name;
|
||||||
|
front->name = back->name;
|
||||||
|
back->name = tmp;
|
||||||
|
|
||||||
|
/* Swap pixmap privates */
|
||||||
|
tmp_pix = *front_pix;
|
||||||
|
*front_pix = *back_pix;
|
||||||
|
*back_pix = tmp_pix;
|
||||||
|
|
||||||
|
glamor_egl_exchange_buffers(front_priv->pixmap, back_priv->pixmap);
|
||||||
|
|
||||||
|
/* Post damage on the front buffer so that listeners, such
|
||||||
|
* as DisplayLink know take a copy and shove it over the USB.
|
||||||
|
*/
|
||||||
|
region.extents.x1 = region.extents.y1 = 0;
|
||||||
|
region.extents.x2 = front_priv->pixmap->drawable.width;
|
||||||
|
region.extents.y2 = front_priv->pixmap->drawable.height;
|
||||||
|
region.data = NULL;
|
||||||
|
DamageRegionAppend(&front_priv->pixmap->drawable, ®ion);
|
||||||
|
DamageRegionProcessPending(&front_priv->pixmap->drawable);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ms_dri2_frame_event_handler(uint64_t msc,
|
ms_dri2_frame_event_handler(uint64_t msc,
|
||||||
uint64_t usec,
|
uint64_t usec,
|
||||||
|
@ -417,6 +609,13 @@ ms_dri2_frame_event_handler(uint64_t msc,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (frame_info->type) {
|
switch (frame_info->type) {
|
||||||
|
case MS_DRI2_QUEUE_FLIP:
|
||||||
|
if (can_flip(scrn, drawable, frame_info->front, frame_info->back) &&
|
||||||
|
ms_dri2_schedule_flip(frame_info)) {
|
||||||
|
ms_dri2_exchange_buffers(drawable, frame_info->front, frame_info->back);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* else fall through to blit */
|
||||||
case MS_DRI2_QUEUE_SWAP:
|
case MS_DRI2_QUEUE_SWAP:
|
||||||
ms_dri2_blit_swap(drawable, frame_info->front, frame_info->back);
|
ms_dri2_blit_swap(drawable, frame_info->front, frame_info->back);
|
||||||
DRI2SwapComplete(frame_info->client, drawable, msc, tv_sec, tv_usec,
|
DRI2SwapComplete(frame_info->client, drawable, msc, tv_sec, tv_usec,
|
||||||
|
@ -607,7 +806,7 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
|
||||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
modesettingPtr ms = modesettingPTR(scrn);
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
drmVBlank vbl;
|
drmVBlank vbl;
|
||||||
int ret;
|
int ret, flip = 0;
|
||||||
xf86CrtcPtr crtc = ms_dri2_crtc_covering_drawable(draw);
|
xf86CrtcPtr crtc = ms_dri2_crtc_covering_drawable(draw);
|
||||||
drmmode_crtc_private_ptr drmmode_crtc;
|
drmmode_crtc_private_ptr drmmode_crtc;
|
||||||
ms_dri2_frame_event_ptr frame_info = NULL;
|
ms_dri2_frame_event_ptr frame_info = NULL;
|
||||||
|
@ -645,20 +844,36 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
|
||||||
|
|
||||||
ret = ms_get_crtc_ust_msc(crtc, ¤t_ust, ¤t_msc);
|
ret = ms_get_crtc_ust_msc(crtc, ¤t_ust, ¤t_msc);
|
||||||
|
|
||||||
|
/* Flips need to be submitted one frame before */
|
||||||
|
if (can_flip(scrn, draw, front, back)) {
|
||||||
|
frame_info->type = MS_DRI2_QUEUE_FLIP;
|
||||||
|
flip = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Correct target_msc by 'flip' if frame_info->type == MS_DRI2_QUEUE_FLIP.
|
||||||
|
* Do it early, so handling of different timing constraints
|
||||||
|
* for divisor, remainder and msc vs. target_msc works.
|
||||||
|
*/
|
||||||
|
if (*target_msc > 0)
|
||||||
|
*target_msc -= flip;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If divisor is zero, or current_msc is smaller than target_msc
|
* If divisor is zero, or current_msc is smaller than target_msc
|
||||||
* we just need to make sure target_msc passes before initiating
|
* we just need to make sure target_msc passes before initiating
|
||||||
* the swap.
|
* the swap.
|
||||||
*/
|
*/
|
||||||
if (divisor == 0 || current_msc < *target_msc) {
|
if (divisor == 0 || current_msc < *target_msc) {
|
||||||
/* We need to use DRM_VBLANK_NEXTONMISS to avoid unreliable
|
|
||||||
* timestamping later on.
|
|
||||||
*/
|
|
||||||
vbl.request.type = (DRM_VBLANK_ABSOLUTE |
|
vbl.request.type = (DRM_VBLANK_ABSOLUTE |
|
||||||
DRM_VBLANK_NEXTONMISS |
|
|
||||||
DRM_VBLANK_EVENT |
|
DRM_VBLANK_EVENT |
|
||||||
drmmode_crtc->vblank_pipe);
|
drmmode_crtc->vblank_pipe);
|
||||||
|
|
||||||
|
/* If non-pageflipping, but blitting/exchanging, we need to use
|
||||||
|
* DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later
|
||||||
|
* on.
|
||||||
|
*/
|
||||||
|
if (flip == 0)
|
||||||
|
vbl.request.type |= DRM_VBLANK_NEXTONMISS;
|
||||||
|
|
||||||
/* If target_msc already reached or passed, set it to
|
/* If target_msc already reached or passed, set it to
|
||||||
* current_msc to ensure we return a reasonable value back
|
* current_msc to ensure we return a reasonable value back
|
||||||
* to the caller. This makes swap_interval logic more robust.
|
* to the caller. This makes swap_interval logic more robust.
|
||||||
|
@ -683,7 +898,8 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
|
||||||
goto blit_fallback;
|
goto blit_fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
*target_msc = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
|
*target_msc = ms_kernel_msc_to_crtc_msc(crtc,
|
||||||
|
vbl.reply.sequence + flip);
|
||||||
frame_info->frame = *target_msc;
|
frame_info->frame = *target_msc;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -695,9 +911,10 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
|
||||||
* equation.
|
* equation.
|
||||||
*/
|
*/
|
||||||
vbl.request.type = (DRM_VBLANK_ABSOLUTE |
|
vbl.request.type = (DRM_VBLANK_ABSOLUTE |
|
||||||
DRM_VBLANK_NEXTONMISS |
|
|
||||||
DRM_VBLANK_EVENT |
|
DRM_VBLANK_EVENT |
|
||||||
drmmode_crtc->vblank_pipe);
|
drmmode_crtc->vblank_pipe);
|
||||||
|
if (flip == 0)
|
||||||
|
vbl.request.type |= DRM_VBLANK_NEXTONMISS;
|
||||||
|
|
||||||
request_msc = current_msc - (current_msc % divisor) +
|
request_msc = current_msc - (current_msc % divisor) +
|
||||||
remainder;
|
remainder;
|
||||||
|
@ -721,7 +938,8 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
|
||||||
if (!seq)
|
if (!seq)
|
||||||
goto blit_fallback;
|
goto blit_fallback;
|
||||||
|
|
||||||
vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, request_msc);
|
/* Account for 1 frame extra pageflip delay if flip > 0 */
|
||||||
|
vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, request_msc) - flip;
|
||||||
vbl.request.signal = (unsigned long)seq;
|
vbl.request.signal = (unsigned long)seq;
|
||||||
|
|
||||||
ret = drmWaitVBlank(ms->fd, &vbl);
|
ret = drmWaitVBlank(ms->fd, &vbl);
|
||||||
|
@ -732,7 +950,8 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
|
||||||
goto blit_fallback;
|
goto blit_fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
*target_msc = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
|
/* Adjust returned value for 1 fame pageflip offset of flip > 0 */
|
||||||
|
*target_msc = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence + flip);
|
||||||
frame_info->frame = *target_msc;
|
frame_info->frame = *target_msc;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -156,11 +156,12 @@ Bool ms_present_screen_init(ScreenPtr screen);
|
||||||
|
|
||||||
#ifdef GLAMOR
|
#ifdef GLAMOR
|
||||||
|
|
||||||
typedef void (*ms_pageflip_handler_proc)(uint64_t frame,
|
typedef void (*ms_pageflip_handler_proc)(modesettingPtr ms,
|
||||||
|
uint64_t frame,
|
||||||
uint64_t usec,
|
uint64_t usec,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
typedef void (*ms_pageflip_abort_proc)(void *data);
|
typedef void (*ms_pageflip_abort_proc)(modesettingPtr ms, void *data);
|
||||||
|
|
||||||
int ms_flush_drm_events(ScreenPtr screen);
|
int ms_flush_drm_events(ScreenPtr screen);
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,9 @@ typedef struct {
|
||||||
Bool is_secondary;
|
Bool is_secondary;
|
||||||
|
|
||||||
PixmapPtr fbcon_pixmap;
|
PixmapPtr fbcon_pixmap;
|
||||||
|
|
||||||
|
Bool dri2_flipping;
|
||||||
|
Bool present_flipping;
|
||||||
} drmmode_rec, *drmmode_ptr;
|
} drmmode_rec, *drmmode_ptr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -98,7 +98,7 @@ ms_pageflip_handler(uint64_t msc, uint64_t ust, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flipdata->flip_count == 1) {
|
if (flipdata->flip_count == 1) {
|
||||||
flipdata->event_handler(flipdata->fe_msc,
|
flipdata->event_handler(ms, flipdata->fe_msc,
|
||||||
flipdata->fe_usec,
|
flipdata->fe_usec,
|
||||||
flipdata->event);
|
flipdata->event);
|
||||||
|
|
||||||
|
@ -115,9 +115,12 @@ ms_pageflip_abort(void *data)
|
||||||
{
|
{
|
||||||
struct ms_crtc_pageflip *flip = data;
|
struct ms_crtc_pageflip *flip = data;
|
||||||
struct ms_flipdata *flipdata = flip->flipdata;
|
struct ms_flipdata *flipdata = flip->flipdata;
|
||||||
|
ScreenPtr screen = flipdata->screen;
|
||||||
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
|
|
||||||
if (flipdata->flip_count == 1)
|
if (flipdata->flip_count == 1)
|
||||||
flipdata->abort_handler(flipdata->event);
|
flipdata->abort_handler(ms, flipdata->event);
|
||||||
|
|
||||||
ms_pageflip_free(flip);
|
ms_pageflip_free(flip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
struct ms_present_vblank_event {
|
struct ms_present_vblank_event {
|
||||||
uint64_t event_id;
|
uint64_t event_id;
|
||||||
|
Bool unflip;
|
||||||
};
|
};
|
||||||
|
|
||||||
static RRCrtcPtr
|
static RRCrtcPtr
|
||||||
|
@ -197,7 +198,8 @@ ms_present_flush(WindowPtr window)
|
||||||
* Notify the extension code
|
* Notify the extension code
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data)
|
ms_present_flip_handler(modesettingPtr ms, uint64_t msc,
|
||||||
|
uint64_t ust, void *data)
|
||||||
{
|
{
|
||||||
struct ms_present_vblank_event *event = data;
|
struct ms_present_vblank_event *event = data;
|
||||||
|
|
||||||
|
@ -205,6 +207,9 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data)
|
||||||
(long long) event->event_id,
|
(long long) event->event_id,
|
||||||
(long long) msc, (long long) ust));
|
(long long) msc, (long long) ust));
|
||||||
|
|
||||||
|
if (event->unflip)
|
||||||
|
ms->drmmode.present_flipping = FALSE;
|
||||||
|
|
||||||
ms_present_vblank_handler(msc, ust, event);
|
ms_present_vblank_handler(msc, ust, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +217,7 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data)
|
||||||
* Callback for the DRM queue abort code. A flip has been aborted.
|
* Callback for the DRM queue abort code. A flip has been aborted.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ms_present_flip_abort(void *data)
|
ms_present_flip_abort(modesettingPtr ms, void *data)
|
||||||
{
|
{
|
||||||
struct ms_present_vblank_event *event = data;
|
struct ms_present_vblank_event *event = data;
|
||||||
|
|
||||||
|
@ -240,6 +245,9 @@ ms_present_check_flip(RRCrtcPtr crtc,
|
||||||
if (!ms->drmmode.pageflip)
|
if (!ms->drmmode.pageflip)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (ms->drmmode.dri2_flipping)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!scrn->vtSema)
|
if (!scrn->vtSema)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -286,6 +294,7 @@ ms_present_flip(RRCrtcPtr crtc,
|
||||||
{
|
{
|
||||||
ScreenPtr screen = crtc->pScreen;
|
ScreenPtr screen = crtc->pScreen;
|
||||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
|
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
|
||||||
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
|
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
|
||||||
Bool ret;
|
Bool ret;
|
||||||
|
@ -302,10 +311,14 @@ ms_present_flip(RRCrtcPtr crtc,
|
||||||
(long long) event_id, (long long) target_msc));
|
(long long) event_id, (long long) target_msc));
|
||||||
|
|
||||||
event->event_id = event_id;
|
event->event_id = event_id;
|
||||||
|
event->unflip = FALSE;
|
||||||
|
|
||||||
ret = ms_do_pageflip(screen, pixmap, event, drmmode_crtc->vblank_pipe, !sync_flip,
|
ret = ms_do_pageflip(screen, pixmap, event, drmmode_crtc->vblank_pipe, !sync_flip,
|
||||||
ms_present_flip_handler, ms_present_flip_abort);
|
ms_present_flip_handler, ms_present_flip_abort);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
|
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
|
||||||
|
else
|
||||||
|
ms->drmmode.present_flipping = TRUE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -317,6 +330,7 @@ static void
|
||||||
ms_present_unflip(ScreenPtr screen, uint64_t event_id)
|
ms_present_unflip(ScreenPtr screen, uint64_t event_id)
|
||||||
{
|
{
|
||||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
|
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
|
||||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||||
int i;
|
int i;
|
||||||
|
@ -327,6 +341,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event->event_id = 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) &&
|
||||||
ms_do_pageflip(screen, pixmap, event, -1, FALSE,
|
ms_do_pageflip(screen, pixmap, event, -1, FALSE,
|
||||||
|
@ -358,6 +373,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
present_event_notify(event_id, 0, 0);
|
present_event_notify(event_id, 0, 0);
|
||||||
|
ms->drmmode.present_flipping = FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue