[Xorg] Damage/Composite + direct rendering clients

Andy Ritger aritger at nvidia.com
Mon May 17 08:41:18 PDT 2004


I've given some thought to how best to integrate direct rendering
clients with Damage/Composite.  For the below discussion, I'll focus
on GLX as the direct rendering client but the same concepts should
apply to XvMC or any other direct rendering client.

For anyone not already familiar with the Damage and Composite
extensions, please see Keith Packard's description of how compositing
works in the modular X server:

    http://www.freedesktop.org/Software/TranslucentWindows

The relevant extensions are Damage and Composite (explanations
of both, as well as links to the specs are available in Keith's
above description).  Damage has already been integrated back into
the X.org X server; integration of Composite is in progress.


How should a direct rendering client interact with Damage/Composite?
There seem to be two pieces to this: damage notification, and
synchronization.


Damage Notification

Obviously, when rendering is performed by the X server, the X server
knows what regions of the X screen have been damaged so that it can
send notification to all Damage clients.  When a direct rendering
client performs the rendering, the X server does not know when the
rendering has been performed.  When a direct rendering client damages
the X screen, it needs to communicate that information to the X
server so that the X server can notify Damage clients of the damage.

Presumably, any direct rendering client today requires support from a
vendor-specific X module to negotiate things like window moves, etc.
Given that, it seems best to leave the details up to each vendor.
As long as the core X server exposes to X drivers some function
such that an X driver can inform the X server of damage, then each
vendor can solve the client -> server communication with whatever
mechanism works best with their architecture.


Synchronization

There are atleast two possible race conditions:

   1) client kicks off rendering, notifies X server of damage,
      X server sends Damage event to composite manager, composite
      manager sends compositing request back to server, server
      performs composite.  There needs to be some synchronization to
      guarantee that the composite is not performed until the client
      rendering is completed by the hardware.

   2) some damage occurs, composite manager sends composite request,
      additional rendering is performed, part of which the composite
      operation picks up, but the rest of the rendering is not
      composited until the next "frame" of the composite manager,
      and we see visible tearing.

      Consider this example: a translucent xterm partially overlaps
      glxgears.  If the xterm is damaged, and the composite manager
      requests a composite, and then glxgears is updated (between
      when the composite request is sent, and when the composite
      operation is performed), then the part of the glxgears beneath
      the xterm will be composited this frame of compositing.  Later,
      the composite manager will receive a damage event for glxgears,
      and will composite, causing the visible screen to be brought
      up to date.  But in the period of time between the first and
      second composites, glxgears will tear.

      The above xterm+glxgears scenario is not limited to direct
      rendering clients.  The same should be reproducible with any
      regular X rendering -- there is a race between when the
      composite manager retrieves the damage region(s), when it
      sends the composite requests, and any rendering protocol
      (or direct rendering) that is processed in between.

      It seems that the complete solution would be for the composite
      manager to perform an XGrabServer(3X11) before retrieving the
      damage regions, then send the compositing requests, and then
      XUngrabServer(3X11).  Unfortunately, that seems very heavy
      weight.  On the other hand, it may ensure faster compositing
      by effectively raising the priority of the composite manager's
      protocol while all other X clients are locked out.

      Some may be inclined to accept the tearing rather than pay
      the heavy weight operation of grabbing/ungrabbing around every
      compositing frame.  For X clients, that may be OK, but I expect
      the tearing will be much more pronounced with OpenGL clients,
      because by nature they are more often animating.


Perhaps the best solution is to introduce two new requests to the
Composite extension: a "BeginComposite" and an "EndComposite" that
composite managers would call, bracketing their compositing requests.
The X server would dispatch these requests into the X driver.
This would give vendors the flexibility to perform any necessary
synchronization to protect against the above race conditions.


In short, some sort of bracketing around the compositing is the
only thing I see lacking from the current specs that may be necessary
to adequately support direct rendering clients with Damage/Composite.



Below are 2 additional ideas that we may want to consider:

   1) Truly double buffer the compositing system.  Keith's sample
      xcompmgr double buffers the compositing by creating a pixmap the
      size of the root window, compositing into that, and then after
      each frame of compositing is complete, copying from the pixmap
      to the visible X screen (is that accurate, Keith?)

      I can't make a strong argument for it, but if instead a back
      buffer for the root window were automatically allocated when a
      composite manager started redirecting windows, and compositing
      was done into that buffer, then this might allow for various
      minor optimizations:

        - the backbuffer could be allocated, by the X driver,
          with a different surface format optimal for compositing,
          but not necessarily optimal for normal pixmaps.

        - possibly swap by flip rather than blit (though obviously
          there would be other complications: the back buffer is
          expected to accumulate, rather than get completely redrawn
          each composite frame).

        - swaps could be done by an X driver at vblank


    2) An actual fullscreen mode.  This is admittedly orthogonal
       to compositing, but the overhead of compositing suggests that
       we should have a mode of operation that clients can request
       where they are given exclusive access to the hardware,
       bypassing the compositing system.

       Today, applications use the XF86VidMode extension (or possibly
       RandR?) to set the mode that they want, and then place their
       window such that it is the only thing that is visible.

       It seems desirable to provide a way for an application to
       bypass the compositing system.  The vidmem for the X root
       window could be freed (along with everything else in video
       memory?)  A surface just the necessary size would be
       allocated, leaving all extra vidmem available for pbuffers,
       multisample buffers, textures, etc.


Do either of the above ideas sound interesting?


Here are a few other important implementation details:

- It is important that X.org maintain a binary compatible driver
  interface, so that vendors are not required to provide multiple
  driver binaries (how to determine which binary to install? etc...)

- An X driver should be able to wrap the redirection of windows to
  offscreen storage:
    - so that the window can be allocated with optimal surface
      format by the X driver
    - The X driver needs to be able to tell its direct rendering
      clients where in video memory the buffer is located

- An X driver should be able to call into the core X server to
  notify X of damage done by direct rendering clients.

- A Video Overlay Xv Adaptor is obviously fundamentally incompatible
  with Damage/Composite.  Should X drivers no longer advertise
  Video Overlay Xv adaptors if they are running in an X server that
  includes Composite support?

- As window managers and desktop environments start folding composite
  manager functionality into their projects, it would be nice
  for them to provide a way to dynamically disable/enable
  compositing... I expect some users will need to disable
  compositing while using film tools, CAD applications, etc, where
  OpenGL performance is more important to them than window system
  compositing.


Feedback very welcome.

Thanks,
- Andy






More information about the xorg mailing list