Skip to content

Commit d3ec45f

Browse files
vsyrjalametux
authored andcommitted
modesetting: Use IN_FORMATS_ASYNC for async flips
Use the IN_FORMATS_ASYNC blob (as opposed to the normal IN_FORMATS blob) to determine which formats/modifiers are supported. This will allow the client to allocate buffers which can actually be async flipped. In order to guarantee that the most optimal modifier is always used we also need to force a modifier renegotiation when swicthing between sync and async flips. Otherwise eg. sync flips might end up using a less optimal sync+async modifier instead of a more optimal sync-only modifier. Signed-off-by: notbabaisyou <[email protected]> Link: https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1816
1 parent a345c59 commit d3ec45f

File tree

5 files changed

+82
-3
lines changed

5 files changed

+82
-3
lines changed

hw/xfree86/drivers/video/modesetting/driver.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,51 @@ msSetWindowVRRMode(WindowPtr window, WindowVRRMode mode)
927927
ms_present_set_screen_vrr(scrn, variable_refresh);
928928
}
929929

930+
931+
Bool
932+
ms_window_has_async_flip(WindowPtr win)
933+
{
934+
ScrnInfoPtr scrn = xf86ScreenToScrn(win->drawable.pScreen);
935+
modesettingPtr ms = modesettingPTR(scrn);
936+
struct ms_async_flip_priv *priv = dixLookupPrivate(&win->devPrivates,
937+
&ms->drmmode.asyncFlipPrivateKeyRec);
938+
939+
return priv->async_flip;
940+
}
941+
942+
void
943+
ms_window_update_async_flip(WindowPtr win, Bool async_flip)
944+
{
945+
ScrnInfoPtr scrn = xf86ScreenToScrn(win->drawable.pScreen);
946+
modesettingPtr ms = modesettingPTR(scrn);
947+
struct ms_async_flip_priv *priv = dixLookupPrivate(&win->devPrivates,
948+
&ms->drmmode.asyncFlipPrivateKeyRec);
949+
950+
priv->async_flip = async_flip;
951+
}
952+
953+
Bool
954+
ms_window_has_async_flip_modifiers(WindowPtr win)
955+
{
956+
ScrnInfoPtr scrn = xf86ScreenToScrn(win->drawable.pScreen);
957+
modesettingPtr ms = modesettingPTR(scrn);
958+
struct ms_async_flip_priv *priv = dixLookupPrivate(&win->devPrivates,
959+
&ms->drmmode.asyncFlipPrivateKeyRec);
960+
961+
return priv->async_flip_modifiers;
962+
}
963+
964+
void
965+
ms_window_update_async_flip_modifiers(WindowPtr win, Bool async_flip)
966+
{
967+
ScrnInfoPtr scrn = xf86ScreenToScrn(win->drawable.pScreen);
968+
modesettingPtr ms = modesettingPTR(scrn);
969+
struct ms_async_flip_priv *priv = dixLookupPrivate(&win->devPrivates,
970+
&ms->drmmode.asyncFlipPrivateKeyRec);
971+
972+
priv->async_flip_modifiers = async_flip;
973+
}
974+
930975
static void
931976
FreeScreen(ScrnInfoPtr pScrn)
932977
{
@@ -1711,6 +1756,11 @@ modesetCreateScreenResources(ScreenPtr pScreen)
17111756
sizeof(struct ms_vrr_priv)))
17121757
return FALSE;
17131758

1759+
if (!dixRegisterPrivateKey(&ms->drmmode.asyncFlipPrivateKeyRec,
1760+
PRIVATE_WINDOW,
1761+
sizeof(struct ms_async_flip_priv)))
1762+
return FALSE;
1763+
17141764
return ret;
17151765
}
17161766

hw/xfree86/drivers/video/modesetting/driver.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ struct ms_vrr_priv {
5252
Bool variable_refresh;
5353
};
5454

