Swap limit

Mario Kleiner mario.kleiner at tuebingen.mpg.de
Mon Dec 13 09:04:01 PST 2010

On Dec 10, 2010, at 8:00 PM, Jesse Barnes wrote:

> On Fri, 10 Dec 2010 15:40:38 +0100
> Mario Kleiner <mario.kleiner at tuebingen.mpg.de> wrote:
>> It schedules an immediate copy-swap via blitting. Unfortunately  
>> the ddx
>> doesn't know about the swap_interval, so it still synchronizes the
>> execution of the blit to vsync via vline waits. That's tear-free,  
>> but it
>> depends on the location and size of the drawable and the current
>> position of the scanout if this will cause an immediate swap (if  
>> scanout
>> is outside the drawables area) or a vsync'ed swap. It's a bit  
>> undefined
>> behaviour for non-fullscreen drawables and it effectively enforces a
>> minimum swap interval of 1 for fullscreen drawables, which is not  
>> what
>> we want.
> That's actually the problem; swapbufferswait isn't *quite* equivalent
> to swap interval = 1, since you can potentially do multiple blits
> before the scanline intercepts your rect(s).
> But regardless, we should add an API option to allow blits to happen
> immediately when swap_interval = 0 both with and without tear
> avoidance.  I think Pauli's followup covers this (tearing swap limit 0
> vs tear free swap limit 0).

Ja, if i understand Pauli's proposal correctly, it's non-vsync'ed  
flips/copies for the tearing case and some kind of limited n- 
buffering + dropping frames. I mostly like it, but i think clients  
should have control over the desired behaviour.

The non-vsync'ed flips as i proposed it would be as easy as  
communicating swap_interval to the ddx (or the ddx querying it) and  
then the ddx not vsync'ing its copies or flips. I think that's the  
same as what Pauli proposes for the tearing case? I don't think using  
target_msc == current_msc is a good way of choosing this. Usually you  
want a flip to be delayed in this case, not a complete rendered frame  
to be dropped. At least i would panic if dropping frames would be  
suddenly the default behaviour of the ddx in case of target_msc ==  
current_msc, unless there's extra api to control this.

The reason i like this swap_interval == 0 --> tearing immedate flip  
is mostly because

a) It's consistent with what all other os'es and non-free drivers do.  
As a toolkit developer i like it if the default behaviour of  
different platforms is somewhat consistent for a similar existing  
api, it makes porting and maintenance simpler.

b) It can be used as a hack for userspace toolkits to allow somewhat  
synchronized swaps across drawables if there isn't proper api to  
control this. E.g., if you have two drawables on two display heads  
and you want to swap them simultaneously and at least somewhat tear- 
free, you can do glFinish on both drawables contexts, so the  
drawables are swap-ready, then schedule a swap_interval = 1 swap on  
one drawable, wait for it to complete its swap and then immediately  
schedule a swap_interval = 0 swap on the 2nd drawable. You will get a  
tear-free update of the 1st drawable and depending on latencies and  
how well the displays are synchronized, you may get a tear-free  
update on the 2nd head as well.

Ideally we should have api to control this, maybe some  
OML_sync_control_2 extension. Ideally, i'd like to have a swapbuffers  
call that allows to...

...define the swap deadline by target_msc or target system time.
...vsync or non-vsync
...If we have n-buffering, what to do for each queued swap if we fall  
behind the target presentation time. Present the buffer, tear-free  
and just accumulate more delay, or drop the buffer to catch up.
...synchronize multiple drawables in their swap behaviour -> the  
sgi_swap_group extension could handle that.

For a extension of the pageflip ioctl() it would be good if we could  
pass some flags or more info to the kms driver. Currently we have a  
bitfield to pass flags to the drm's ioctl() entry point, but they  
aren't passed through to the kms drivers implementation of the ioctl.


- A flag to ask for non-vsynced pageflip
- A flag or mask to implement synchronized flips across crtc's, to  
make mirror mode, swap_group support and drawables that span multiple  
crtc's robust.
- Possible future flags to allow to implement frame-sequential  
stereo, e.g., to tell if you're queuing a new future frontbuffer for  
the left-eye or right-eye.


More information about the xorg-devel mailing list