void WaylandNativeWindow::finishSwap() { int ret = 0; lock(); WaylandNativeWindowBuffer *wnb = queue.front(); if (!wnb) { wnb = m_lastBuffer; } else { queue.pop_front(); } assert(wnb); m_lastBuffer = wnb; wnb->busy = 1; ret = readQueue(false); if (this->frame_callback) { do { ret = readQueue(true); } while (this->frame_callback && ret != -1); } if (ret < 0) { HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb); return; } if (wnb->wlbuffer == NULL) { wnb->init(m_android_wlegl, m_display, wl_queue); TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer); wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this); wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue); } if (m_swap_interval > 0) { this->frame_callback = wl_surface_frame(m_window->surface); wl_callback_add_listener(this->frame_callback, &frame_listener, this); wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue); } wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0); wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height); wl_surface_commit(m_window->surface); // Some compositors, namely Weston, queue buffer release events instead // of sending them immediately. If a frame event is used, this should // not be a problem. Without a frame event, we need to send a sync // request to ensure that they get flushed. wl_callback_destroy(wl_display_sync(m_display)); wl_display_flush(m_display); fronted.push_back(wnb); m_window->attached_width = wnb->width; m_window->attached_height = wnb->height; m_damage_rects = NULL; m_damage_n_rects = 0; unlock(); }