[Bug 79223] extra vsync when reading back pixels in xbmc

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Mon Jun 2 12:24:18 PDT 2014


https://bugs.freedesktop.org/show_bug.cgi?id=79223

--- Comment #15 from Pierre Ossman <pierre-bugzilla at ossman.eu> ---
Ok, I took a step back and decided to look at this at a higher level again. A
single wait for vsync can't be causing problems, and there has to be at least
two. So I set out to find the other one. And I think I've figured this out
(somewhat).

First this though:

(In reply to comment #7)
> I am still seeing the frame rate problem on this machine. It is however not
> constant, and comes and goes. I am running a lower resolution here, which
> might be a factor.

Turns out it was caused be different configuration in xbmc. I hadn't turned on
the setting where it tries to properly keep track of when to display frames
(which I've found necessary in many cases to keep good A/V sync).

With that setting on, I'm reliably getting a constant halved frame rate.



Scenario 1 - No glReadPixels()
==============================

This is the normal case that works, but by some luck it seems. This is how xbmc
expects things to go:

1. Render the frame
2. Wait for vblanks until the right timestamp
3. glXSwapBuffers();

Now what happens here is that 1. will block and wait for the last swap. By the
time we've reached 2., we've already passed the proper timestamp and we want to
wait for -8 ms. This returns instantly and we move on to 3. and then repeat the
cycle.


This design seems broken even in the best of cases. Say that 1. is
non-blocking. Then we'd get:

The rendering (1.) goes instantly. We're still at the start of the screen
refresh, so we have 8 ms to wait in step 2. But it waits for vblanks so we'll
wait for 17 ms instead. When we then do the swap (3.), it will not happen until
yet another 17 ms later, completely overshooting the desired presentation time.

And if glXSwapBuffers() is blocking, then we'd be even worse of and limited to
just one frame every other screen refresh.


Scenario 2 - with glReadPixels()
================================

This to some extent degenerates into that bad scenario in the last paragraph.
We now have these steps:

1. Render the frame
2. Wait for vblanks until the right timestamp
3. glXSwapBuffers();
4. Render capture frame
5. glReadPixels()

What happens here is precisely the same as a blocking glXSwapBuffers(). 1. will
no longer be blocking as 4. has already forced a wait for a buffer swap. 2.
will then wait for at least 8 ms, but in practice for another vblank. The swap
is scheduled (3.), and then immediately waited on by doing more rendering (4.).
By the time we come back to 1., xbmc realises too much time has passed and
drops a frame.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20140602/6f1c6aa6/attachment.html>


More information about the dri-devel mailing list