[RFC mesa 3/4] wayland: Add new take_buffer and commit for wayland-egl
John Kåre Alsaker
john.kare.alsaker at gmail.com
Sat Mar 2 17:26:13 PST 2013
---
src/egl/drivers/dri2/platform_wayland.c | 106 ++++++++++++++++++-------
src/egl/wayland/wayland-egl/wayland-egl-priv.h | 2 +
src/egl/wayland/wayland-egl/wayland-egl.c | 22 +++++
3 files changed, 102 insertions(+), 28 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 56f5d3c..8797491 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -98,6 +98,12 @@ static struct wl_buffer_listener wl_buffer_listener = {
wl_buffer_release
};
+static struct wl_buffer *
+take_buffer(struct dri2_egl_surface *dri2_surf);
+
+static EGLBoolean
+commit_surface(struct dri2_egl_display *, struct dri2_egl_surface *dri2_surf);
+
static void
resize_callback(struct wl_egl_window *wl_win, void *data)
{
@@ -108,6 +114,22 @@ resize_callback(struct wl_egl_window *wl_win, void *data)
(*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
}
+static struct wl_buffer *
+take_buffer_callback(struct wl_egl_window *wl_win, void *data)
+{
+ return take_buffer(data);
+}
+
+static int
+commit_callback(struct wl_egl_window *wl_win, void *data)
+{
+ struct dri2_egl_surface *dri2_surf = data;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ return commit_surface(dri2_dpy, dri2_surf) ? 0 : -1;
+}
+
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
@@ -143,6 +165,8 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
dri2_surf->wl_win->private = dri2_surf;
dri2_surf->wl_win->resize_callback = resize_callback;
+ dri2_surf->wl_win->take_buffer_callback = take_buffer_callback;
+ dri2_surf->wl_win->commit_callback = commit_callback;
dri2_surf->base.Width = -1;
dri2_surf->base.Height = -1;
@@ -221,6 +245,8 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
dri2_surf->wl_win->private = NULL;
dri2_surf->wl_win->resize_callback = NULL;
+ dri2_surf->wl_win->take_buffer_callback = NULL;
+ dri2_surf->wl_win->commit_callback = NULL;
}
free(surf);
@@ -438,16 +464,13 @@ static const struct wl_callback_listener frame_listener = {
wayland_frame_callback
};
-/**
- * Called via eglSwapBuffers(), drv->API.SwapBuffers().
- */
-static EGLBoolean
-dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+static struct wl_buffer *
+take_buffer(struct dri2_egl_surface *dri2_surf)
{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
__DRIbuffer buffer;
- int i, ret;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ int i;
for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
if (dri2_surf->color_buffers[i].age > 0)
@@ -456,8 +479,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
/* Make sure we have a back buffer in case we're swapping without ever
* rendering. */
if (get_back_bo(dri2_surf, &buffer) < 0) {
- _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
- return EGL_FALSE;
+ return NULL;
}
dri2_surf->back->age = 1;
@@ -465,31 +487,30 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
dri2_surf->back = NULL;
if (dri2_surf->current->wl_buffer == NULL) {
- dri2_surf->current->wl_buffer =
+ struct wl_buffer *result =
wl_drm_create_buffer(dri2_dpy->wl_drm,
dri2_surf->current->dri_buffer->name,
dri2_surf->base.Width,
dri2_surf->base.Height,
dri2_surf->current->dri_buffer->pitch,
dri2_surf->format);
- wl_proxy_set_queue((struct wl_proxy *) dri2_surf->current->wl_buffer,
- dri2_dpy->wl_queue);
- wl_buffer_add_listener(dri2_surf->current->wl_buffer,
- &wl_buffer_listener, dri2_surf);
+ /* TODO: Handle the case where dri2_surf->current->wl_buffer is NULL */
+ wl_proxy_set_queue((struct wl_proxy *) result, dri2_dpy->wl_queue);
+ wl_buffer_add_listener(result, &wl_buffer_listener, dri2_surf);
+
+ dri2_surf->current->wl_buffer = result;
}
- wl_surface_attach(dri2_surf->wl_win->surface,
- dri2_surf->current->wl_buffer,
- dri2_surf->dx, dri2_surf->dy);
+ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+ (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
- dri2_surf->wl_win->attached_width = dri2_surf->base.Width;
- dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
- /* reset resize growing parameters */
- dri2_surf->dx = 0;
- dri2_surf->dy = 0;
+ return dri2_surf->current->wl_buffer;
+}
- wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
- dri2_surf->base.Width, dri2_surf->base.Height);
+static EGLBoolean
+commit_surface(struct dri2_egl_display *dri2_dpy, struct dri2_egl_surface *dri2_surf)
+{
+ int ret;
dri2_surf->frame_callback = wl_surface_frame(dri2_surf->wl_win->surface);
wl_callback_add_listener(dri2_surf->frame_callback,
@@ -499,9 +520,6 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
wl_surface_commit(dri2_surf->wl_win->surface);
- (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
- (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
-
ret = 0;
while (dri2_surf->frame_callback && ret != -1)
@@ -512,6 +530,38 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
return EGL_TRUE;
}
+/**
+ * Called via eglSwapBuffers(), drv->API.SwapBuffers().
+ */
+static EGLBoolean
+dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ struct wl_buffer *wl_buffer;
+
+ wl_buffer = take_buffer(dri2_surf);
+
+ if (!wl_buffer) {
+ _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
+ return EGL_FALSE;
+ }
+
+ wl_surface_attach(dri2_surf->wl_win->surface, wl_buffer,
+ dri2_surf->dx, dri2_surf->dy);
+
+ dri2_surf->wl_win->attached_width = dri2_surf->base.Width;
+ dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
+ /* reset resize growing parameters */
+ dri2_surf->dx = 0;
+ dri2_surf->dy = 0;
+
+ wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
+ dri2_surf->base.Width, dri2_surf->base.Height);
+
+ return commit_surface(dri2_dpy, dri2_surf);
+}
+
static EGLint
dri2_query_buffer_age(_EGLDriver *drv,
_EGLDisplay *disp, _EGLSurface *surface)
diff --git a/src/egl/wayland/wayland-egl/wayland-egl-priv.h b/src/egl/wayland/wayland-egl/wayland-egl-priv.h
index da25be9..901d2c7 100644
--- a/src/egl/wayland/wayland-egl/wayland-egl-priv.h
+++ b/src/egl/wayland/wayland-egl/wayland-egl-priv.h
@@ -27,6 +27,8 @@ struct wl_egl_window {
void *private;
void (*resize_callback)(struct wl_egl_window *, void *);
+ struct wl_buffer *(*take_buffer_callback)(struct wl_egl_window *, void *);
+ int (*commit_callback)(struct wl_egl_window *, void *);
};
#ifdef __cplusplus
diff --git a/src/egl/wayland/wayland-egl/wayland-egl.c b/src/egl/wayland/wayland-egl/wayland-egl.c
index 8bd49cf..57b8262 100644
--- a/src/egl/wayland/wayland-egl/wayland-egl.c
+++ b/src/egl/wayland/wayland-egl/wayland-egl.c
@@ -31,6 +31,8 @@ wl_egl_window_create(struct wl_surface *surface,
egl_window->surface = surface;
egl_window->private = NULL;
egl_window->resize_callback = NULL;
+ egl_window->take_buffer_callback = NULL;
+ egl_window->commit_callback = NULL;
wl_egl_window_resize(egl_window, width, height, 0, 0);
egl_window->attached_width = 0;
egl_window->attached_height = 0;
@@ -53,3 +55,23 @@ wl_egl_window_get_attached_size(struct wl_egl_window *egl_window,
if (height)
*height = egl_window->attached_height;
}
+
+WL_EGL_EXPORT struct wl_buffer *
+wl_egl_window_take_buffer(struct wl_egl_window *egl_window)
+{
+ if (egl_window->take_buffer_callback)
+ return egl_window->take_buffer_callback(egl_window,
+ egl_window->private);
+ else
+ return NULL;
+}
+
+WL_EGL_EXPORT int
+wl_egl_window_commit(struct wl_egl_window *egl_window)
+{
+ if (egl_window->commit_callback)
+ return egl_window->commit_callback(egl_window,
+ egl_window->private);
+ else
+ return -1;
+}
--
1.8.1.4
More information about the wayland-devel
mailing list