> On Sat, Jul 28, 2018 at 8:15 PM, Sichem Zhou <[email protected]> wrote: > > > Dear Weston devs: > > > > Sorry for the bothering in when weston-5.0 is approaching, but I am stuck > > in the project for three days I need some one's help very much. > > > > I have a widget implementation of shell widgets that destroys the > > weston_view > > when pressed Esc. The widget is implemented in wayland EGL. Here is the > > view_destroy code. > > > > void > > twshell_close_ui_surface(struct weston_surface *wd_surface) > > { > > struct weston_view *view, *next; > > wd_surface->committed = NULL; > > wd_surface->committed_private = NULL; > > wl_list_for_each_safe(view, next, &wd_surface->views, > > surface_link) { > > weston_view_destroy(view); > > } > > } > > > > The weston_view is destroyed but the the buffer in the last commit was not > > released and the done event was not sent to the widget. When I triggered > > the event to show widget again, the client was stuck in EGLSwapbuffer. I > > found out about this by using WAYLAND_DEBUG env variable, I hope to the > > way to release the buffer after umapping the weston view. Thanks very much.
Hi, destroying or unmapping a weston_view is not meant to release the wl_surface's buffer. If the compositor spontaneously chooses to hide a surface, it may also spontaneously choose to show it again. To show a surface, it must have content, so if the renderer needs the buffer around, hiding cannot release the buffer. Views are Weston internal objects, clients are completely unaware of them. However, clients are aware of the mappedness of a wl_surface (weston_surface). Clients issue protocol requests and assume a specific sequence will map the surface. A compositor must keep up that appearance, even if it was a lie internally. That is, if a compositor spontaneously unmaps the view, it will not make the surface unmapped. This is also why we have 'bool is_mapped' in both weston_surface and weston_view. The client still thinks the surface is mapped, so it will not even expect the buffer to be released. The only client-visible effect of unmapping all views is that the frame callbacks will pause. This does not mean that the surface is unmapped, it is just temporarily not visible. Frame callbacks are used to throttle clients so that they don't draw frames that will not be shown. If you don't forcefully release the buffer, re-creating the view should let your app continue as usual while Weston is showing the last frame it got. It is also intentional that frame callback 'done' events are only ever triggered from repaint. Repaint makes the frame visible. As long as the frame is not processed yet, 'done' should not be sent. 'done' means that it is a good time for a continuously animating client to start drawing the next frame. It is an advisory throttling mechanism, and if your client really knows better, it can choose to draw new frames regardless. When you use EGL in a client, is it important to never let eglSwapBuffers() block for you. You need to track frame callbacks manually or set eglSwapInterval to zero, preferably both, so your application code does not get blocked by EGL API that was designed for applications far less smart than yours. On Sun, 29 Jul 2018 20:49:24 -0400 Sichem Zhou <[email protected]> wrote: > I actually found the reason, in the function `weston_output_repaint`, the > frame_callbacks > only send the done events for surface which has view on the compositor's > view_list, > but this poses a dilemma, since I cannot either destroy or unmap the view > before the > output repainted. I don't see a problem on the compositor side. You can unmap or destroy the view, and the frame callbacks will stall until you re-map the view again. The last buffer will not get released while unmapped, because the compositor needs it on re-map. The pending frame callbacks will resume once the view is re-mapped. It sounds like your problem is in the app: do not let eglSwapBuffers() block on a frame callback. Create a frame callback just before you call eglSwapBuffers(), and do not call eglSwapBuffers() again until that frame callback has signalled. That way eglSwapBuffers should never block indefinitely. Additionally you can set eglSwapInterval to zero in case there are situations where you really need to eglSwapBuffers() before the frame callback has signalled. Thanks, pq
pgpANAKmE6Zvn.pgp
Description: OpenPGP digital signature
_______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
