glx/dri3: Don't fail on glXSwapBuffersMscOML(dpy, window, 0, 0, 0) (v2)
glXSwapBuffersMscOML() with target_msc=divisor=remainder=0 gets translated into target_msc=divisor=0 but remainder=1 by the mesa api. This is done for server DRI2 where there needs to be a way to tell the server-side DRI2ScheduleSwap implementation if a call to glXSwapBuffers() or glXSwapBuffersMscOML(dpy,window,0,0,0) was done. remainder = 1 was (ab)used as a flag to tell the server to select proper semantic. The DRI3/Present backend ignored this signalling, treated any target_msc=0 as glXSwapBuffers() request, and called xcb_present_pixmap with invalid divisor=0, remainder=1 combo. The present extension responded kindly to this with a BadValue error and dropped the request, but mesa's DRI3/Present backend doesn't check for error codes. From there on stuff went downhill quickly for the calling OpenGL client... This patch fixes the problem. v2: Change comments to be more clear, with reference to relevant spec, as suggested by Eric Anholt. Cc: "10.3 10.4" <mesa-stable@lists.freedesktop.org> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Reviewed-by: Axel Davy <axel.davy@ens.fr> Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:

committed by
Emil Velikov

parent
455d3036fa
commit
0d7f4c8658
@@ -1560,11 +1560,24 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
|
||||
dri3_fence_reset(c, back);
|
||||
|
||||
/* Compute when we want the frame shown by taking the last known successful
|
||||
* MSC and adding in a swap interval for each outstanding swap request
|
||||
* MSC and adding in a swap interval for each outstanding swap request.
|
||||
* target_msc=divisor=remainder=0 means "Use glXSwapBuffers() semantic"
|
||||
*/
|
||||
++priv->send_sbc;
|
||||
if (target_msc == 0)
|
||||
if (target_msc == 0 && divisor == 0 && remainder == 0)
|
||||
target_msc = priv->msc + priv->swap_interval * (priv->send_sbc - priv->recv_sbc);
|
||||
else if (divisor == 0 && remainder > 0) {
|
||||
/* From the GLX_OML_sync_control spec:
|
||||
*
|
||||
* "If <divisor> = 0, the swap will occur when MSC becomes
|
||||
* greater than or equal to <target_msc>."
|
||||
*
|
||||
* Note that there's no mention of the remainder. The Present extension
|
||||
* throws BadValue for remainder != 0 with divisor == 0, so just drop
|
||||
* the passed in value.
|
||||
*/
|
||||
remainder = 0;
|
||||
}
|
||||
|
||||
/* From the GLX_EXT_swap_control spec:
|
||||
*
|
||||
|
Reference in New Issue
Block a user