[PATCH 2/2] DRI2: Add error message when working around driver bug
Mario Kleiner
mario.kleiner at tuebingen.mpg.de
Wed Oct 27 08:15:28 PDT 2010
On Oct 26, 2010, at 7:08 PM, Jesse Barnes wrote:
> On Tue, 26 Oct 2010 19:19:11 +0300
> Pauli Nieminen <ext-pauli.nieminen at nokia.com> wrote:
>> SGI_video_sync:
>> "The kernel maintains a video sync counter for
>> each physical hardware pipe in a system; the counter is incremented
>> upon the completion of the display of each full frame of video
>> data. An
>> OpenGL context always corresponds to a pipe."
>
> Right, this is the rule we break; we don't have a 1:1 correspondence
> between gfx pipes and display pipes.
>
>> "The single video sync counter is shared by all GLXContexts."
>>
>> Yes. You have to extent both OML_sync_control and SGI_video_sync
>> to expose
>> separate MSC for different CRTCs.
>>
>> I can see race condition even with events.
>>
>> * Client checks for event (none yet in queue)
>> * Client prepares to call some blocking msc call
>> * Window manager decides to move the window
>> * xserver send MSC change event
>> * Client calls blocking MSC call
>>
>> But maybe there is solution. All blocking calls could fail if MSC
>> base
>> changes. Client would have to query for new base and rate before
>> trying to
>> issue same request again.
>
> Yeah, that might work; I agree there's a race even with events that
> we'll need to handle. But even with that race handled I'd like the
> server to fail gracefully rather than hanging the app if an old MSC
> value is passed in (though in that case we could print an error
> message
> since we could assume an app error as long as the app was using the
> extended version of the spec).
>
>> For swap interval it would be enough if DDX would notify DRI2
>> about crtc
>> changes with offset (msc_for_new_crtc - msc_for_old_crtc) that can
>> be applied
>> to swaptarget.
>
> Yeah, just jumping to the new value might be ok in general. Hardcore
> libraries like Mario's can do something fancier with the extensions
> above to avoid unintended behavior.
>
I agree. Pauli's offset fix would fix the common glXSwapBuffers()
case for now and make most apps happy. We should do that. My current
hack works fine (due to the underlying vsync'ing of the ddx's) as
long as an app uses glXSwapBuffers and has swap_interval left at its
default of 1. I'd expect most apps to do that, as it was the only
supported setting (except for 0) for a long time, and all other
operating systems i know of (Linux + proprietary drivers, all
Windows, all OS/X) only obey a swap_interval = 0 or 1, but this fix
would fix it for all swap_interval settings.
For the oml_sync_control case i see these options, and each of them
makes me dizzy and uneasy in a different way, probably because i
didn't think it through clearly:
a) As Michel Daenzer proposed earlier, give each drawable its own
virtualized msc. Initialize it at drawable creation time to the true
msc of the initial crtc. Then just use the current msc and info about
crtc transitions to update the virtualized msc. This way we'd be
probably closest to the spirit of the current spec, all msc's would
always increase monotonically instead of jumping back and forth and
crtc transitions would be handled properly without the app even
noticing or needing to care. If multiple drawable's are created on
the same crtc and stay there, they'll have the same msc's, so
bufferswaps, waits and other events can be synchronized across
drawables and timestamps and counts compared meaningfully between
them. That would be nice to have.
Downside: As soon as a drawable moves away to another crtc with
different count, this beauty breaks down and the app would have large
problems finding out what just happened to it and how to relate the
msc's of different drawables to each other again. Possibly impossible
to recover with all those virtualized counts.
Also it's tricky to implement. We would need to translate forward and
backward between hardware msc's and virtualized msc each time we get
any event from the kernel or schedule one and keep track of which
crtc was assigned when all the time, also in all queued vblank events
and all returned vblank and swap events.
The fact that we currently have 64 bit msc counters in userspace and
spec, but only < 32 bit counters in kernel space and all the
wraparound issues doesn't make it simpler to get right and race-free.
b) Extend the spec: If a crtc transition is detected, make all calls
that rely on the msc (glXSwapBuffersMsc(), glXWaitForMsc()) fail with
some error code until the app has called glXGetSyncValuesOML() again
to fetch the new, updated msc for the new crtc.
I like this because i think it is simpler to implement correctly and
because the apps still see what is really going on. Toolkits like
mine which require very tight (=paranoid) control about timing don't
like too much abstraction and virtualization.
Downside: Less elegant? What if multiple threads (somewhat likely)
will use blocking calls on the same drawable? One thread might query
the msc and clear the 'dirty bit', but other threads may not notice?
Need a per-thread dirty bit??
Or even have some dedicated function that the app needs to call to
acknowledge it realizes what just happened? Or a way for apps to tell
the server how they want to be treated in such cases?
E.g., one could have a transition counter for each drawable which
increments at each crtc transition and a way for the app to query the
current count and to pass the count with each blocking call,
basically as a cookie? The implementation could compare counts to
know if an app is aware at function call time that the crtc has
changed and fail a call if the counts mismatch.
c) Extend the spec with new possible error cases to watch out:
Unblock such calls in some slightly ugly manner to at least avoid an
application hang, e.g., just . Somehow notify the application of what
happened (error return code, or deriveable from the returned
timestamps/counts/intel_swap_events?), maybe print some warning to
the server log? How to decide which call after a transition should be
unblocked and which are valid calls again?
Ideas?
> Thanks again for all your work on this. These are good improvements.
>
Indeed!
-mario
*********************************************************************
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner at tuebingen.mpg.de
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
More information about the xorg-devel
mailing list