Initial DRI3000 protocol specs available

Chris Wilson chris at chris-wilson.co.uk
Thu Feb 21 03:55:26 PST 2013


On Wed, Feb 20, 2013 at 10:17:56PM -0800, Keith Packard wrote:
> Chris Wilson <chris at chris-wilson.co.uk> writes:
> 
> > You manage ask yourself the question I was trying to lead: how the heck
> > does the compositor learn that the underlying graphics object has
> > changed?
> 
> It can certainly tell that the underlying contents have changed with
> Damage events, but as to how it knows that it should do another
> BufferFromPixmap request, I think that's gonna require another
> event.
> 
> Now, the big question is how to deal with compositing managers which
> don't know about DRI3. I suspect we'll just have to skip the DMA-BUF
> swapping hack for window pixmaps unless the compositor gives us the OK
> to do so.

If a DRI2 client also grabs the buffer, then we have to fallback to blits.
That should be fairly easy to detect and handle.
 
> > In DRI2 this is through the InvalidateEvent, and the lack of
> > being able to send those from the driver before the Damage is sent is
> > one of the reasons why the current exchange mechanism is broken.
> 
> Hrm. With the current system, except for override-redirect windows, if
> the compositor is also the window manager, it should always know when
> the window pixmap is going to be replaced because that only happens when
> the window is resized, and the window manager is entirely responsible
> for making that happen. For override-redirect windows, if the
> ConfigureNotify event was delivered before the Damage event, then the
> compositor could know about that as well.

We are concerned with the GEM objects backing the Pixmaps, which may
be changed at whim by the driver.

> I guess I'd like to know more about what is broken with the current
> system for compositors...

We cannot perform simple name exchanges currently in DRI2 because the
Damage is badly ordered wrt the Invalidate event and there is no
coordination between client <-> server <-> compositor on when the
buffers are reusable by the client.

> In any case, as the underlying DMA-BUF is changing, the compositor is
> going to need to know that so it can release the old pixmap back to the
> application, and so it can rewire its own compositing operations to use
> the new object.
> 
> It might be nice to have the compositor use persistent names for the
> various DMA-BUFs that are used for a particular window. I think that
> means having the compositor hold on to old DMA-BUF window pixmap
> IDs. That seems tricky though. The alternative will be to have the
> compositor create/destroy a pixmap ID per frame. Not intolerable, but
> not optimal.
> 
> > Getting buffer exchanges working in conjunction with the external
> > compositor is more or less as tricky as it gets. The notion that the
> > buffer is kept busy by the compositor and so prevents the DRI3 client
> > from overdrawing it is key. And that naturally leads to the compositor
> > needing to release the old buffer once it is referencing the new
> > post-swap buffer.
> 
> Right, an easy technique there would be to have it use NameWindowPixmap
> when it got an event telling it that a new pixmap was in use for the
> window, and then when it was finished with that pixmap, it could just
> use FreePixmap to tell the server it was done. That would bump the
> refcnt down to one in the server, at which point it could queue the
> pixmap to be sent as 'idle' the next time SwapRegion was called.
> 
> > Serialisation between rendering of the common buffers
> > is definitely s.e.p. I agree that should solve the compositor problem.
> 
> Ok, cool.
> 
> So, changes that I think are needed:
> 
>  1) If someone calls TextureFromPixmap on a window pixmap, we need to
>     suppress the window pixmap swapping hack. Alternatively, we can have
>     the compositor explicitly enable window pixmap swapping.

I think we definitely want to support window swapping with DRI3
compositors. DRI2 compositors will just have to continue to force blits.

>  2) We need to send an event when the buffer underlying a window switches.
> 
>  3) We need to be explicit about event ordering between the new window
>     pixmap change notify event and any related Damage.

As I see it the challenge is to prevent sending the buffer release
(SwapIdle) back to the client before all interested third parties have
had a chance to snoop its contents and react. Sketching that out we
need to increment the busy count everytime we send an Invalidate and
expect the client (compositor) to send a release after they have
finished processing the buffer.

For fun, imagine a fullscreen redirected Window (because Wine still
manages to confuse everybody):

client                 server                        compositor

new drawable -------------------------------------> setup Damage
show A  (Swap) ----->
		      invalidate buffer & damage ->
		                <-----------------  show A (Swap)
		       
		      flip A
show B ------------>
		      invalidate buffer & damage ->
		                <-----------------  show B
		      FlipDone A
		      flip B
		      FlipDone B
		      SwapIdle A ---------------->
                                <-----------------  release A
     <--------------- SwapIdle A
show C ------------>
		      invalidate buffer & damage ->
		                <-----------------  show C
		      flip C
show A ------------>
		      invalidate buffer & damage ->
		                <-----------------  show A
		      FlipDone C
		      SwapIdle B ---------------->
		      flip A
		                <-----------------  release B
     <--------------- SwapIdle B
 
One variation here would be for the compositor to not listen for its
SwapIdle events but release the buffer early.

show A  (Swap) ----->
		      invalidate buffer & damage ->
		                <-----------------  show A (Swap)
		       
		      flip A
		      FlipDone A
show B ------------>
		      invalidate buffer & damage ->
		                <-----------------  show B
                                <-----------------  release A
		      flip B
		      FlipDone B
     <--------------- SwapIdle A

For a small Window, it begins to look like

show A  (Swap) ----->
		      invalidate buffer & damage ->
		                <-----------------  create pixmap from A
				                    render into C
		                <-----------------  show C (swap)
		      flip C
		      FlipDone C
show B ------------>
		      invalidate buffer & damage ->
		                <-----------------  create pixmap from B
                                <-----------------  release A
     <--------------- SwapIdle A
				                    render into D
		                <-----------------  show D
		      flip D
		      FlipDone D
		      SwapIdle C ---------------->

The magic invalidate is a little worrisome - that it creates an active
reference needs to be explicit. Can it be an event that sends a new
buffer ID along with reference? The other aspect to bear in mind is that
with this model we should be able to just keep adding layers of
compositors for nested servers.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the xorg-devel mailing list