static void set_fullscreen(struct window *window, int fullscreen) { struct wl_callback *callback; window->fullscreen = fullscreen; window->configured = 0; if (fullscreen) { wl_shell_surface_set_fullscreen(window->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL); callback = wl_display_sync(window->display->display); wl_callback_add_listener(callback, &configure_callback_listener, window); } else { wl_shell_surface_set_toplevel(window->shell_surface); handle_configure(window, window->shell_surface, 0, window->window_size.width, window->window_size.height); window->configured = 1; } }
void WaylandNativeWindowBuffer::wlbuffer_from_native_handle(struct android_wlegl *android_wlegl, struct wl_display *display, struct wl_event_queue *queue) { struct wl_array ints; int *ints_data; struct android_wlegl_handle *wlegl_handle; wl_array_init(&ints); ints_data = (int*) wl_array_add(&ints, handle->numInts*sizeof(int)); memcpy(ints_data, handle->data + handle->numFds, handle->numInts*sizeof(int)); wlegl_handle = android_wlegl_create_handle(android_wlegl, handle->numFds, &ints); wl_array_release(&ints); for (int i = 0; i < handle->numFds; i++) { android_wlegl_handle_add_fd(wlegl_handle, handle->data[i]); } wlbuffer = android_wlegl_create_buffer(android_wlegl, width, height, stride, format, usage, wlegl_handle); android_wlegl_handle_destroy(wlegl_handle); creation_callback = wl_display_sync(display); wl_callback_add_listener(creation_callback, &buffer_create_sync_listener, &creation_callback); wl_proxy_set_queue((struct wl_proxy *)creation_callback, queue); }
void create_surface(struct display *display) { EGLBoolean ret; display->surface = wl_compositor_create_surface(display->compositor); display->shell_surface = wl_shell_get_shell_surface(display->shell, display->surface); wl_shell_surface_add_listener(display->shell_surface, &shell_surface_listener, display); display->native = wl_egl_window_create(display->surface, 1, 1); display->egl_surface = eglCreateWindowSurface((EGLDisplay) display->egl.dpy, display->egl.conf, (EGLNativeWindowType) display->native, NULL); wl_shell_surface_set_title(display->shell_surface, "projection"); ret = eglMakeCurrent(display->egl.dpy, display->egl_surface, display->egl_surface, display->egl.ctx); assert(ret == EGL_TRUE); struct wl_callback *callback; display->configured = 0; wl_shell_surface_set_fullscreen(display->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL); callback = wl_display_sync(display->display); wl_callback_add_listener(callback, &configure_callback_listener, display); }
static void dri2_release_buffers(struct dri2_egl_surface *dri2_surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); struct wl_callback *callback; int i; if (dri2_surf->third_buffer) { dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->third_buffer); dri2_surf->third_buffer = NULL; } for (i = 0; i < __DRI_BUFFER_COUNT; ++i) { if (dri2_surf->dri_buffers[i]) { switch (i) { case __DRI_BUFFER_FRONT_LEFT: if (dri2_surf->pending_buffer) wl_display_roundtrip(dri2_dpy->wl_dpy); dri2_surf->pending_buffer = dri2_surf->dri_buffers[i]; callback = wl_display_sync(dri2_dpy->wl_dpy); wl_callback_add_listener(callback, &release_buffer_listener, dri2_surf); break; default: dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->dri_buffers[i]); break; } dri2_surf->dri_buffers[i] = NULL; } } }
void setup_callback_listener() { struct wl_callback *callback; callback = wl_display_sync(GLWin.wl_display); wl_callback_add_listener(callback, &configure_callback_listener, 0); }
static void leak_closure(void) { struct wl_callback *cb; struct pollfd pfd; struct client *c = client_connect(); cb = wl_display_sync(c->wl_display); assert(cb); assert(wl_display_flush(c->wl_display) > 0); /* we don't need it, it is referenced */ wl_callback_destroy(cb); pfd.fd = wl_display_get_fd(c->wl_display); pfd.events = POLLIN; test_set_timeout(2); assert(poll(&pfd, 1, -1) == 1); /* read events, but do not dispatch them */ assert(wl_display_prepare_read(c->wl_display) == 0); assert(wl_display_read_events(c->wl_display) == 0); /* * now we have wl_callback.done and wl_display.delete_id queued; * if we now release the queue (in wl_display_disconnect()) * we should not leak memory */ client_disconnect(c); }
/* Swap the contents of a drawable to the screen */ static WSEGLError wseglSwapDrawable (WSEGLDrawableHandle _drawable, unsigned long data) { struct wl_egl_window *drawable = (struct wl_egl_window *) _drawable; struct wl_callback *callback; if (drawable->numFlipBuffers) { PVR2DPresentFlip(drawable->display->context, drawable->flipChain, drawable->backBuffers[drawable->currentBackBuffer], 0); } else if (drawable->display->display) { while (drawable->block_swap_buffers == 1) wl_display_iterate(drawable->display->display, WL_DISPLAY_READABLE); drawable->block_swap_buffers = 1; callback = wl_display_sync(drawable->display->display); wl_callback_add_listener(callback, &sync_listener, drawable); wl_buffer_damage(drawable->drmbuffers[drawable->currentBackBuffer], 0, 0, drawable->width, drawable->height); wl_surface_attach(drawable->surface, drawable->drmbuffers[drawable->currentBackBuffer], 0, 0); wl_surface_damage(drawable->surface, 0, 0, drawable->width, drawable->height); } else { PVR2DBLTINFO blit; memset(&blit, 0, sizeof(blit)); blit.CopyCode = PVR2DROPcopy; blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL; blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer]; blit.SrcStride = drawable->strideBytes; blit.SrcX = 0; blit.SrcY = 0; blit.SizeX = drawable->width; blit.SizeY = drawable->height; blit.SrcFormat = wsegl2pvr2dformat(drawable->format); blit.pDstMemInfo = drawable->frontBufferPVRMEM; blit.DstStride = drawable->strideBytes; blit.DstX = 0; blit.DstY = 0; blit.DSizeX = drawable->width; blit.DSizeY = drawable->height; blit.DstFormat = wsegl2pvr2dformat(drawable->format); PVR2DBlt(drawable->display->context, &blit); PVR2DQueryBlitsComplete (drawable->display->context, drawable->frontBufferPVRMEM, 1); } drawable->currentBackBuffer = (drawable->currentBackBuffer + 1) % WAYLANDWSEGL_MAX_BACK_BUFFERS; return WSEGL_SUCCESS; }
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->wlbuffer_from_native_handle(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(); }
static void wait_for_roundtrip(GdkWaylandDisplay *display) { struct wl_callback *callback; display->init_ref_count++; callback = wl_display_sync(display->wl_display); wl_callback_add_listener(callback, &init_sync_listener, display); }
static void _gdk_wayland_display_async_roundtrip (GdkWaylandDisplay *display_wayland) { struct wl_callback *callback; callback = wl_display_sync (display_wayland->wl_display); wl_callback_add_listener (callback, &async_roundtrip_listener, display_wayland); display_wayland->async_roundtrips = g_list_append (display_wayland->async_roundtrips, callback); }
int wayland_roundtrip(struct wl_egl_display *display) { struct wl_callback *callback; int done = 0, ret = 0; wl_display_dispatch_queue_pending(display->display, display->queue); callback = wl_display_sync(display->display); wl_callback_add_listener(callback, &roundtrip_listener, &done); wl_proxy_set_queue((struct wl_proxy *)callback, display->queue); while (ret == 0 && !done) ret = wl_display_dispatch_queue(display->display, display->queue); return ret; }
/* Test that when receiving the first of two synchronization * callback events, destroying the second one doesn't cause any * errors even if the delete_id event is handled out of order. */ static int client_test_multiple_queues(void) { struct wl_event_queue *queue; struct wl_callback *callback1; struct multiple_queues_state state; int ret = 0; state.display = wl_display_connect(SOCKET_NAME); client_assert(state.display); /* Make the current thread the display thread. This is because * wl_display_dispatch_queue() will only read the display fd if * the main display thread has been set. */ wl_display_dispatch_pending(state.display); queue = wl_display_create_queue(state.display); client_assert(queue); state.done = false; callback1 = wl_display_sync(state.display); wl_callback_add_listener(callback1, &sync_listener, &state); wl_proxy_set_queue((struct wl_proxy *) callback1, queue); state.callback2 = wl_display_sync(state.display); wl_callback_add_listener(state.callback2, &sync_listener, NULL); wl_proxy_set_queue((struct wl_proxy *) state.callback2, queue); wl_display_flush(state.display); while (!state.done && !ret) ret = wl_display_dispatch_queue(state.display, queue); wl_display_disconnect(state.display); return ret == -1 ? -1 : 0; }
int WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display) { struct wl_callback *callback; int done = 0, ret = 0; wl_display_dispatch_queue_pending(display->m_display, display->wl_queue); callback = wl_display_sync(display->m_display); wl_callback_add_listener(callback, &sync_listener, &done); wl_proxy_set_queue((struct wl_proxy *) callback, display->wl_queue); while (ret == 0 && !done) ret = wl_display_dispatch_queue(display->m_display, display->wl_queue); return ret; }
extern "C" _EGLDisplay *waylandws_GetDisplay(EGLNativeDisplayType display) { WaylandDisplay *wdpy = new WaylandDisplay; wdpy->wl_dpy = (wl_display *)display; wdpy->wlegl = NULL; wdpy->queue = wl_display_create_queue(wdpy->wl_dpy); wdpy->registry = wl_display_get_registry(wdpy->wl_dpy); wl_proxy_set_queue((wl_proxy *) wdpy->registry, wdpy->queue); wl_registry_add_listener(wdpy->registry, ®istry_listener, wdpy); wl_callback *cb = wl_display_sync(wdpy->wl_dpy); wl_proxy_set_queue((wl_proxy *) cb, wdpy->queue); wl_callback_add_listener(cb, &callback_listener, wdpy); return &wdpy->base; }
int wayland_roundtrip(struct wayland_display *display) { struct wl_callback *callback; int done = 0, ret = 0; callback = wl_display_sync(display->dpy); wl_callback_add_listener(callback, &sync_listener, &done); wl_proxy_set_queue((struct wl_proxy *) callback, display->queue); while (ret != -1 && !done) ret = wl_display_dispatch_queue(display->dpy, display->queue); if (!done) wl_callback_destroy(callback); return ret; }
bool WindowEGLImpl::CreateSurface() { struct wl_callback *callback; EGLBoolean ret; m_native = wl_egl_window_create(m_window->GetWlSurface(), m_window->GetWidth(), m_window->GetHeight()); m_eglSurface = eglCreateWindowSurface(m_egl.dpy, m_egl.cfg, m_native, NULL); ret = eglMakeCurrent(m_egl.dpy, m_eglSurface, m_eglSurface, m_egl.ctx); if (ret != EGL_TRUE) return false; callback = wl_display_sync(m_window->GetDisplay()->GetWlDisplay()); wl_callback_add_listener(callback, &configureListener, this); return true; }
static gint gst_wl_display_roundtrip (GstWlDisplay * self) { struct wl_callback *callback; gint ret = 0; gboolean done = FALSE; g_return_val_if_fail (self != NULL, -1); /* We don't own the display, process only our queue */ callback = wl_display_sync (self->display); wl_callback_add_listener (callback, &sync_listener, &done); wl_proxy_set_queue ((struct wl_proxy *) callback, self->queue); while (ret != -1 && !done) ret = wl_display_dispatch_queue (self->display, self->queue); wl_callback_destroy (callback); return ret; }
static int xwl_dri3_open_client(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *pfd) { struct xwl_screen *xwl_screen = xwl_screen_get(screen); struct xwl_auth_state *state; struct wl_callback *callback; drm_magic_t magic; int fd; fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC); if (fd < 0) return BadAlloc; if (xwl_screen->fd_render_node) { *pfd = fd; return Success; } state = malloc(sizeof *state); if (state == NULL) { close(fd); return BadAlloc; } state->client = client; state->fd = fd; if (drmGetMagic(state->fd, &magic) < 0) { close(state->fd); free(state); return BadMatch; } wl_drm_authenticate(xwl_screen->drm, magic); callback = wl_display_sync(xwl_screen->display); wl_callback_add_listener(callback, &sync_listener, state); IgnoreClient(client); return Success; }
/** Block until all pending request are processed by the server * * \param display The display context object * \return The number of dispatched events on success or -1 on failure * * Blocks until the server process all currently issued requests and * sends out pending events on all event queues. * * \memberof wl_display */ WL_EXPORT int wl_display_roundtrip(struct wl_display *display) { struct wl_callback *callback; int done, ret = 0; done = 0; callback = wl_display_sync(display); if (callback == NULL) return -1; wl_callback_add_listener(callback, &sync_listener, &done); while (!done && ret >= 0) ret = wl_display_dispatch(display); if (ret == -1 && !done) wl_callback_destroy(callback); return ret; }
int WaylandNativeWindow::cancelBuffer(BaseNativeWindowBuffer* buffer, int fenceFd){ std::list<WaylandNativeWindowBuffer *>::iterator it; WaylandNativeWindowBuffer *wnb = (WaylandNativeWindowBuffer*) buffer; lock(); HYBRIS_TRACE_BEGIN("wayland-platform", "cancelBuffer", "-%p", wnb); /* Check first that it really is our buffer */ for (it = m_bufList.begin(); it != m_bufList.end(); it++) { if ((*it) == wnb) break; } assert(it != m_bufList.end()); wnb->busy = 0; ++m_freeBufs; HYBRIS_TRACE_COUNTER("wayland-platform", "m_freeBufs", "%i", m_freeBufs); for (it = m_bufList.begin(); it != m_bufList.end(); it++) { (*it)->youngest = 0; } wnb->youngest = 1; if (m_queueReads != 0) { // Some thread is waiting on wl_display_dispatch_queue(), possibly waiting for a wl_buffer.release // event. Since we have now cancelled a buffer push an artificial event so that the dispatch returns // and the thread can notice the cancelled buffer. This means there is a delay of one roundtrip, // but I don't see other solution except having one dedicated thread for calling wl_display_dispatch_queue(). wl_callback_destroy(wl_display_sync(m_display)); } HYBRIS_TRACE_END("wayland-platform", "cancelBuffer", "-%p", wnb); unlock(); return 0; }
static void wayland_window_surface_handle_resize(struct wayland_surface *surface) { struct wayland_display *display = surface->display; struct pipe_resource *front_resource; const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT; int i; front_resource = resource_surface_get_single_resource(surface->rsurf, front_natt); if (resource_surface_set_size(surface->rsurf, surface->win->width, surface->win->height)) { if (surface->pending_resource) wayland_roundtrip(display); if (front_resource) { struct wl_callback *callback; surface->pending_resource = front_resource; front_resource = NULL; callback = wl_display_sync(display->dpy); wl_callback_add_listener(callback, &release_buffer_listener, surface); wl_proxy_set_queue((struct wl_proxy *) callback, display->queue); } for (i = 0; i < WL_BUFFER_COUNT; ++i) { if (surface->buffer[i]) wl_buffer_destroy(surface->buffer[i]); surface->buffer[i] = NULL; } surface->dx = surface->win->dx; surface->dy = surface->win->dy; } pipe_resource_reference(&front_resource, NULL); }
void GHOST_WindowWayland::DisplaySyncHandler::init() { m_callback = WL_CHK(wl_display_sync(m_window->m_system->getDisplay())); ADD_LISTENER(callback); }
void _glfwPlatformPostEmptyEvent(void) { wl_display_sync(_glfw.wl.display); }
void QWaylandXCompositeEGLContext::geometryChanged() { QSize size(mWindow->geometry().size()); if (size.isEmpty()) { //QGLWidget wants a context for a window without geometry size = QSize(1,1); } delete mBuffer; //XFreePixmap deletes the glxPixmap as well if (mXWindow) { XDestroyWindow(mEglIntegration->xDisplay(),mXWindow); } VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig); XVisualInfo visualInfoTemplate; memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); visualInfoTemplate.visualid = visualId; int matchingCount = 0; XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount); Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone); XSetWindowAttributes a; a.colormap = cmap; mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(), 0, visualInfo->depth, InputOutput, visualInfo->visual, CWColormap, &a); XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual); XMapWindow(mEglIntegration->xDisplay(), mXWindow); mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0); if (mEglWindowSurface == EGL_NO_SURFACE) { qFatal("Could not make eglsurface"); } XSync(mEglIntegration->xDisplay(),False); mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(), (uint32_t)mXWindow, size, mEglIntegration->waylandDisplay()->argbVisual()); mWindow->attach(mBuffer); wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(), QWaylandXCompositeEGLContext::sync_function, this); mWaitingForSync = true; wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0); mEglIntegration->waylandDisplay()->flushRequests(); while (mWaitingForSync) { mEglIntegration->waylandDisplay()->readEvents(); } }