• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    KHR_partial_update
4
5Name Strings
6
7    EGL_KHR_partial_update
8
9Contributors
10
11    Ray Smith
12    Tom Cooksey
13    James Jones
14    Chad Versace
15    Jesse Hall
16
17Contact
18
19    Ray Smith, ARM (Raymond.Smith 'at' arm.com)
20
21IP Status
22
23    No known claims.
24
25Notice
26
27    Copyright (c) 2014 The Khronos Group Inc. Copyright terms at
28        http://www.khronos.org/registry/speccopyright.html
29
30Status
31
32    Complete.
33    Approved by the EGL Working Group on September 17, 2014.
34    Approved by the Khronos Board of Promoters on November 7, 2014.
35
36Version
37
38    Version 12, September 12, 2014
39
40Number
41
42    EGL Extension #83
43
44Extension Type
45
46    EGL display extension
47
48Dependencies
49
50    EGL 1.4 or later is required.
51
52    Written based on the EGL 1.5 specification (March 12, 2014).
53
54    The behavior of part of this extension is different depending on whether the
55    EGL_EXT_buffer_age extension is also present.
56
57    This extension trivially interacts with EGL_KHR_swap_buffers_with_damage and
58    EGL_EXT_swap_buffers_with_damage. This extension is worded against the KHR
59    version, but the interactions with the EXT version are identical.
60
61New Procedures and Functions
62
63
64    EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy,
65                                     EGLSurface surface,
66                                     EGLint *rects,
67                                     EGLint n_rects);
68
69New Tokens
70
71    Accepted in the <attribute> parameter of eglQuerySurface:
72
73        EGL_BUFFER_AGE_KHR           0x313D
74
75Overview
76
77    The aim of this extension is to allow efficient partial updates for postable
78    surfaces. It allows implementations to completely avoid processing areas of
79    the surface which have not changed between frames, allowing increased
80    efficiency.
81
82    It does so by providing information and guarantees about the content of the
83    current back buffer which allow the application to "repair" only areas that
84    have become out of date since the particular back buffer was last used.
85
86    The information provided is in the form of the "age" of the buffer, that is,
87    how many frames ago it was last used as the back buffer for the surface. If
88    the application tracks what changes it has made to the surface since this
89    back buffer was last used, it can bring the entire back buffer up to date by
90    only re-rendering the areas it knows to be out of date.
91
92    Use of this extension provides a more efficient alternative to
93    EGL_BUFFER_PRESERVED swap behaviour. EGL_BUFFER_PRESERVED typically implies
94    an expensive full-frame copy at the beginning of the frame, as well as a
95    dependency on the previous frame. Usage of this extension avoids both and
96    requires only the necessary updates to a back buffer to be made.
97
98Terminology
99
100    This extension and the EGL_KHR_swap_buffers_with_damage extension both use
101    the word "damage" for subtly but significantly different purposes:
102
103    "Surface damage" is what the EGL_KHR_swap_buffers_with_damage extension
104    is concerned with. This is the area of the *surface* that changes between
105    frames for that surface. It concerns the differences between two buffers -
106    the current back buffer and the current front buffer. It is useful only to
107    the consumer.
108
109    "Buffer damage" is what the EGL_KHR_partial_update extension is concerned
110    with. This is the area of a particular buffer that has changed since that
111    same buffer was last used. As it only concerns changes to a single buffer,
112    there is no dependency on the next or previous frames or any other buffer.
113    It therefore cannot be used to infer anything about changes to the surface,
114    which requires linking one frame or buffer to another. Buffer damage is
115    therefore only useful to the producer.
116
117    Following are examples of the two different damage types. Note that the
118    final surface content is the same in both cases, but the damaged areas
119    differ according to the type of damage being discussed.
120
121Surface damage example (EGL_KHR_swap_buffers_with_damage)
122
123    The surface damage for frame n is the difference between frame n and frame
124    (n-1), and represents the area that a compositor must recompose.
125
126      Frame 0     Frame 1     Frame 2     Frame 3     Frame 4
127    +---------+ +---------+ +---------+ +---------+ +---------+
128    |         | |#########| |#########| |#########| |#########|
129    |         | |         | |#########| |#########| |#########| Final surface
130    |         | |         | |         | |#########| |#########|   content
131    |         | |         | |         | |         | |#########|
132    +---------+ +---------+ +---------+ +---------+ +---------+
133
134    +---------+ +---------+ +---------+ +---------+ +---------+
135    |@@@@@@@@@| |@@@@@@@@@| |         | |         | |         |
136    |@@@@@@@@@| |         | |@@@@@@@@@| |         | |         | Surface damage
137    |@@@@@@@@@| |         | |         | |@@@@@@@@@| |         |
138    |@@@@@@@@@| |         | |         | |         | |@@@@@@@@@|
139    +---------+ +---------+ +---------+ +---------+ +---------+
140
141Buffer damage example (EGL_KHR_partial_update)
142
143    The buffer damage for a frame is the area changed since that same buffer was
144    last used. If the buffer has not been used before, the buffer damage is the
145    entire area of the buffer.
146
147    The buffer marked with an 'X' in the top left corner is the buffer that is
148    being used for that frame. This is the buffer to which the buffer age and
149    the buffer damage relate.
150
151    Note that this example shows a double buffered surface - the actual number
152    of buffers could be different and variable throughout the lifetime of the
153    surface. The age *must* therefore be queried for every frame.
154
155      Frame 0     Frame 1     Frame 2     Frame 3     Frame 4
156    +---------+ +---------+ +---------+ +---------+ +---------+
157    |         | |#########| |#########| |#########| |#########|
158    |         | |         | |#########| |#########| |#########| Final surface
159    |         | |         | |         | |#########| |#########|   content
160    |         | |         | |         | |         | |#########|
161    +---------+ +---------+ +---------+ +---------+ +---------+
162
163    X---------+ +---------+ X---------+ +---------+ X---------+
164    |         | |         | |#########| |#########| |#########|
165    |         | |         | |#########| |#########| |#########| Buffer 1 content
166    |         | |         | |         | |         | |#########|
167    |         | |         | |         | |         | |#########|
168    +---------+ +---------+ +---------+ +---------+ +---------+
169
170                X---------+ +---------+ X---------+ +---------+
171                |#########| |#########| |#########| |#########|
172                |         | |         | |#########| |#########| Buffer 2 content
173                |         | |         | |#########| |#########|
174                |         | |         | |         | |         |
175                +---------+ +---------+ +---------+ +---------+
176
177         0           0           2           2           2      Buffer age
178
179    +---------+ +---------+ +---------+ +---------+ +---------+
180    |@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |         | |         |
181    |@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |         | Buffer damage
182    |@@@@@@@@@| |@@@@@@@@@| |         | |@@@@@@@@@| |@@@@@@@@@|
183    |@@@@@@@@@| |@@@@@@@@@| |         | |         | |@@@@@@@@@|
184    +---------+ +---------+ +---------+ +---------+ +---------+
185
186
187Add a new section entitled "Partial updates to postable surfaces" to section
1883.5:
189
190    The "damage region" defines the area of the buffer to which all rendering
191    commands must be restricted. It applies only for surfaces which can be
192    posted, as described in section 3.10, and only when the swap behavior is
193    EGL_BUFFER_DESTROYED.
194
195    The contents of the buffer outside of the damage region may always be relied
196    upon to contain the same content as the last time they were defined for the
197    current back buffer. See section 3.5.6 for how to query when the current
198    back buffer was last used, and therefore what those contents are.
199
200    If EGL_EXT_buffer_age is supported, the contents of the buffer inside the
201    damage region may also be relied upon to contain the same content as the
202    last time they were defined for the current back buffer. If
203    EGL_EXT_buffer_age is not supported, the contents of the buffer inside the
204    damage region are always undefined after calling eglSwapBuffers.
205
206    Setting the damage region appropriately can be used to efficiently update
207    only the necessary areas inbetween frames.
208
209    After posting the back buffer, the damage region is set to the full
210    dimensions of the surface. The damage region can only be changed by the
211    application before any client API commands that draw to the surface have
212    been made. After this, the damage region is frozen until the back buffer is
213    posted again.
214
215    Use the command
216        EGLBoolean eglSetDamageRegionKHR(
217                            EGLDisplay dpy,
218                            EGLSurface surface,
219                            EGLint *rects,
220                            EGLint n_rects)
221
222    to set the damage region.
223
224    The damage region for <surface> is set to the area described by <n_rects> and
225    <rects> if all of the following conditions are met:
226
227    * <surface> is the current draw surface of the calling thread
228    * <surface> is a postable surface
229    * There have been no client API commands which result with rendering to
230      <surface> since eglSwapBuffers was last called with <surface>, or since
231      <surface> was created in case eglSwapBuffers has not yet been called with
232      <surface>.
233    * The surface's swap behavior is EGL_BUFFER_DESTROYED
234
235    <n_rects> specifies the number of rectangles comprising the damage region.
236    <rects> is a pointer to a list of values describing the rectangles. The list
237    should consist of <n_rects> groups of four values, with each group
238    representing a single rectangle in surface coordinates in the form {x, y,
239    width, height}. Coordinates are specified relative to the lower left corner
240    of the surface. It is not necessary to avoid overlaps of the specified
241    rectangles. Rectangles that lie (partially) outside of the current surface
242    dimensions (as queryable via the EGL_WIDTH and EGL_HEIGHT attributes) will
243    be clamped to the current surface dimensions.
244
245    If <n_rects> is zero, <rects> is ignored and the damage region is set to the
246    full dimensions of the surface.
247
248    If <n_rects> is not zero but the rectangles in <rects> describe a region of
249    zero area after clamping, the damage region is set to the empty region.
250
251    If <rects> contains more than (4 * <n_rects>) values, the remaining values
252    are ignored. If <rects> contains fewer than (4 * <n_rects>) values, the
253    behavior is undefined, up to and including program termination.
254
255    At all times, any client API rendering which falls outside of the damage
256    region results in undefined framebuffer contents for the entire framebuffer.
257    It is the client's responsibility to ensure that rendering is confined to
258    the current damage area.
259
260    If any client API commands resulting in rendering to <surface> have been
261    issued since eglSwapBuffers was last called with <surface>, or since the
262    surface was created in case eglSwapBuffers has not yet been called on it,
263    attempting to set the damage region will result in undefined framebuffer
264    contents for the entire framebuffer.
265
266    Errors
267    ------
268    eglSetDamageRegionKHR returns EGL_FALSE on failure:
269    * If <surface> is not a postable surface, an EGL_BAD_MATCH error is
270      generated
271    * If <surface> is not the current draw surface for the calling thread, an
272      EGL_BAD_MATCH error is generated
273    * If the value of EGL_SWAP_BEHAVIOR for <surface> is not
274      EGL_BUFFER_DESTROYED, an EGL_BAD_MATCH error is generated
275    * If eglSetDamageRegionKHR has already been called on <surface> since the
276      most recent frame boundary, an EGL_BAD_ACCESS error is generated
277    * If the EGL_BUFFER_AGE_KHR attribute of <surface> has not been queried
278      since the most recent frame boundary, an EGL_BAD_ACCESS error is generated
279
280Add before the final paragraph in section 3.5.6 "Surface Attributes":
281
282    Querying EGL_BUFFER_AGE_KHR returns the age of the color contents of the
283    current back buffer as the number of frames elapsed since it was most
284    recently defined.  Under certain conditions described below, applications
285    can, in conjunction with the surface's damage region (see section 3.5.1),
286    use this age to safely rely on the contents of old back buffers to reduce
287    the amount of redrawing they do each frame.
288
289    To query the age of a surface, it must be the current draw surface for the
290    calling thread.
291
292        Function name
293        --------------------
294        eglSwapBuffers
295        eglSwapBuffersWithDamageKHR
296
297        Table 3.X, Frame Boundary Functions
298
299    Buffers' ages are initialized to 0 at buffer creation time. When a frame
300    boundary is reached, the following occurs before any exchanging or copying
301    of color buffers:
302
303        * The current back buffer's age is set to 1.
304        * Any other color buffers' ages are incremented by 1 if
305          their age was previously greater than 0.
306
307    For example, with a double buffered surface and an implementation that swaps
308    via buffer exchanges, the age would usually be 2. With a triple buffered
309    surface the age would usually be 3. An age of 1 usually means the previous
310    swap was implemented as a copy. An age of 0 means the buffer has only just
311    been initialized and the contents are undefined. Single buffered surfaces
312    have no frame boundaries and therefore always have an age of 0.
313
314    Where specified in terms of the current damage region (see section 3.5.6),
315    the relevant part of a buffer's content is considered defined when the
316    buffer's age is a value greater than 0.
317
318    Frame boundaries are the only events that can set a buffer's age to a
319    positive value. Once EGL_BUFFER_AGE_KHR has been queried then it can be
320    assumed that the age will remain valid until the next frame boundary. EGL
321    implementations are permitted, but not required, to reset the buffer age in
322    response to pixel ownership test changes for any pixels within the drawable,
323    or if new pixels are added to or removed from the drawable, i.e., the
324    drawable is resized. A reset of this nature does not affect the age of
325    content for pixels that pass the pixel ownership test before and after the
326    event that caused the reset.  In other words, applications can assume that
327    no event will invalidate the content of pixels that continuously pass the
328    pixel ownership test between when the buffer age was queried and the
329    following frame boundary.  It is up to applications to track pixel ownership
330    using data collected from relevant window system events, such as
331    configuration and expose events on the X11 platform.
332
333    EGL_BUFFER_AGE_KHR state is a property of the EGL surface that owns the
334    buffers and lives in the address space of the application.  That is, if an
335    EGL surface has been created from a native window or pixmap that may be
336    shared between processes, the buffer age is not guaranteed to be
337    synchronized across the processes. Binding and unbinding a surface to and
338    from one or more contexts in the same address space will not affect the ages
339    of any buffers in that surface.
340
341Add to the list of errors for eglQuerySurface at the end of section 3.5.6
342"Surface Attributes":
343
344    If <attribute> is EGL_BUFFER_AGE_KHR and <surface> is not the current draw
345    surface for the calling thread, an EGL_BAD_SURFACE error is generated.
346
347Add to the end of section 3.10.1.1 "Native Window Resizing":
348
349    If eglSetDamageRegionKHR has been called with anything other than zero for
350    <n_rects>, a surface resize will cause the damage region to become
351    undefined. This will effectively cause the entire framebuffer content to
352    become undefined until the next frame.
353
354Dependencies on EGL_KHR_swap_buffers_with_damage
355
356    If EGL_KHR_swap_buffers_with_damage is not supported, all references to
357    eglSwapBuffersWithDamageKHR are removed.
358
359Issues
360
361 1) What should happen if the client renders outside of the damage area?
362
363    RESOLVED: The entire framebuffer content will be undefined.
364
365    DISCUSSION: The definedness of different parts of the buffer varies across
366    implementations, making it hard to define, and providing any more specific
367    information may encourage improper and non-portable use of this extension.
368
369 2) How does this interact with EGL_EXT_buffer_age?
370
371    RESOLVED: The initial content of the damage area differs depending on
372    whether EGL_EXT_buffer_age is present or not, making this extension fully
373    backwards compatible with EGL_EXT_buffer_age, while not depending on it.
374
375 3) How does this interact with EGL_KHR_swap_buffers_with_damage?
376
377    RESOLVED: It does not interact materially with
378    EGL_KHR_swap_buffers_with_damage, except for the trivial interaction with
379    eglSwapBuffersWithDamageKHR being a frame boundary function if the extension
380    is also supported.
381
382    DISCUSSION: This extension only provides a way to efficiently update the
383    back buffer for a surface. It does not have any effect on the subsequent
384    posting of that buffer. For maximum efficiency, applications should use both
385    EGL_KHR_partial_update and EGL_KHR_swap_buffers_with_damage simultaneously.
386
387 4) How does this interact with EGL_BUFFER_PRESERVED?
388
389    RESOLVED: It is an error to call eglSetDamageRegionKHR with a surface with
390    EGL_BUFFER_PRESERVED swap behavior. However, it is not an error to query the
391    age of the buffer in this case.
392
393    DISCUSSION: A layered extension will be proposed to guarantee that the age
394    of a buffer is always 1 after the first frame for a surface. This will
395    provide similar (but not identical) semantics to EGL_BUFFER_PRESERVED for
396    applications that need it.
397
398 5) How does surface resizing affect the damage region?
399
400    RESOLVED: The damage region becomes undefined if a surface resize occurs
401    after it has been set to anything except the full buffer. Because rendering
402    outside the damage area results in undefined framebuffer contents, this
403    effectively means that the entire framebuffer content becomes undefined
404    until the next frame.
405
406 6) What happens if the damage region is set after any client rendering
407    commands?
408
409    OPTION 1: An error is returned. Detecting this condition is non-trivial in
410    some implementations.
411
412    OPTION 2: The entire framebuffer contents become undefined.
413
414    RESOLVED: Option 2.
415
416 7) Should the entire region be provided in advance of any rendering, or should
417    each region be supplied immediately before the rendering commands for that
418    region, and multiple regions can be defined per frame?
419
420    RESOLVED: The entire region must be provided in advance of any rendering.
421
422 8) What should be the behavior if eglSetDamageRegionKHR is called multiple
423    times before the first rendering command?
424
425    RESOLVED: This is an error. The entire region must be provided during a
426    single call, with no overwrite or modify behavior needed.
427
428 9) Is it allowed to set the damage region when the buffer age has not been
429    queried?
430
431    RESOLVED: This is an error.  This could only make sense when the damage
432    region is the entire buffer, which it is initially anyway. Otherwise the
433    undamaged area needs to be defined to an age that the application doesn't
434    know about. It's not clear that this would ever be useful to the
435    application, because it can't know at this point which areas it needs to
436    update.
437
43810) What is the behavior if, after clamping, the damage region is empty?
439
440    RESOLVED: The damage region is set to empty.
441
442
443Revision History
444
445    Version 1, 28/01/2014
446     - Initial draft
447    Version 2, 05/02/2014
448     - Removed clip behavior, replaced with undefined framebuffer contents if
449       client renders outside of given damage region
450     - Renamed to EGL_KHR_partial_update from EGL_KHR_frame_clip
451     - Added detailed parameter descriptions and error conditions
452     - Added dependency on GL_XXX_damage_region
453     - Defined interactions with EGL_EXT_buffer_age
454    Version 3, 04/03/2014
455     - Removed dependency on GL_XXX_damage_region
456     - Changed error on defining damage region after drawcalls to be undefined
457       rendering results instead
458     - Redefined interactions with EGL_EXT_buffer_age to allow both to exist
459    Version 4, 20/03/2014
460     - Modified language to allow use with EGLStream producer surfaces
461     - Clarified that surface must be the current *draw* surface
462     - Changed n_rects=0 behavior to set the damage region to the entire surface
463     - Clarified that rendering outside the damage region results in the entire
464       framebuffer becoming undefined
465    Version 5, 20/03/2014
466     - Updated to be based on EGL 1.5 spec
467    Version 6, 23/04/2014
468     -Added the pixel ownership logic from EGL_EXT_buffer_age
469     -Ported over the detailed description of buffer age from EGL_EXT_buffer_age
470     -Added a "New Functions" and "New Tokens" section.
471     -Added dependencies on EGL_EXT_swap_buffers_with_damage
472    Version 7, 20/05/2014
473     - Removing a couple of now-obsolete sentences
474     - An age of 1 *usually* means the previous swap was implemented as a copy.
475     - Reworded "For the purposes of buffer age tracking..." to reference the
476       conditions under which the different parts of the buffer are actually
477       defined, which depend on the damage region
478    Version 8, 20/05/2014
479     - Added issues list
480    Version 9, 12/08/2014
481     - Removed outdated modification to "Posting to a Window"
482     - Changed names and order of rects/n_rects to match
483       EGL_EXT_swap_buffers_with_damage
484     - Resolved issue 3 on EGL_EXT_swap_buffers_with_damage interactions
485     - Resolved issue 4 on EGL_BUFFER_PRESERVED swap behavior
486     - Resolved issue 5 on surface resize behavior
487     - Resolved issue 7 on multiple calls to eglSetDamageRegionKHR
488     - Added issue 8 and suggested resolution
489     - Added issue 9 and suggested resolution
490     - Added issue 10 and suggested resolution
491    Version 10, 19/08/2014
492     - Added section on terminology and damage types
493    Version 11, 10/09/2014
494     - Resolved outstanding issues
495    Version 12, 12/09/2014
496     - Added the restriction that you can only query the age of a surface while
497       it is the current draw surface.
498    Version 13, 18/09/2015
499     - Marked as a Display extension
500     - Changed remaining references to EGL_EXT_swap_buffers_with_damage to
501       EGL_KHR_swap_buffers_with_damage
502