DRI2/xserver: Don't hang in glXSwapBuffers if drawable moves between crtc's (bug 28383)
Detect if a drawable has been moved from an original crtc to a new crtc with a lower current vblank count than the original crtc inbetween glXSwapBuffers() calls. Reinitialize drawable's last_swap_target before scheduling next swap if such a move has taken place. last_swap_target defines the baseline for scheduling the next swap. If a movement between crtc's is not taken into account, the swap may schedule for a vblank count on the new crtc far in the future, resulting in a apparent "hang" of the drawable for a long time. Fixes Bugzilla bug #28383. Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
		
							parent
							
								
									868bf3de47
								
							
						
					
					
						commit
						75beadd766
					
				| 
						 | 
					@ -759,6 +759,7 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
 | 
				
			||||||
    DRI2DrawablePtr pPriv;
 | 
					    DRI2DrawablePtr pPriv;
 | 
				
			||||||
    DRI2BufferPtr   pDestBuffer = NULL, pSrcBuffer = NULL;
 | 
					    DRI2BufferPtr   pDestBuffer = NULL, pSrcBuffer = NULL;
 | 
				
			||||||
    int             ret, i;
 | 
					    int             ret, i;
 | 
				
			||||||
 | 
					    CARD64          ust, current_msc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pPriv = DRI2GetDrawable(pDraw);
 | 
					    pPriv = DRI2GetDrawable(pDraw);
 | 
				
			||||||
    if (pPriv == NULL) {
 | 
					    if (pPriv == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -803,12 +804,26 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
 | 
				
			||||||
     * need to schedule a swap for the last swap target + the swap interval.
 | 
					     * need to schedule a swap for the last swap target + the swap interval.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    if (target_msc == 0 && divisor == 0 && remainder == 0) {
 | 
					    if (target_msc == 0 && divisor == 0 && remainder == 0) {
 | 
				
			||||||
 | 
						/* If the current vblank count of the drawable's crtc is lower
 | 
				
			||||||
 | 
						 * than the count stored in last_swap_target from a previous swap
 | 
				
			||||||
 | 
						 * then reinitialize last_swap_target to the current crtc's msc,
 | 
				
			||||||
 | 
						 * otherwise the swap will hang. This will happen if the drawable
 | 
				
			||||||
 | 
						 * is moved to a crtc with a lower refresh rate, or a crtc that just
 | 
				
			||||||
 | 
						 * got enabled.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!(*ds->GetMSC)(pDraw, &ust, ¤t_msc))
 | 
				
			||||||
 | 
						    pPriv->last_swap_target = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (current_msc < pPriv->last_swap_target)
 | 
				
			||||||
 | 
						    pPriv->last_swap_target = current_msc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Swap target for this swap is last swap target + swap interval since
 | 
						 * Swap target for this swap is last swap target + swap interval since
 | 
				
			||||||
	 * we have to account for the current swap count, interval, and the
 | 
						 * we have to account for the current swap count, interval, and the
 | 
				
			||||||
	 * number of pending swaps.
 | 
						 * number of pending swaps.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	*swap_target = pPriv->last_swap_target + pPriv->swap_interval;
 | 
						*swap_target = pPriv->last_swap_target + pPriv->swap_interval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
	/* glXSwapBuffersMscOML could have a 0 target_msc, honor it */
 | 
						/* glXSwapBuffersMscOML could have a 0 target_msc, honor it */
 | 
				
			||||||
	*swap_target = target_msc;
 | 
						*swap_target = target_msc;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue