Fully implement tearing control
* 12to11.man: Document new protocol. * compositor.h (enum _RenderMode): Add RenderModeVsyncAsync. * picture_renderer.c (SwapBackBuffers, PresentToWindow) (NotifyMsc): Handle new render mode. * sync_source.c (GetWantedSynchronizationType): Use presentation if the mode is VsyncAsync. (NoteFrame): Set the vsync presentation mode to RenderModeVsyncAsync.
This commit is contained in:
parent
bd3d0a96e0
commit
151473bfb5
4 changed files with 37 additions and 6 deletions
|
@ -272,6 +272,7 @@ zwp_pointer_constraints_v1 1
|
|||
zwp_relative_pointer_manager 1
|
||||
zwp_idle_inhibit_manager_v1 1
|
||||
xdg_activation_v1 1
|
||||
wp_tearing_control_manager_v1 1
|
||||
.TE
|
||||
.PP
|
||||
When the protocol translator is built with EGL support, the following
|
||||
|
|
|
@ -321,6 +321,9 @@ enum _RenderMode
|
|||
RenderModeAsync,
|
||||
/* Synchronize rendering with the vertical refresh. */
|
||||
RenderModeVsync,
|
||||
/* Synchronize rendering with the vertical refresh but allow async
|
||||
presentation if deadlines were missed. */
|
||||
RenderModeVsyncAsync,
|
||||
};
|
||||
|
||||
struct _RenderFuncs
|
||||
|
|
|
@ -847,6 +847,13 @@ SwapBackBuffers (PictureTarget *target, pixman_region32_t *damage)
|
|||
back_buffer->pixmap, present_serial,
|
||||
None, region, 0, 0, None, None, fence,
|
||||
PresentOptionAsync, 0, 0, 0, NULL, 0);
|
||||
else if (target->render_mode == RenderModeVsyncAsync)
|
||||
/* Present the pixmap asynchronously at the next frame. */
|
||||
XPresentPixmap (compositor.display, target->window,
|
||||
back_buffer->pixmap, present_serial,
|
||||
None, region, 0, 0, None, None, fence,
|
||||
PresentOptionAsync, target->next_msc,
|
||||
1, 0, NULL, 0);
|
||||
else
|
||||
/* Present the pixmap synchronously at the next frame. */
|
||||
XPresentPixmap (compositor.display, target->window,
|
||||
|
@ -1927,6 +1934,12 @@ PresentToWindow (RenderTarget target, RenderBuffer source,
|
|||
XPresentPixmap (compositor.display, pict_target->window, buffer->pixmap,
|
||||
++present_serial, None, region, 0, 0, None, None, None,
|
||||
PresentOptionAsync, 0, 0, 0, NULL, 0);
|
||||
else if (pict_target->render_mode == RenderModeVsyncAsync)
|
||||
/* Present the pixmap at the next msc if possible. Otherwise,
|
||||
present the pixmap asynchronously. */
|
||||
XPresentPixmap (compositor.display, pict_target->window, buffer->pixmap,
|
||||
++present_serial, None, region, 0, 0, None, None, None,
|
||||
PresentOptionAsync, pict_target->next_msc, 1, 0, NULL, 0);
|
||||
else
|
||||
/* Present the pixmap at the next msc. */
|
||||
XPresentPixmap (compositor.display, pict_target->window, buffer->pixmap,
|
||||
|
@ -1972,7 +1985,7 @@ NotifyMsc (RenderTarget target, RenderCompletionFunc callback,
|
|||
|
||||
pict_target = target.pointer;
|
||||
|
||||
if (pict_target->render_mode != RenderModeVsync)
|
||||
if (pict_target->render_mode == RenderModeAsync)
|
||||
return NULL;
|
||||
|
||||
/* Allocate a presentation completion callback. */
|
||||
|
@ -1982,8 +1995,14 @@ NotifyMsc (RenderTarget target, RenderCompletionFunc callback,
|
|||
callback_rec->id = ++present_serial;
|
||||
|
||||
/* Ask for a notification. */
|
||||
if (pict_target->render_mode == RenderModeVsync)
|
||||
XPresentNotifyMSC (compositor.display, pict_target->window,
|
||||
present_serial, 0, 1, 0);
|
||||
else
|
||||
XPresentNotifyMSC (compositor.display, pict_target->window,
|
||||
present_serial, pict_target->next_msc,
|
||||
1, 0);
|
||||
|
||||
return callback_rec;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,13 @@ GetWantedSynchronizationType (SyncHelper *helper)
|
|||
return SyncTypeFrameClock;
|
||||
}
|
||||
|
||||
/* If tearing is allowed, then use present targeting the next
|
||||
frame. */
|
||||
if (helper->role->surface
|
||||
&& (helper->role->surface->current_state.presentation_hint
|
||||
== PresentationHintAsync))
|
||||
return SyncTypePresent;
|
||||
|
||||
#ifdef AllowPresent /* TODO: make this work. */
|
||||
/* Otherwise, use Present. */
|
||||
return SyncTypePresent;
|
||||
|
@ -307,10 +314,11 @@ NoteFrame (FrameMode mode, uint64_t id, void *data,
|
|||
}
|
||||
else if (wanted == SyncTypePresent)
|
||||
{
|
||||
/* Since presentation is wanted, switch the renderer to
|
||||
vsync mode. */
|
||||
/* Since presentation is wanted (which can currently only be
|
||||
due to the client having requested a presentation hint of
|
||||
"async"), switch the renderer to vsync-async mode. */
|
||||
|
||||
if (!RenderSetRenderMode (helper->target, RenderModeVsync,
|
||||
if (!RenderSetRenderMode (helper->target, RenderModeVsyncAsync,
|
||||
helper->last_msc + 1))
|
||||
{
|
||||
wanted = SyncTypeFrameClock;
|
||||
|
|
Loading…
Add table
Reference in a new issue