55+
struct ms_async_flip_priv {
56+
Bool async_flip;
57+
Bool async_flip_modifiers;
58+
};
59+
5560
typedef enum {
5661
OPTION_SW_CURSOR,
5762
OPTION_CURSOR_SIZE,
@@ -265,5 +270,9 @@ void ms_drain_drm_events(ScreenPtr screen);
265270
Bool ms_window_has_variable_refresh(modesettingPtr ms, WindowPtr win);
266271
void ms_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
267272
Bool ms_tearfree_is_active_on_crtc(xf86CrtcPtr crtc);
273+
Bool ms_window_has_async_flip(WindowPtr win);
274+
void ms_window_update_async_flip(WindowPtr win, Bool async_flip);
275+
Bool ms_window_has_async_flip_modifiers(WindowPtr win);
276+
void ms_window_update_async_flip_modifiers(WindowPtr win, Bool async_flip);
268277

269278
#endif /* XSERVER_XFREE86_DRIVER_H */

hw/xfree86/drivers/video/modesetting/drmmode_display.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ get_drawable_modifiers(DrawablePtr draw, uint32_t format,
248248
{
249249
ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
250250
modesettingPtr ms = modesettingPTR(scrn);
251+
Bool async_flip;
251252

252253
if (!present_can_window_flip((WindowPtr) draw) ||
253254
!ms->drmmode.pageflip || ms->drmmode.dri2_flipping || !scrn->vtSema) {
@@ -256,8 +257,11 @@ get_drawable_modifiers(DrawablePtr draw, uint32_t format,
256257
return TRUE;
257258
}
258259

260+
async_flip = ms_window_has_async_flip((WindowPtr)draw);
261+
ms_window_update_async_flip_modifiers((WindowPtr)draw, async_flip);
262+
259263
*num_modifiers = get_modifiers_set(scrn, format, modifiers,
260-
TRUE, FALSE, FALSE);
264+
TRUE, FALSE, async_flip);
261265
return TRUE;
262266
}
263267
#endif

hw/xfree86/drivers/video/modesetting/drmmode_display.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ typedef struct {
120120
DevPrivateKeyRec pixmapPrivateKeyRec;
121121
DevScreenPrivateKeyRec spritePrivateKeyRec;
122122
DevPrivateKeyRec vrrPrivateKeyRec;
123+
DevPrivateKeyRec asyncFlipPrivateKeyRec;
123124
/* Number of SW cursors currently visible on this screen */
124125
int sprites_visible;
125126

hw/xfree86/drivers/video/modesetting/present.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ ms_present_check_unflip(RRCrtcPtr crtc,
294294
modifier = gbm_bo_get_modifier(gbm);
295295
gbm_bo_destroy(gbm);
296296

297-
if (!drmmode_is_format_supported(scrn, format, modifier, FALSE)) {
297+
if (!drmmode_is_format_supported(scrn, format, modifier, !sync_flip)) {
298298
if (reason)
299299
*reason = PRESENT_FLIP_REASON_BUFFER_FORMAT;
300300
return FALSE;
@@ -321,15 +321,30 @@ ms_present_check_flip(RRCrtcPtr crtc,
321321
ScreenPtr screen = window->drawable.pScreen;
322322
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
323323
modesettingPtr ms = modesettingPTR(scrn);
324+
Bool async_flip = !sync_flip;
324325

325326
if (ms->drmmode.sprites_visible > 0)
326327
goto no_flip;
327328

328329
if (ms->drmmode.pending_modeset)
329330
goto no_flip;
330331

331-
if(!ms_present_check_unflip(crtc, window, pixmap, sync_flip, reason))
332+
if (!ms_present_check_unflip(crtc, window, pixmap, sync_flip, reason)) {
333+
if (reason && *reason == PRESENT_FLIP_REASON_BUFFER_FORMAT)
334+
ms_window_update_async_flip(window, async_flip);
332335
goto no_flip;
336+
}
337+
338+
ms_window_update_async_flip(window, async_flip);
339+
340+
/*
341+
* Force a format renegotiation when switching between sync and async,
342+
* otherwise we may end up with a working but suboptimal modifier.
343+
*/
344+
if (reason && async_flip != ms_window_has_async_flip_modifiers(window)) {
345+
*reason = PRESENT_FLIP_REASON_BUFFER_FORMAT;
346+
goto no_flip;
347+
}
333348

334349
ms->flip_window = window;
335350

0 commit comments

Comments
 (0)