<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - weston-subsurfaces does not render/display"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=72612#c4">Comment # 4</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - weston-subsurfaces does not render/display"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=72612">bug 72612</a>
              from <span class="vcard"><a class="email" href="mailto:neil@linux.intel.com" title="Neil Roberts <neil@linux.intel.com>"> <span class="fn">Neil Roberts</span></a>
</span></b>
        <pre>I think I understand what's going on here. I'm not really sure what to do about
it though. It looks like the bug is triggered by my Mesa patch to make it block
for the frame callback for SwapInterval(1) in get_back_bo instead of in
eglSwapBuffers:

<a href="http://cgit.freedesktop.org/mesa/mesa/commit/?id=25cc889004aad6d1cab9edd76db89">http://cgit.freedesktop.org/mesa/mesa/commit/?id=25cc889004aad6d1cab9edd76db89</a>

weston-subsurfaces creates 2 subsurfaces. One of them is a regular widget which
is drawn with cairo-glesv2. The other is custom EGL widget which renders a
triangle with GL calls. The triangle widget is set to use eglSwapInterval(0).
However, because the triangle widget is created using the toy toolkit, it
actually also gets a secret cairo surface which will also use EGL to draw. Both
of these cairo surfaces will be using eglSwapInterval(1) so they will install a
frame callback after each buffer swap.

When drawing window_flush in window.c is called to swap all of the buffers for
the sub-surfaces. It will first swap the secret cairo surface for the triangle
and then it will swap the other cairo surface. When Cairo tries to call swap
buffers it will first ‘acquire’ the GL context. Acquiring the context calls
eglMakeCurrent with whatever surface Cairo last used. After acquiring the
context it will then call eglMakeCurrent again with the actual surface that
it's going to swap.

The problem is that calling eglMakeCurrent also calls get_back_bo. That means
that when swapping the other cairo surface, it will also end up calling
eglMakeCurrent and thus get_back_bo for the hidden triangle surface. The hidden
triangle surface has a frame callback installed so get_back_bo will end up
blocking. The triangle surface is a synchronized subsurface so the frame
callback event is not going to be delivered until the parent surface also
commits. However, that is never going to happen because weston-subsurfaces
tries to swap the subsurfaces before it swaps the main surface so it just ends
up in a deadlock.

So there are three weird things going on here. Fixing any one of these would
make the problem go away:

1. The toy toolkit shouldn't be making a secret extra Cairo surface for the
triangle widget.

2. Cairo shouldn't be redundantly rebinding the old surface before switching to
a new one.

3. Mesa probably shouldn't be calling get_back_bo just because eglMakeCurrent
is called on a surface. (Although maybe there is a good reason for that, I
don't know).

But really if we fixed any of these then we'd still have a core problem that
Mesa can block indefinitely when synchronized subsurfaces are involved. I
suppose we had that problem before my patch as well, but it was just a bit
harder to trigger because you'd have to try to swap the subsurface twice before
swapping the parent surface.</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>