• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    KHR_swap_buffers_with_damage
4
5Name Strings
6
7    EGL_KHR_swap_buffers_with_damage
8
9Contributors
10
11    Robert Bragg
12    Tapani Pälli
13    Kristian Høgsberg
14    Benjamin Franzke
15    Ian Stewart
16    James Jones
17    Ray Smith
18
19Contact
20
21    Robert Bragg, Intel (robert.bragg 'at' intel.com)
22
23IP Status
24
25    No known claims.
26
27Notice
28
29    Copyright (c) 2014 The Khronos Group Inc. Copyright terms at
30        http://www.khronos.org/registry/speccopyright.html
31
32Status
33
34    Complete.
35    Approved by the EGL Working Group on September 17, 2014.
36    Approved by the Khronos Board of Promoters on November 7, 2014.
37
38Version
39
40    Version 13, February 20, 2020
41
42Number
43
44    EGL Extension #84
45
46Extension Type
47
48    EGL display extension
49
50Dependencies
51
52    Requires EGL 1.4
53
54    This extension is written against the wording of the EGL 1.4
55    Specification.
56
57Overview
58
59    This extension provides a means to issue a swap buffers request to
60    display the contents of the current back buffer and also specify a
61    list of damage rectangles that can be passed to a system
62    compositor so it can minimize how much it has to recompose.
63
64    This should be used in situations where an application is only
65    animating a small portion of a surface since it enables the
66    compositor to avoid wasting time recomposing parts of the surface
67    that haven't changed.
68
69Terminology
70
71    This extension and the EGL_KHR_partial_update extension both use the word
72    "damage" for subtly but significantly different purposes:
73
74    "Surface damage" is what the EGL_KHR_swap_buffers_with_damage extension
75    is concerned with. This is the area of the *surface* that changes between
76    frames for that surface. It concerns the differences between two buffers -
77    the current back buffer and the current front buffer. It is useful only to
78    the consumer.
79
80    "Buffer damage" is what the EGL_KHR_partial_update extension is concerned
81    with. This is the area of a particular buffer that has changed since that
82    same buffer was last used. As it only concerns changes to a single buffer,
83    there is no dependency on the next or previous frames or any other buffer.
84    It therefore cannot be used to infer anything about changes to the surface,
85    which requires linking one frame or buffer to another. Buffer damage is
86    therefore only useful to the producer.
87
88    Following are examples of the two different damage types. Note that the
89    final surface content is the same in both cases, but the damaged areas
90    differ according to the type of damage being discussed.
91
92Surface damage example (EGL_KHR_swap_buffers_with_damage)
93
94    The surface damage for frame n is the difference between frame n and frame
95    (n-1), and represents the area that a compositor must recompose.
96
97      Frame 0     Frame 1     Frame 2     Frame 3     Frame 4
98    +---------+ +---------+ +---------+ +---------+ +---------+
99    |         | |#########| |#########| |#########| |#########|
100    |         | |         | |#########| |#########| |#########| Final surface
101    |         | |         | |         | |#########| |#########|   content
102    |         | |         | |         | |         | |#########|
103    +---------+ +---------+ +---------+ +---------+ +---------+
104
105    +---------+ +---------+ +---------+ +---------+ +---------+
106    |@@@@@@@@@| |@@@@@@@@@| |         | |         | |         |
107    |@@@@@@@@@| |         | |@@@@@@@@@| |         | |         | Surface damage
108    |@@@@@@@@@| |         | |         | |@@@@@@@@@| |         |
109    |@@@@@@@@@| |         | |         | |         | |@@@@@@@@@|
110    +---------+ +---------+ +---------+ +---------+ +---------+
111
112Buffer damage example (EGL_KHR_partial_update)
113
114    The buffer damage for a frame is the area changed since that same buffer was
115    last used. If the buffer has not been used before, the buffer damage is the
116    entire area of the buffer.
117
118    The buffer marked with an 'X' in the top left corner is the buffer that is
119    being used for that frame. This is the buffer to which the buffer age and
120    the buffer damage relate.
121
122    Note that this example shows a double buffered surface - the actual number
123    of buffers could be different and variable throughout the lifetime of the
124    surface. The age *must* therefore be queried for every frame.
125
126      Frame 0     Frame 1     Frame 2     Frame 3     Frame 4
127    +---------+ +---------+ +---------+ +---------+ +---------+
128    |         | |#########| |#########| |#########| |#########|
129    |         | |         | |#########| |#########| |#########| Final surface
130    |         | |         | |         | |#########| |#########|   content
131    |         | |         | |         | |         | |#########|
132    +---------+ +---------+ +---------+ +---------+ +---------+
133
134    X---------+ +---------+ X---------+ +---------+ X---------+
135    |         | |         | |#########| |#########| |#########|
136    |         | |         | |#########| |#########| |#########| Buffer 1 content
137    |         | |         | |         | |         | |#########|
138    |         | |         | |         | |         | |#########|
139    +---------+ +---------+ +---------+ +---------+ +---------+
140
141                X---------+ +---------+ X---------+ +---------+
142                |#########| |#########| |#########| |#########|
143                |         | |         | |#########| |#########| Buffer 2 content
144                |         | |         | |#########| |#########|
145                |         | |         | |         | |         |
146                +---------+ +---------+ +---------+ +---------+
147
148         0           0           2           2           2      Buffer age
149
150    +---------+ +---------+ +---------+ +---------+ +---------+
151    |@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |         | |         |
152    |@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |@@@@@@@@@| |         | Buffer damage
153    |@@@@@@@@@| |@@@@@@@@@| |         | |@@@@@@@@@| |@@@@@@@@@|
154    |@@@@@@@@@| |@@@@@@@@@| |         | |         | |@@@@@@@@@|
155    +---------+ +---------+ +---------+ +---------+ +---------+
156
157
158New Procedures and Functions
159
160    EGLBoolean eglSwapBuffersWithDamageKHR (
161        EGLDisplay dpy,
162        EGLSurface surface,
163        const EGLint *rects,
164        EGLint n_rects);
165
166New Tokens
167
168    None
169
170Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
171
172    Add the following text to subsection 3.9.1 titled "Posting to a
173    Window" after the description of eglSwapBuffers.
174
175        As an alternative to eglSwapBuffers use:
176
177        EGLBoolean eglSwapBuffersWithDamageKHR (
178            EGLDisplay dpy,
179            EGLSurface surface,
180            const EGLint *rects,
181            EGLint n_rects);
182
183        to do the same thing as eglSwapBuffers but additionally report
184        a list of rectangles that define the region that has truly
185        changed since the last frame. To be clear; the entire contents
186        of the back buffer will still be swapped to the front so
187        applications using this API must still ensure that the entire
188        back buffer is consistent. The rectangles are only a hint for
189        the system compositor so it can avoid recomposing parts of the
190        surface that haven't really changed.
191            <rects> points to a list of integers in groups of four that
192        each describe a rectangle in screen coordinates in this
193        layout: {x, y, width, height}. The rectangles are specified
194        relative to the bottom-left of the surface and the x and y
195        components of each rectangle specify the bottom-left position
196        of that rectangle. <n_rects> determines how many groups of 4
197        integers can be read from <rects>.  It is not necessary to
198        avoid overlaps of the specified rectangles.
199            If <n_rects> is 0 then <rects> is ignored and the entire
200        surface is implicitly damaged and the behaviour is equivalent
201        to calling eglSwapBuffers.
202            The error conditions checked for are the same as for the
203        eglSwapBuffers api.
204
205    Modify the first paragraph of Section 3.9.1 titled "Native Window
206    Resizing"
207
208        "If the native window corresponding to <surface> has been
209        resized prior to the swap, <surface> must be resized to match.
210        <surface> will normally be resized by the EGL implementation
211        at the time the native window is resized. If the
212        implementation cannot do this transparently to the client,
213        then eglSwapBuffers and eglSwapBuffersWithDamageKHR must
214        detect the change and resize surface prior to copying its
215        pixels to the native window. In this case the meaningfulness
216        of any damage rectangles forwarded by
217        eglSwapBuffersWithDamageKHR to the native window system is
218        undefined."
219
220    Modify the following sentences in Section 3.9.3, page 51 (Posting
221    Semantics)
222
223    Paragraph 2, first sentence:
224
225        "If <dpy> and <surface> are the display and surface for the
226        calling thread's current context, eglSwapBuffers,
227        eglSwapBuffersWithDamageKHR, and eglCopyBuffers perform an
228        implicit flush operation on the context (glFlush for OpenGL or
229        OpenGL ES context, vgFlush for an OpenVG context)."
230
231    Paragraph 3, first sentence:
232
233        "The destination of a posting operation (a visible window, for
234        eglSwapBuffers or eglSwapBuffersWithDamageKHR, or a native
235        pixmap, for eglCopyBuffers) should have the same number of
236        components and component sizes as the color buffer it's being
237        copied from."
238
239    Paragraph 6, first two sentences:
240
241        "The function
242
243            EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint
244                interval);
245
246        specifies the minimum number of video frame periods per color
247        buffer post operation for the window associated with the
248        current context. The interval takes effect when eglSwapBuffers
249        or eglSwapBuffersWithDamageKHR is first called subsequent to
250        the eglSwapInterval call."
251
252    Modify the following sentences in Section 3.9.4, page 52 (Posting
253    Errors)
254
255    Paragraph 1, first sentence:
256
257        "eglSwapBuffers, eglSwapBuffersWithDamageKHR, and
258        eglCopyBuffers return EGL_FALSE on failure."
259
260    Paragraph 1, seventh sentence:
261
262        "If eglSwapBuffers or eglSwapBuffersWithDamageKHR are called
263        and the native window associated with <surface> is no longer
264        valid, an EGL_BAD_NATIVE_WINDOW error is generated.  If
265        eglSwapBuffersWithDamageKHR is called and <n_rects>, is less
266        than zero or <n_rects> is greater than zero but <rects> is
267        NULL, EGL_BAD_PARAMETER is generated."
268
269Dependencies on OpenGL ES
270
271    None
272
273Dependencies on OpenVG
274
275    None
276
277Issues
278
2791)  Do applications have to make sure the rectangles don't overlap?
280
281    RESOLVED: No, that would be inconvenient for applications and we
282    see no difficulty for implementations to supporting overlapping
283    rectangles.
284
2852)  Would it be valid for an implementation to discard the list of
286    rectangles internally and work just in terms of the
287    eglSwapBuffers api?
288
289    RESOLVED: Yes, the rectangles are only there for optimization
290    purposes so although it wouldn't be beneficial to applications if
291    it was convenient at times then it would be compliant for an
292    implementation to discard the rectangles and just call
293    eglSwapBuffers instead. The error conditions that should be
294    checked for are compatible with the requirements for
295    eglSwapBuffers.
296
2973)  What origin should be used for damage rectangles?
298
299    RESOLVED: Bottom left since this is consistent with all other
300    uses of 2D window coordinates in EGL and OpenGL that specify a
301    bottom left origin.
302
303    Originally this specification was written with a top-left origin
304    for the damage rectangles even though it was known to be
305    inconsistent and that was because most window systems use a
306    top-left origin and there are some awkward semantic details
307    related to handling native window resizing that we had hoped to
308    simplify.
309
310    This extension and also several other existing EGL extensions
311    struggle to guarantee a reliable behaviour in response to native
312    window resizing which can happen asynchronously on some platforms
313    and this can make it difficult for applications to avoid certain
314    visual artefacts.
315
316    The crux of the problem is that when a native window is
317    asynchronously resized then the window system may maintain the old
318    buffer contents with respect to a different origin than EGL's
319    bottom left origin. For this extension that means that EGL damage
320    rectangles that are intended to map to specific surface contents
321    may end up mapping to different contents when a native window is
322    resized because the rectangles and buffer contents will be moved in
323    different directions in relation to the new window size.
324
325    In the end we decided that this issue isn't simply solved by
326    choosing to use a top-left origin and so we can instead aim for
327    consistency and clarify what guarantees we offer in relation to
328    native window resizing separate from this issue.
329
3304)  What guarantees do we provide about the meaningfulness of EGL
331    damage rectangles that are forwarded to the native window system
332    when presenting to a native window that has been resized?
333
334    RESOLVED: The meaningfulness of those forwarded damage rectangles
335    is undefined since this simplifies the implementation requirements
336    and we saw very little benefit to applications from providing
337    stricter guarantees.
338
339    The number of applications that would be able to avoid fully
340    redrawing the contents of a window in response to a window resize
341    is expected to be so low that there would be almost no benefit to
342    defining strict guarantees here.
343
344    Since EGL already states that the contents of window surface
345    buffers become undefined when a native window has been resized,
346    this limitation doesn't introduce any new issue for applications
347    to consider. Applications should already fully redraw buffer
348    contents in response to a native window resize, unless they are
349    following some platform specific documentation that provides
350    additional guarantees.
351
352    For an example of the implementation details that make this an
353    awkward issue to provide guarantees for we can consider X11 based
354    platforms where native windows can be resized asynchronously with
355    respect to a client side EGL surface:
356
357    With X11 there may be multiple "gravity" transformations that can
358    affect how surface buffer content is positioned with respect to a
359    new native window size; there is the core X "bit gravity" and
360    there is the EGL driver gravity that determines how a surface's
361    contents with one size should be mapped to a native window with a
362    different size.  Without very careful cooperation between the EGL
363    driver and the core X implementation and without the right
364    architecture to be able to do transforms atomically with respect
365    to different clients that may enact a window resize then it is not
366    possible to reliably map EGL damage rectangles to native window
367    coordinates.
368
369    The disadvantage of a driver that is not able to reliably map EGL
370    damage rectangles to native window coordinates is that a native
371    compositor may re-compose the wrong region of window. This may
372    result in a temporary artefact until the full window gets redrawn
373    and then re-composed. X11 already suffers other similar transient
374    artefacts when resizing windows.
375
376    The authors of this spec believe that even if a driver can't do
377    reliable mappings of EGL damage rectangles then compositors would
378    be able mitigate the majority of related artefacts by ignoring
379    sub-window damage during an interactive window resize.
380
381    The authors of this spec believe that that if an X11 driver did
382    want to reliably map EGL damage rectangles to the native window
383    coordinates then that may be technically feasible depending on the
384    driver architecture. For reference one approach that had been
385    considered (but not tested) is as follows:
386
387      1) When eglSwapBuffersWithDamageKHR is called, send EGL damage
388      rectangles from the client to a driver component within the
389      xserver un-transformed in EGL window surface coordinates with a
390      bottom-left origin.
391
392      2) Within the X server the driver component should look at the
393      bit-gravity of a window and use the bit-gravity convention to
394      copy EGL surface content to the front-buffer of a native window.
395
396      3) Within the X server the driver component should use the same
397      gravity transform that was used to present the surface content
398      to also transform the EGL damage rectangle coordinates.
399
400      Note that because this transform is done in the xserver then
401      this is implicitly synchronized with all clients that would
402      otherwise be able to enact an asynchronous window resize.
403
404
405Revision History
406
407    Version 1, 29/07/2011
408      - First draft
409    Version 2, 03/08/2011
410      - Clarify that the rectangles passed may overlap
411    Version 3, 01/09/2011
412      - Fix a missing '*' in prototype to make rects a pointer
413    Version 4, 11,02,2012
414      - Clarify that implementing in terms of eglSwapBuffers would be
415        compliant.
416    Version 5, 11,02,2012
417      - Tweak the cases where we report BAD_PARAMETER errors
418    Version 6, 05/02/2013
419      - Specify more thorough updates across the EGL 1.4 spec
420        wherever it relates to the eglSwapBuffers api
421      - Clarify that passing <n_rects> of 0 behaves as if
422        eglSwapBuffers were called.
423    Version 7, 14/02/2013
424      - Specify that a bottom-left origin should be used for rectangles
425    Version 8, 19/03/2013
426      - Add Ian and James as contributors
427      - Add an issue explaining why we changed to a bottom-left origin
428      - Clarify that the behaviour is undefined when presenting to a
429        native window that has been resized.
430      - Document the awkward details that would be involved in
431        providing more strict guarantees when presenting to a native
432        window that has been resized.
433    Version 9, 12/06/2013, Chad Versace <chad.versace@intel.com>
434      - Remove the "all rights reserved" clause from the copyright notice. The
435        removal does not change the copyright notice's semantics, since the
436        clause is already implied by any unadorned copyright notice. But, the
437        removal does diminish the likelihood of unwarranted caution in readers
438        of the spec.
439      - Add "IP Status" section to explicitly state that this extension has no
440        knonw IP claims.
441    Version 10, 19/08/2014
442      - Draft for promoting to KHR
443      - Added section on terminology and damage types
444    Version 11, 10/09/2014
445      - Marked as display extension
446    Version 12, 11/05/2014
447      - Change copyright to Khronos after signoff from Intel.
448    Version 13, 20/02/2020, Jon Leech
449      - Constify rects parameter (EGL-Registry issue 98).
450