xwayland: re-compute target msc during xwl_present_re_execute
If a presentation request is delayed while waiting for a fence, the original target msc may no longer be correct. Instead, we should compute a new target msc in xwl_present_re_execute. Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
This commit is contained in:
parent
3df236a3d5
commit
0a7b09a041
|
@ -215,6 +215,13 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
|
||||||
static void
|
static void
|
||||||
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
|
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
|
||||||
|
|
||||||
|
static int
|
||||||
|
xwl_present_queue_vblank(ScreenPtr screen,
|
||||||
|
WindowPtr present_window,
|
||||||
|
RRCrtcPtr crtc,
|
||||||
|
uint64_t event_id,
|
||||||
|
uint64_t msc);
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
|
xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
|
||||||
{
|
{
|
||||||
|
@ -237,6 +244,18 @@ xwl_present_get_ust_msc(ScreenPtr screen,
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
xwl_present_get_exec_msc(uint32_t options, uint64_t target_msc)
|
||||||
|
{
|
||||||
|
/* Synchronous Xwayland presentations always complete (at least) one frame after they
|
||||||
|
* are executed
|
||||||
|
*/
|
||||||
|
if (options & PresentOptionAsyncMayTear)
|
||||||
|
return target_msc;
|
||||||
|
|
||||||
|
return target_msc - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the wait fence or previous flip is completed, it's time
|
* When the wait fence or previous flip is completed, it's time
|
||||||
* to re-try the request
|
* to re-try the request
|
||||||
|
@ -244,9 +263,27 @@ xwl_present_get_ust_msc(ScreenPtr screen,
|
||||||
static void
|
static void
|
||||||
xwl_present_re_execute(present_vblank_ptr vblank)
|
xwl_present_re_execute(present_vblank_ptr vblank)
|
||||||
{
|
{
|
||||||
|
struct xwl_present_event *event = xwl_present_event_from_vblank(vblank);
|
||||||
uint64_t ust = 0, crtc_msc = 0;
|
uint64_t ust = 0, crtc_msc = 0;
|
||||||
|
|
||||||
(void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
|
(void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
|
||||||
|
/* re-compute target / exec msc */
|
||||||
|
vblank->target_msc = present_get_target_msc(0, crtc_msc,
|
||||||
|
event->divisor,
|
||||||
|
event->remainder,
|
||||||
|
event->options);
|
||||||
|
vblank->exec_msc = xwl_present_get_exec_msc(event->options,
|
||||||
|
vblank->target_msc);
|
||||||
|
|
||||||
|
vblank->queued = TRUE;
|
||||||
|
if (msc_is_after(vblank->exec_msc, crtc_msc) &&
|
||||||
|
xwl_present_queue_vblank(vblank->screen, vblank->window,
|
||||||
|
vblank->crtc,
|
||||||
|
vblank->event_id,
|
||||||
|
vblank->exec_msc) == Success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
xwl_present_execute(vblank, ust, crtc_msc);
|
xwl_present_execute(vblank, ust, crtc_msc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -818,7 +855,7 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
|
||||||
|
|
||||||
if (xwl_window->tearing_control) {
|
if (xwl_window->tearing_control) {
|
||||||
uint32_t hint;
|
uint32_t hint;
|
||||||
if (event->async_may_tear)
|
if (event->options & PresentOptionAsyncMayTear)
|
||||||
hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
|
hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
|
||||||
else
|
else
|
||||||
hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
|
hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
|
||||||
|
@ -1047,15 +1084,10 @@ xwl_present_pixmap(WindowPtr window,
|
||||||
}
|
}
|
||||||
|
|
||||||
vblank->event_id = ++xwl_present_event_id;
|
vblank->event_id = ++xwl_present_event_id;
|
||||||
event->async_may_tear = options & PresentOptionAsyncMayTear;
|
event->options = options;
|
||||||
|
event->divisor = divisor;
|
||||||
/* Synchronous Xwayland presentations always complete (at least) one frame after they
|
event->remainder = remainder;
|
||||||
* are executed
|
vblank->exec_msc = xwl_present_get_exec_msc(options, vblank->target_msc);
|
||||||
*/
|
|
||||||
if (event->async_may_tear)
|
|
||||||
vblank->exec_msc = vblank->target_msc;
|
|
||||||
else
|
|
||||||
vblank->exec_msc = vblank->target_msc - 1;
|
|
||||||
|
|
||||||
vblank->queued = TRUE;
|
vblank->queued = TRUE;
|
||||||
if (crtc_msc < vblank->exec_msc) {
|
if (crtc_msc < vblank->exec_msc) {
|
||||||
|
|
|
@ -58,8 +58,11 @@ struct xwl_present_event {
|
||||||
present_vblank_rec vblank;
|
present_vblank_rec vblank;
|
||||||
|
|
||||||
PixmapPtr pixmap;
|
PixmapPtr pixmap;
|
||||||
Bool async_may_tear;
|
|
||||||
Bool copy_executed;
|
Bool copy_executed;
|
||||||
|
|
||||||
|
uint32_t options;
|
||||||
|
uint64_t divisor;
|
||||||
|
uint64_t remainder;
|
||||||
};
|
};
|
||||||
|
|
||||||
Bool xwl_present_entered_for_each_frame_callback(void);
|
Bool xwl_present_entered_for_each_frame_callback(void);
|
||||||
|
|
Loading…
Reference in New Issue