wl_surface.attach with NULL wl_buffer behaviour

Prabhu S prabhusundar at gmail.com
Wed Sep 2 11:38:50 PDT 2015


With the below change in simple-shm.c, weston+fbdev backend will be stuck
and other compositors may work. It depends on compositor implementation and
the actual behavior supposed to be is not clearly defined. I'm still trying
to identify fix in weston, it looks like state information is overwritten
before idle_repaint is being called.

    window->callback = wl_surface_frame(window->surface);
    wl_callback_add_listener(window->callback, &frame_listener, window);
    wl_surface_commit(window->surface);

   + wl_surface_attach(window->surface, 0, 0, 0);
    +wl_surface_damage(window->surface,
              0, 0, 0, 0);
   + wl_surface_commit(window->surface);

But the cause is wl_buffer set to null from the client and as per
discussions it is not recommended. So we are trying to get this issue fixed
in the QTWayland plugin.
https://bugreports.qt.io/browse/QTBUG-47902

Some proposal to hide the surface would be greatly appreciated.
Below the discussion in the thread.

"I did a quick check on gtk+ and it seems that in:
gdk_wayland_window_hide_surface (GdkWindow *window)
they actually destroy* the surface ... which sounds wrong as well?

I tried to dig into EFL code as well .. but gave up due to not finding the
implementation of efl_gfx_visible_set (if someone can either point to that
or find the actual function to look at, that would be nice)"


On Mon, Aug 24, 2015 at 4:35 AM, Pekka Paalanen <ppaalanen at gmail.com> wrote:

> On Fri, 21 Aug 2015 19:04:11 -0500
> Prabhu S <prabhusundar at gmail.com> wrote:
>
> > Below is the case where I'm getting stuck with the actual test case.
> > Wondering why there is no callback wl_callback at 25.done or
> > wl_buffer at 29.release
> > The EGL implementation depends on these callback/buffer release.
>
> You will not get wl_callback at 25.done, because the NULL wl_buffer has
> overwritten the other wl_buffer, leaving the wl_surface without any
> content, which makes it disappear from screen. Frame callbacks are not
> intended to be posted for non-visible wl_surfaces.
>
> You should get wl_buffer at 29.release though. I bet you actually do get
> it, but something else is stopping the incoming Wayland events from
> being dispatched. See:
> http://lists.freedesktop.org/archives/wayland-devel/2014-April/014121.html
> and "protocol dumpers" on:
> http://wayland.freedesktop.org/extras.html
>
> My wild guess would be that something is blocking, waiting on the frame
> callback, likely EGL. It's not really EGL's bug but the application's
> (or Qt).
>
> > Also noticed if the valid buffer is attached immediately after null
> buffer,
> > everything is fine, so most of the time it is unnoticed. If the frame is
>
> Hmm, no, things should not be fine in that case. Well, it depends on
> what role the wl_surface you are committing on has, but the very least
> it may cause flicker.
>
> You definetely want to get rid of that null attach. You do not want to
> just ignore it.
>
> > complex, egl will attach after null frame.
> >
>
> It sounds like your application is committing to the wl_surface behind
> Qt's back somehow, and it only works occasionally by luck.
>
> > I will keep debug if any other race conditions in my implementation.
> >
> > [3741557.293]  -> wl_surface at 20.frame(new id wl_callback at 25)
> > [3741557.476]  -> wl_surface at 20.attach(wl_buffer at 29, 0, 0)
> > [3741557.676]  -> wl_surface at 20.damage(0, 0, 800, 480)
> > [3741557.906]  -> wl_surface at 20.commit() <=EGL
> > [3741558.500]  -> wl_surface at 20.attach(nil, 0, 0) <=QTWayland
> > [3741558.604]  -> wl_surface at 20.commit() <=QTWayland
> > stuck
> >
> >
> > On Fri, Aug 21, 2015 at 12:16 PM, Jasper St. Pierre <
> jstpierre at mecheye.net>
> > wrote:
>
> ...
>
> > > However crazy it is, the logic sort of makes sense -- the "frame"
> > > event is guaranteed to be called once a frame when the surface content
> > > is painted and shown on the screen. When there's no surface content,
> > > it isn't painted, so the frame event isn't called.
> > >
> > > I'm not sure what you mean about a buffer release event -- you never
> > > attached a buffer to begin with, so I can't imagine how you'll get an
> > > event on it.
> > >
> > > On Fri, Aug 21, 2015 at 10:03 AM, Prabhu S <prabhusundar at gmail.com>
> wrote:
> > > > Hi,
> > > > Based on the wayland protocol specification for wl_surface::attach
> > > >>>If wl_surface.attach is sent with a NULL wl_buffer, the following
> > > >>> wl_surface.commit will remove the surface content.
> > > >
> > > > Wondering if wl_surface_attach called with wl_buffer=NULL, will
> there be
> > > any
> > > > wl_buffer release event or frame callbacks?
> > > >
> > > > Modified the redraw in simple-shm.c as below and not receiving any
> > > callback
> > > > or buffer release. It just got stuck.
> > > > The same thing is being done in qtwayland to hide the surface and it
> is
> > > > getting stuck. Some help to check this case would be helpful.
> > > >
> > > > static int odd = 1;
> > > > if(odd == 1){
> > > >         wl_surface_attach(window->surface, buffer->buffer, 0, 0);
> > > >         wl_surface_damage(window->surface,
> > > >                           20, 20, window->width - 40, window->height
> -
> > > 40);
> > > >         odd = 0;
> > > >     }
> > > >     else{
> > > >             wl_surface_attach(window->surface, 0, 0, 0);
> > > >             wl_surface_damage(window->surface,
> > > >                           0, 0, 0, 0);
> > > >             odd=1;
> > > >     }
> > > >
> > > >
> > > >
> > > > [823379.816]  -> wl_compositor at 4.create_surface(new id wl_surface at 3)
> > > > [823379.949]  -> xdg_shell at 6.get_xdg_surface(new id xdg_surface at 7,
> > > > wl_surface at 3)
> > > > [823380.120]  -> xdg_surface at 7.set_title("simple-shm")
> > > > [823380.244]  -> wl_surface at 3.damage(0, 0, 250, 250)
> > > > [823381.333]  -> wl_shm at 5.create_pool(new id wl_shm_pool at 8, fd 5,
> > > 250000)
> > > > [823381.561]  -> wl_shm_pool at 8.create_buffer(new id wl_buffer at 9, 0,
> 250,
> > > > 250, 1000, 1)
> > > > [823381.870]  -> wl_shm_pool at 8.destroy()
> > > > [823384.880]  -> wl_surface at 3.attach(wl_buffer at 9, 0, 0)
> > > > [823385.095]  -> wl_surface at 3.damage(20, 20, 210, 210)
> > > > [823385.317]  -> wl_surface at 3.frame(new id wl_callback at 10)
> > > > [823385.443]  -> wl_surface at 3.commit()
> > > > [823388.852] wl_display at 1.delete_id(8)
> > > > [823388.979] xdg_surface at 7.configure(0, 0, array, 4)
> > > > [823389.238]  -> xdg_surface at 7.ack_configure(4)
> > > > [823401.773] wl_display at 1.delete_id(10)
> > > > [823401.908] wl_buffer at 9.release()
>
> This is the buffer release you expected. Note, that release can come
> before the next buffer is attached, like here. This is typical for a
> compositor using GL while the client is using software rendering
> (wl_shm). Things can differ if the client is using GL or if the
> compositor is not using GL.
>
> > > > [823401.991] wl_callback at 10.done(4056537)
> > > > [823404.239]  -> wl_surface at 3.attach(nil, 0, 0)
> > > > [823404.442]  -> wl_surface at 3.damage(0, 0, 0, 0)
> > > > [823404.663]  -> wl_surface at 3.frame(new id wl_callback at 10)
> > > > [823404.792]  -> wl_surface at 3.commit()
> > > > [823406.292] xdg_surface at 7.configure(0, 0, array, 5)
> > > > [823406.524]  -> xdg_surface at 7.ack_configure(5)
>
> Just like Jasper explained, wl_callback at 10 will not be signalled until
> the surface is composited the next time. Without a wl_buffer, it won't
> get composited. The spec for wl_surface.frame says:
>
>         "A server should avoid signalling the frame callbacks if the
>         surface is not visible in any way"
>
> Committing a NULL wl_buffer causes the wl_surface to be not visible.
>
>
> Thanks,
> pq
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20150902/dc001bc7/attachment-0001.html>


More information about the wayland-devel mailing list