nuclear@6: The DAMAGE Extension nuclear@6: Protocol Version 1.1 nuclear@6: Document Revision 1 nuclear@6: 2007-01-08 nuclear@6: nuclear@6: Keith Packard nuclear@6: keithp@keithp.com nuclear@6: nuclear@6: Eric Anholt nuclear@6: eric@anholt.net nuclear@6: Open Source Technology Center nuclear@6: Intel Corporation nuclear@6: 1. Introduction nuclear@6: nuclear@6: Monitoring the regions affected by rendering has wide-spread use, from nuclear@6: VNC-like systems scraping the screen to screen magnifying applications nuclear@6: designed to aid users with limited visual acuity. The DAMAGE extension is nuclear@6: designed to make such applications reasonably efficient in the face of nuclear@6: server-client latency. nuclear@6: nuclear@6: 2. Acknolwedgements nuclear@6: nuclear@6: As usual, the author had significant input from many people, in particular: nuclear@6: nuclear@6: + Havoc Pennington who designed and implemented a Damage extension nuclear@6: last year which was then lost to the mists of time. nuclear@6: nuclear@6: + Bill Haneman whose work on accessibility in the Gnome environment nuclear@6: is legendary. nuclear@6: nuclear@6: + Jim Gettys who found a way to avoid streaming damage rectangles nuclear@6: to the client in many cases. nuclear@6: nuclear@6: + Owen Taylor who suggested that streaming damage rectangles may nuclear@6: be warranted in some cases after all. nuclear@6: nuclear@6: 3. Damage Model nuclear@6: nuclear@6: We call changes made to pixel contents of windows and pixmaps 'damage' nuclear@6: throughout this extension. Another notion of 'damage' are drawable regions nuclear@6: which are in need of redisplay to repair the effects of window manipulation nuclear@6: or other data loss. This extension doesn't deal with this second notion at nuclear@6: all; suggestions on a better term which isn't easily conflated with existing nuclear@6: notions are eagerly solicited. nuclear@6: nuclear@6: Damage accumulates as drawing occurs in the drawable. Each drawing operation nuclear@6: 'damages' one or more rectangular areas within the drawable. The rectangles nuclear@6: are guaranteed to include the set of pixels modified by each operation, but nuclear@6: may include significantly more than just those pixels. The desire is for nuclear@6: the damage to strike a balance between the number of rectangles reported and nuclear@6: the extraneous area included. A reasonable goal is for each primitive nuclear@6: object drawn (line, string, rectangle) to be represented as a single nuclear@6: rectangle and for the damage area of the operation to be the union of these nuclear@6: rectangles. nuclear@6: nuclear@6: The DAMAGE extension allows applications to either receive the raw nuclear@6: rectangles as a stream of events, or to have them partially processed within nuclear@6: the X server to reduce the amount of data transmitted as well as reduce the nuclear@6: processing latency once the repaint operation has started. nuclear@6: nuclear@6: Damage to a window reflects both drawing within the window itself as well as nuclear@6: drawing within any inferior window that affects pixels seen by nuclear@6: IncludeInferiors rendering operations. To reduce the computational nuclear@6: complexity of this, the DAMAGE extension allows the server to monitor all nuclear@6: rendering operations within the physical target pixel storage that fall nuclear@6: within the bounds of the window. In a system with a single frame buffer nuclear@6: holding all windows, this means that damage will accumulate for all nuclear@6: rendering operations that lie within the visible part of the window. nuclear@6: nuclear@6: The precise reason for this architecture is to enable the Composite nuclear@6: extension which provides multiple pixel storage areas for the screen nuclear@6: contents. nuclear@6: nuclear@6: 3.1 Additions in the 1.1 version of the protocol nuclear@6: nuclear@6: Damage is automatically computed by the X Server for X rendering operations, nuclear@6: but direct rendering extensions have allowed clients to perform rendering nuclear@6: outside of the control of the X Server. The 1.1 version of the protocol nuclear@6: added a request to allow direct rendering clients to report damage to a nuclear@6: drawable. Some direct rendering clients, due to architectural limitations, nuclear@6: always perform rendering to the root window, even in when it should be nuclear@6: performed to the backing pixmap in the Composite case. To provide nuclear@6: less-incorrect rendering in this cases, the direct rendering client should nuclear@6: translate its damage region to screen coordinates and report the damage against nuclear@6: the root window rather than the drawable. nuclear@6: nuclear@6: 4. Data types nuclear@6: nuclear@6: The "Damage" object holds any accumulated damage region and reflects the nuclear@6: relationship between the drawable selected for damage notification and the nuclear@6: drawable for which damage is tracked. nuclear@6: nuclear@6: 5. Errors nuclear@6: nuclear@6: Damage nuclear@6: A value for a DAMAGE argument does not name a defined DAMAGE. nuclear@6: nuclear@6: 6. Types nuclear@6: nuclear@6: DAMAGE 32-bit value (top three bits guaranteed to be zero) nuclear@6: nuclear@6: DamageReportLevel { DamageReportRawRectangles, nuclear@6: DamageReportDeltaRectangles, nuclear@6: DamageReportBoundingBox, nuclear@6: DamageReportNonEmpty } nuclear@6: nuclear@6: DamageReportRawRectangles nuclear@6: nuclear@6: Delivers DamageNotify events each time the screen nuclear@6: is modified with rectangular bounds that circumscribe nuclear@6: the damaged area. No attempt to compress out overlapping nuclear@6: rectangles is made. nuclear@6: nuclear@6: DamageReportDeltaRectangles nuclear@6: nuclear@6: Delivers DamageNotify events each time damage occurs nuclear@6: which is not included in the damage region. The nuclear@6: reported rectangles include only the changes to that nuclear@6: area, not the raw damage data. nuclear@6: nuclear@6: DamageReportBoundingBox nuclear@6: nuclear@6: Delivers DamageNotify events each time the bounding nuclear@6: box enclosing the damage region increases in size. nuclear@6: The reported rectangle encloses the entire damage region, nuclear@6: not just the changes to that size. nuclear@6: nuclear@6: DamageReportNonEmpty nuclear@6: nuclear@6: Delivers a single DamageNotify event each time the nuclear@6: damage rectangle changes from empty to non-empty, and nuclear@6: also whenever the result of a DamageSubtract request nuclear@6: results in a non-empty region. nuclear@6: nuclear@6: 7. Events nuclear@6: nuclear@6: DamageNotify nuclear@6: nuclear@6: level: DamageReportLevel nuclear@6: drawable: Drawable nuclear@6: damage: DAMAGE nuclear@6: more: Bool nuclear@6: timestamp: Timestamp nuclear@6: area: Rectangle nuclear@6: drawable-geometry: Rectangle nuclear@6: nuclear@6: 'more' indicates whether there are subsequent damage events nuclear@6: being delivered immediately as part of a larger damage region nuclear@6: nuclear@6: 8. Extension Initialization nuclear@6: nuclear@6: The client must negotiate the version of the extension before executing nuclear@6: extension requests. Otherwise, the server will return BadRequest for any nuclear@6: operations other than QueryVersion. nuclear@6: nuclear@6: QueryVersion nuclear@6: nuclear@6: client-major-version: CARD32 nuclear@6: client-minor-version: CARD32 nuclear@6: nuclear@6: -> nuclear@6: nuclear@6: major-version: CARD32 nuclear@6: minor-version: CARD32 nuclear@6: nuclear@6: The client sends the highest supported version to the server and nuclear@6: the server sends the highest version it supports, but no higher than nuclear@6: the requested version. Major versions changes can introduce nuclear@6: incompatibilities in existing functionality, minor version nuclear@6: changes introduce only backward compatible changes. It is nuclear@6: the clients responsibility to ensure that the server supports nuclear@6: a version which is compatible with its expectations. Servers nuclear@6: are encouraged to support multiple versions of the extension. nuclear@6: nuclear@6: 9. Enable Monitoring nuclear@6: nuclear@6: DamageCreate nuclear@6: nuclear@6: damage: DAMAGE nuclear@6: drawable: Drawable nuclear@6: level: DamageReportLevel nuclear@6: nuclear@6: Creates a damage object to monitor changes to Drawable nuclear@6: nuclear@6: DamageDestroy nuclear@6: damage: DAMAGE nuclear@6: nuclear@6: Destroys damage. nuclear@6: nuclear@6: DamageSubtract nuclear@6: nuclear@6: damage: DAMAGE nuclear@6: repair: Region or None nuclear@6: parts: Region or None nuclear@6: nuclear@6: Synchronously modifies the regions in the following manner: nuclear@6: nuclear@6: If repair is None: nuclear@6: nuclear@6: 1) if parts is not None, parts = damage nuclear@6: 2) damage = nuclear@6: nuclear@6: Otherwise: nuclear@6: nuclear@6: 1) tmp = damage INTERSECT repair nuclear@6: 2) damage = damage - tmp nuclear@6: 3) if parts is not None, parts = tmp nuclear@6: 4) Generate DamageNotify for remaining damage areas nuclear@6: nuclear@6: DamageAdd nuclear@6: nuclear@6: drawable: Drawable nuclear@6: region: Region nuclear@6: nuclear@6: Reports damage of the region within the given drawable. This may be nuclear@6: used by direct rendering clients to report damage that the server would nuclear@6: otherwise be unaware of. The damage region is relative to the origin nuclear@6: of the drawable. nuclear@6: nuclear@6: Damage posted in this way will appear in DamageNotify events as normal, nuclear@6: and also in server internal damage tracking (for shadow framebuffer nuclear@6: updates, pixmap damage, and other uses).