modesetting: unflip before any setcrtc() calls
Make sure we're not scanning out any fbs with fancy modifiers when we try to light up new displays. This is already the case in cases where the screen gets resized, but in cases where that doesn't happen it might be possible for the modeset(s) to fail due to watermark/etc. constraints imposed by the fancy modifiers. We can avoid that by making sure everything gets unflipped before the modeset. v2: make poll timeout infinite s/in_modeset/pending_modeset/ deal with tearfree fallout (goto no_flip) Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
This commit is contained in:
parent
0c1a93d319
commit
899c87af1f
|
@ -206,6 +206,8 @@ void ms_drm_abort(ScrnInfoPtr scrn,
|
||||||
void *match_data);
|
void *match_data);
|
||||||
void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
|
void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
|
||||||
|
|
||||||
|
Bool ms_drm_queue_is_empty(void);
|
||||||
|
|
||||||
Bool xf86_crtc_on(xf86CrtcPtr crtc);
|
Bool xf86_crtc_on(xf86CrtcPtr crtc);
|
||||||
|
|
||||||
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
|
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
|
||||||
|
@ -255,6 +257,7 @@ Bool ms_do_tearfree_flip(ScreenPtr screen, xf86CrtcPtr crtc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ms_flush_drm_events(ScreenPtr screen);
|
int ms_flush_drm_events(ScreenPtr screen);
|
||||||
|
void ms_drain_drm_events(ScreenPtr screen);
|
||||||
Bool ms_window_has_variable_refresh(modesettingPtr ms, WindowPtr win);
|
Bool ms_window_has_variable_refresh(modesettingPtr ms, WindowPtr win);
|
||||||
void ms_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
|
void ms_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
|
||||||
Bool ms_tearfree_is_active_on_crtc(xf86CrtcPtr crtc);
|
Bool ms_tearfree_is_active_on_crtc(xf86CrtcPtr crtc);
|
||||||
|
|
|
@ -1662,6 +1662,26 @@ drmmode_create_tearfree_shadow(xf86CrtcPtr crtc)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drmmmode_prepare_modeset(ScrnInfoPtr scrn)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = scrn->pScreen;
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
|
|
||||||
|
if (ms->drmmode.pending_modeset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force present to unflip everything before we might
|
||||||
|
* try lighting up new displays. This makes sure fancy
|
||||||
|
* modifiers can't cause the modeset to fail.
|
||||||
|
*/
|
||||||
|
ms->drmmode.pending_modeset = TRUE;
|
||||||
|
present_check_flips(pScreen->root);
|
||||||
|
ms->drmmode.pending_modeset = FALSE;
|
||||||
|
|
||||||
|
ms_drain_drm_events(pScreen);
|
||||||
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||||
Rotation rotation, int x, int y)
|
Rotation rotation, int x, int y)
|
||||||
|
@ -1677,6 +1697,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||||
Bool can_test;
|
Bool can_test;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (mode)
|
||||||
|
drmmmode_prepare_modeset(crtc->scrn);
|
||||||
|
|
||||||
saved_mode = crtc->mode;
|
saved_mode = crtc->mode;
|
||||||
saved_x = crtc->x;
|
saved_x = crtc->x;
|
||||||
saved_y = crtc->y;
|
saved_y = crtc->y;
|
||||||
|
@ -3906,6 +3929,8 @@ drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw,
|
||||||
Bool success = TRUE;
|
Bool success = TRUE;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
drmmmode_prepare_modeset(pScrn);
|
||||||
|
|
||||||
for (c = 0; c < config->num_crtc; c++) {
|
for (c = 0; c < config->num_crtc; c++) {
|
||||||
xf86CrtcPtr crtc = config->crtc[c];
|
xf86CrtcPtr crtc = config->crtc[c];
|
||||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
|
|
@ -139,6 +139,8 @@ typedef struct {
|
||||||
|
|
||||||
uint32_t vrr_prop_id;
|
uint32_t vrr_prop_id;
|
||||||
Bool use_ctm;
|
Bool use_ctm;
|
||||||
|
|
||||||
|
Bool pending_modeset;
|
||||||
} drmmode_rec, *drmmode_ptr;
|
} drmmode_rec, *drmmode_ptr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -69,6 +69,13 @@ ms_flush_drm_events(ScreenPtr screen)
|
||||||
return ms_flush_drm_events_timeout(screen, 0);
|
return ms_flush_drm_events_timeout(screen, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ms_drain_drm_events(ScreenPtr screen)
|
||||||
|
{
|
||||||
|
while (!ms_drm_queue_is_empty())
|
||||||
|
ms_flush_drm_events_timeout(screen, -1);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef GLAMOR_HAS_GBM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -327,6 +327,9 @@ ms_present_check_flip(RRCrtcPtr crtc,
|
||||||
if (ms->drmmode.sprites_visible > 0)
|
if (ms->drmmode.sprites_visible > 0)
|
||||||
goto no_flip;
|
goto no_flip;
|
||||||
|
|
||||||
|
if (ms->drmmode.pending_modeset)
|
||||||
|
goto no_flip;
|
||||||
|
|
||||||
if(!ms_present_check_unflip(crtc, window, pixmap, sync_flip, reason))
|
if(!ms_present_check_unflip(crtc, window, pixmap, sync_flip, reason))
|
||||||
goto no_flip;
|
goto no_flip;
|
||||||
|
|
||||||
|
|
|
@ -642,6 +642,12 @@ ms_drm_handler(int fd, uint32_t frame, uint32_t sec, uint32_t usec,
|
||||||
FALSE, (uint32_t) (uintptr_t) user_ptr);
|
FALSE, (uint32_t) (uintptr_t) user_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
ms_drm_queue_is_empty(void)
|
||||||
|
{
|
||||||
|
return xorg_list_is_empty(&ms_drm_queue);
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
ms_vblank_screen_init(ScreenPtr screen)
|
ms_vblank_screen_init(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -157,6 +157,9 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc);
|
||||||
extern _X_EXPORT Bool
|
extern _X_EXPORT Bool
|
||||||
present_screen_init(ScreenPtr screen, present_screen_info_ptr info);
|
present_screen_init(ScreenPtr screen, present_screen_info_ptr info);
|
||||||
|
|
||||||
|
extern _X_EXPORT void
|
||||||
|
present_check_flips(WindowPtr window);
|
||||||
|
|
||||||
typedef void (*present_complete_notify_proc)(WindowPtr window,
|
typedef void (*present_complete_notify_proc)(WindowPtr window,
|
||||||
CARD8 kind,
|
CARD8 kind,
|
||||||
CARD8 mode,
|
CARD8 mode,
|
||||||
|
|
|
@ -191,6 +191,26 @@ present_screen_priv_init(ScreenPtr screen)
|
||||||
return screen_priv;
|
return screen_priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_flip_visit(WindowPtr window, void *data)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = window->drawable.pScreen;
|
||||||
|
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||||
|
|
||||||
|
if (!screen_priv)
|
||||||
|
return WT_DONTWALKCHILDREN;
|
||||||
|
|
||||||
|
screen_priv->check_flip_window(window);
|
||||||
|
|
||||||
|
return WT_WALKCHILDREN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
present_check_flips(WindowPtr window)
|
||||||
|
{
|
||||||
|
TraverseTree(window, check_flip_visit, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize a screen for use with present in default screen flip mode (scmd)
|
* Initialize a screen for use with present in default screen flip mode (scmd)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue