<div dir="auto"><div>Hi Pekka,</div><div dir="auto"><br></div><div dir="auto">Thanks for your reply. Yes, preferably if I can hide the map and unmap from client, in this case I cannot because it is part of a desktop shell. After I unmap it and remap the view next time, it is not expected the shell to continue from last draw. I would want the shell be drawing total different things instead. If I simply remap, I shall see the last frame that did get drawed.</div><div dir="auto"><br></div><div dir="auto">It can be seen as a problem in the application, designing smarter clients which is aware of such details, by not sending the last frame for example, but I found an easier solution by unmap the view in the `frame_signal`. It worked quite well.</div><div dir="auto"><br></div><div dir="auto">Regards,</div><div dir="auto">Sichem</div><div dir="auto"><br><br><div class="gmail_quote" dir="auto"><div dir="ltr">Le ven. 3 août 2018 07 h 49, Pekka Paalanen <<a href="mailto:ppaalanen@gmail.com" rel="noreferrer noreferrer" target="_blank">ppaalanen@gmail.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> On Sat, Jul 28, 2018 at 8:15 PM, Sichem Zhou <<a href="mailto:sichem.zh@gmail.com" rel="noreferrer noreferrer noreferrer" target="_blank">sichem.zh@gmail.com</a>> wrote:<br>
> <br>
> > Dear Weston devs:<br>
> ><br>
> > Sorry for the bothering in when weston-5.0 is approaching, but I am stuck<br>
> > in the project for three days I need some one's help very much.<br>
> ><br>
> > I have a widget implementation of shell widgets that destroys the<br>
> > weston_view<br>
> > when pressed Esc. The widget is implemented in wayland EGL. Here is the<br>
> > view_destroy code.<br>
> ><br>
> > void<br>
> > twshell_close_ui_surface(struct weston_surface *wd_surface)<br>
> > {<br>
> >         struct weston_view *view, *next;<br>
> >         wd_surface->committed = NULL;<br>
> >         wd_surface->committed_private = NULL;<br>
> >         wl_list_for_each_safe(view, next, &wd_surface->views,<br>
> > surface_link) {<br>
> >                 weston_view_destroy(view);<br>
> >         }<br>
> > }<br>
> ><br>
> > The weston_view is destroyed but the the buffer in the last commit was not<br>
> > released and the done event was not sent to the widget. When I triggered<br>
> > the event to show widget again, the client was stuck in EGLSwapbuffer. I<br>
> > found out about this by using WAYLAND_DEBUG env variable, I hope to the<br>
> > way to release the buffer after umapping the weston view. Thanks very much.<br>
<br>
Hi,<br>
<br>
destroying or unmapping a weston_view is not meant to release the<br>
wl_surface's buffer. If the compositor spontaneously chooses to hide a<br>
surface, it may also spontaneously choose to show it again. To show a<br>
surface, it must have content, so if the renderer needs the buffer<br>
around, hiding cannot release the buffer.<br>
<br>
Views are Weston internal objects, clients are completely unaware of<br>
them. However, clients are aware of the mappedness of a wl_surface<br>
(weston_surface). Clients issue protocol requests and assume a specific<br>
sequence will map the surface. A compositor must keep up that<br>
appearance, even if it was a lie internally. That is, if a compositor<br>
spontaneously unmaps the view, it will not make the surface unmapped.<br>
This is also why we have 'bool is_mapped' in both weston_surface and<br>
weston_view. The client still thinks the surface is mapped, so it will<br>
not even expect the buffer to be released.<br>
<br>
The only client-visible effect of unmapping all views is that the frame<br>
callbacks will pause. This does not mean that the surface is unmapped,<br>
it is just temporarily not visible. Frame callbacks are used to<br>
throttle clients so that they don't draw frames that will not be shown.<br>
<br>
If you don't forcefully release the buffer, re-creating the view should<br>
let your app continue as usual while Weston is showing the last frame<br>
it got.<br>
<br>
It is also intentional that frame callback 'done' events are only ever<br>
triggered from repaint. Repaint makes the frame visible. As long as the<br>
frame is not processed yet, 'done' should not be sent.<br>
<br>
'done' means that it is a good time for a continuously animating client<br>
to start drawing the next frame. It is an advisory throttling<br>
mechanism, and if your client really knows better, it can choose to<br>
draw new frames regardless.<br>
<br>
When you use EGL in a client, is it important to never let<br>
eglSwapBuffers() block for you. You need to track frame callbacks<br>
manually or set eglSwapInterval to zero, preferably both, so your<br>
application code does not get blocked by EGL API that was designed for<br>
applications far less smart than yours.<br>
<br>
<br>
On Sun, 29 Jul 2018 20:49:24 -0400<br>
Sichem Zhou <<a href="mailto:sichem.zh@gmail.com" rel="noreferrer noreferrer noreferrer" target="_blank">sichem.zh@gmail.com</a>> wrote:<br>
<br>
> I actually found the reason, in the function `weston_output_repaint`, the<br>
> frame_callbacks<br>
> only send the done events for surface which has view on the compositor's<br>
> view_list,<br>
> but this poses a dilemma, since I cannot either destroy or unmap the view<br>
> before the<br>
> output repainted.<br>
<br>
I don't see a problem on the compositor side. You can unmap or destroy<br>
the view, and the frame callbacks will stall until you re-map the view<br>
again. The last buffer will not get released while unmapped, because<br>
the compositor needs it on re-map. The pending frame callbacks will<br>
resume once the view is re-mapped.<br>
<br>
It sounds like your problem is in the app: do not let eglSwapBuffers()<br>
block on a frame callback. Create a frame callback just before you call<br>
eglSwapBuffers(), and do not call eglSwapBuffers() again until that<br>
frame callback has signalled. That way eglSwapBuffers should never<br>
block indefinitely. Additionally you can set eglSwapInterval to zero in<br>
case there are situations where you really need to eglSwapBuffers()<br>
before the frame callback has signalled.<br>
<br>
<br>
Thanks,<br>
pq<br>
</blockquote></div></div></div>