<html>
<head>
<base href="https://bugs.freedesktop.org/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Priority</th>
<td>medium
</td>
</tr>
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - Reporting damage in surface coordinates doesn't work with EGL"
href="https://bugs.freedesktop.org/show_bug.cgi?id=78190">78190</a>
</td>
</tr>
<tr>
<th>Assignee</th>
<td>wayland-bugs@lists.freedesktop.org
</td>
</tr>
<tr>
<th>Summary</th>
<td>Reporting damage in surface coordinates doesn't work with EGL
</td>
</tr>
<tr>
<th>Severity</th>
<td>major
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Reporter</th>
<td>jason@jlekstrand.net
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Component</th>
<td>wayland
</td>
</tr>
<tr>
<th>Product</th>
<td>Wayland
</td>
</tr></table>
<p>
<div>
<pre>Currently, the wl_surface protocol requires damage to be reported in surface
coordinates. However, since EGL is unaware of any buffer-to-surface
transformations that may have been applied through set_buffer_transform,
set_buffer_scale, or wl_viewport, it cannot report damage correctly. In short:
1) The EGL implementation has no way of knowing about buffer transformations.
2) The EGL implementation is responsible to call wl_surface.damage inside of
eglSwapBuffers. Because it doesn't know about buffer transformations, it can't
damage a rectangle the same size as the surface.
3) Mesa currently damages an area of INT32_MAX x INT32_MAX to deal with this.
However, in the version 1.0 of the specification, the surface size was always
the same as buffer size. Some EGL implementations (including older versions of
mesa) rely on this and only damage the buffer size. Therefore, damage is wrong
if the surface is rotated by 90 or 270 degrees.
4) Clients have no way to determine if the EGL stack they are using does max
damage or simply damages the buffer area. Therefore, they cannot assume that
the EGL implementation will do the right thing. (Especially since this used to
be perfectly Ok.) This also means that they can't detect whether or not
surface transformations are useable.
It turns out that damage isn't an issue in the case where we have an integer
buffer_scale or a transform that's a multiple of 180 degress. This is because,
in these cases, the buffer size is at least as large as the surface size and
damaging bigger isn't a problem. Using wl_viewport to scale up a surface,
however, does coause a problem.
As far as I see it, this leaves us with four options:
1) Clients call wl_surface.damage manually right before eglSwapBuffers. The
surface would always get damaged by eglSwapBuffers as well. While the surface
would probably get over-damaged, it would at least ensure enough damage.
2) We add an EGL extension for every type of surface transformation.
3) We say that any EGL implementation that does not damage an area of INT32_MAX
x INT32_MAX is broken and hope they change.
4) We change the protocol so damage is in buffer coordinates.
Option 1 breaks the whole idea of eglSwapBuffers and hiding stuff inside of
EGLSurface and is really messy. Option 2 is bad because we don't want to wait
on EGL implementations before clients can use new protocol bits.
In my initial discussions with Kristian on IRC, he was a much bigger fan of 3
and trying to hack around things in clients. Initially, we thought that we
could just avoid 90 and 270 degree rotations unless we have
EGL_EXT_swap_buffers_with_damage. The idea was that
eglSwapBuffersWithDamageEXT would simply pass the damage rectangles through to
the compositor so it is then up to the client to hand it the right damage and
buffer transforms would then be 100% ok.
Unfortunately, EGL_EXT_swap_buffers_with_damage is even more broken than
eglSwapBuffers in some sense. When the EGL_EXT_swap_buffers_with_damage
extension was written the authors, trying to stay consistent with the rest of
OpenGL, chose to make the coordinates of the damage rectangles relative to the
lower-left corner of the surface rather than the upper-left. This means that
the EGL implementation has to vertically flip all of the damage rectangles.
Normally this is a trivial operation. However, if the EGL implementation does
not know the proper height of the surface, the computed rectangles will be
wrong. This means that, not only is eglSwapBuffers broken, but
eglSwapBuffersWithDamage is broken even worse.
Unless we start re-writing EGL extensions, I think we're stuck with option 4.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are the assignee for the bug.</li>
</ul>
</body>
</html>