window: Use window surfaces for windows

dev
Benjamin Franzke 15 years ago
parent 9c26ff3507
commit 6693ac2108
  1. 4
      clients/dnd.c
  2. 1
      clients/gears.c
  3. 165
      clients/window.c
  4. 2
      clients/window.h
  5. 2
      configure.ac

@ -110,7 +110,7 @@ item_create(struct display *display, int x, int y, int seed)
rect.width = item_width; rect.width = item_width;
rect.height = item_height; rect.height = item_height;
item->surface = display_create_surface(display, &rect); item->surface = display_create_surface(display, NULL, &rect);
item->x = x; item->x = x;
item->y = y; item->y = y;
@ -527,7 +527,7 @@ create_drag_cursor(struct dnd_drag *dnd_drag,
rectangle.width = item_width + 2 * pointer_width; rectangle.width = item_width + 2 * pointer_width;
rectangle.height = item_height + 2 * pointer_height; rectangle.height = item_height + 2 * pointer_height;
surface = display_create_surface(dnd->display, &rectangle); surface = display_create_surface(dnd->display, NULL, &rectangle);
cr = cairo_create(surface); cr = cairo_create(surface);
cairo_translate(cr, pointer_width, pointer_height); cairo_translate(cr, pointer_width, pointer_height);

@ -359,6 +359,7 @@ gears_create(struct display *display)
gears->d = display; gears->d = display;
gears->window = window_create(display, width, height); gears->window = window_create(display, width, height);
window_set_title(gears->window, "Wayland Gears"); window_set_title(gears->window, "Wayland Gears");
window_set_buffer_type(gears->window, WINDOW_BUFFER_TYPE_EGL_IMAGE);
gears->display = display_get_egl_display(gears->d); gears->display = display_get_egl_display(gears->d);
if (gears->display == NULL) if (gears->display == NULL)

@ -66,6 +66,7 @@ struct display {
struct rectangle screen_allocation; struct rectangle screen_allocation;
int authenticated; int authenticated;
EGLDisplay dpy; EGLDisplay dpy;
EGLConfig conf;
EGLContext ctx; EGLContext ctx;
cairo_device_t *device; cairo_device_t *device;
int fd; int fd;
@ -188,6 +189,64 @@ struct surface_data {
#ifdef HAVE_CAIRO_EGL #ifdef HAVE_CAIRO_EGL
struct egl_window_surface_data {
struct display *display;
struct wl_surface *surface;
struct wl_egl_window *window;
EGLSurface surf;
};
static void
egl_window_surface_data_destroy(void *p)
{
struct egl_window_surface_data *data = p;
struct display *d = data->display;
eglDestroySurface(d->dpy, data->surf);
wl_egl_window_destroy(data->window);
data->surface = NULL;
free(p);
}
static cairo_surface_t *
display_create_egl_window_surface(struct display *display,
struct wl_surface *surface,
struct rectangle *rectangle)
{
cairo_surface_t *cairo_surface;
struct egl_window_surface_data *data;
struct wl_visual *visual;
data = malloc(sizeof *data);
if (data == NULL)
return NULL;
data->display = display;
data->surface = surface;
visual = wl_display_get_premultiplied_argb_visual(display->display);
data->window = wl_egl_window_create(display->native_dpy,
surface,
rectangle->width,
rectangle->height,
visual);
data->surf = eglCreateWindowSurface(display->dpy, display->conf,
data->window, NULL);
cairo_surface = cairo_gl_surface_create_for_egl(display->device,
data->surf,
rectangle->width,
rectangle->height);
cairo_surface_set_user_data(cairo_surface, &surface_data_key,
data, egl_window_surface_data_destroy);
return cairo_surface;
}
struct egl_image_surface_data { struct egl_image_surface_data {
struct surface_data data; struct surface_data data;
EGLImageKHR image; EGLImageKHR image;
@ -499,13 +558,20 @@ check_size(struct rectangle *rect)
cairo_surface_t * cairo_surface_t *
display_create_surface(struct display *display, display_create_surface(struct display *display,
struct wl_surface *surface,
struct rectangle *rectangle) struct rectangle *rectangle)
{ {
if (check_size(rectangle) < 0) if (check_size(rectangle) < 0)
return NULL; return NULL;
#ifdef HAVE_CAIRO_EGL #ifdef HAVE_CAIRO_EGL
if (display->dpy) { if (display->dpy) {
return display_create_egl_image_surface(display, rectangle); if (surface)
return display_create_egl_window_surface(display,
surface,
rectangle);
else
return display_create_egl_image_surface(display,
rectangle);
} }
#endif #endif
return display_create_shm_surface(display, rectangle); return display_create_shm_surface(display, rectangle);
@ -607,32 +673,52 @@ window_attach_surface(struct window *window)
{ {
struct display *display = window->display; struct display *display = window->display;
struct wl_buffer *buffer; struct wl_buffer *buffer;
struct egl_window_surface_data *data;
int32_t x, y; int32_t x, y;
int width = window->allocation.width;
int height = window->allocation.height;
if (window->pending_surface != NULL)
return;
window->pending_surface = window->cairo_surface;
window->cairo_surface = NULL;
buffer = display_get_buffer_for_surface(display,
window->pending_surface);
if (window->resize_edges & WINDOW_RESIZING_LEFT) if (window->resize_edges & WINDOW_RESIZING_LEFT)
x = window->server_allocation.width - x = window->server_allocation.width - width;
window->allocation.width;
else else
x = 0; x = 0;
if (window->resize_edges & WINDOW_RESIZING_TOP) if (window->resize_edges & WINDOW_RESIZING_TOP)
y = window->server_allocation.height - y = window->server_allocation.height - height;
window->allocation.height;
else else
y = 0; y = 0;
window->server_allocation = window->allocation;
window->resize_edges = 0; window->resize_edges = 0;
wl_surface_attach(window->surface, buffer, x, y);
wl_display_sync_callback(display->display, free_surface, window); switch (window->buffer_type) {
case WINDOW_BUFFER_TYPE_EGL_WINDOW:
data = cairo_surface_get_user_data(window->cairo_surface,
&surface_data_key);
wl_egl_window_resize(data->window, width, height, x, y);
cairo_gl_surface_swapbuffers(window->cairo_surface);
wl_egl_window_get_attached_size(data->window,
&window->server_allocation.width,
&window->server_allocation.height);
break;
case WINDOW_BUFFER_TYPE_EGL_IMAGE:
case WINDOW_BUFFER_TYPE_SHM:
if (window->pending_surface != NULL)
return;
window->pending_surface = window->cairo_surface;
window->cairo_surface = NULL;
buffer =
display_get_buffer_for_surface(display,
window->pending_surface);
wl_surface_attach(window->surface, buffer, x, y);
window->server_allocation = window->allocation;
wl_display_sync_callback(display->display, free_surface,
window);
break;
}
if (window->fullscreen) if (window->fullscreen)
wl_surface_map_fullscreen(window->surface); wl_surface_map_fullscreen(window->surface);
@ -666,6 +752,22 @@ window_set_surface(struct window *window, cairo_surface_t *surface)
window->cairo_surface = surface; window->cairo_surface = surface;
} }
static void
window_resize_cairo_window_surface(struct window *window)
{
struct egl_window_surface_data *data;
data = cairo_surface_get_user_data(window->cairo_surface,
&surface_data_key);
wl_egl_window_resize(data->window,
window->allocation.width,
window->allocation.height, 0, 0);
cairo_gl_surface_set_size(window->cairo_surface,
window->allocation.width,
window->allocation.height);
}
void void
window_create_surface(struct window *window) window_create_surface(struct window *window)
{ {
@ -673,8 +775,18 @@ window_create_surface(struct window *window)
switch (window->buffer_type) { switch (window->buffer_type) {
#ifdef HAVE_CAIRO_EGL #ifdef HAVE_CAIRO_EGL
case WINDOW_BUFFER_TYPE_EGL_WINDOW:
if (window->cairo_surface) {
window_resize_cairo_window_surface(window);
return;
}
surface = display_create_surface(window->display,
window->surface,
&window->allocation);
break;
case WINDOW_BUFFER_TYPE_EGL_IMAGE: case WINDOW_BUFFER_TYPE_EGL_IMAGE:
surface = display_create_surface(window->display, surface = display_create_surface(window->display,
NULL,
&window->allocation); &window->allocation);
break; break;
#endif #endif
@ -1325,7 +1437,8 @@ window_create_internal(struct display *display, struct window *parent,
window->decoration = 1; window->decoration = 1;
if (display->dpy) if (display->dpy)
window->buffer_type = WINDOW_BUFFER_TYPE_EGL_IMAGE; /* FIXME: make TYPE_EGL_IMAGE choosable for testing */
window->buffer_type = WINDOW_BUFFER_TYPE_EGL_WINDOW;
else else
window->buffer_type = WINDOW_BUFFER_TYPE_SHM; window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
@ -1595,6 +1708,17 @@ static int
init_egl(struct display *d) init_egl(struct display *d)
{ {
EGLint major, minor; EGLint major, minor;
EGLint n;
static const EGLint cfg_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};
d->dpy = eglGetDisplay(d->native_dpy); d->dpy = eglGetDisplay(d->native_dpy);
if (!eglInitialize(d->dpy, &major, &minor)) { if (!eglInitialize(d->dpy, &major, &minor)) {
@ -1607,7 +1731,12 @@ init_egl(struct display *d)
return -1; return -1;
} }
d->ctx = eglCreateContext(d->dpy, NULL, EGL_NO_CONTEXT, NULL); if (!eglChooseConfig(d->dpy, cfg_attribs, &d->conf, 1, &n) || n != 1) {
fprintf(stderr, "failed to choose config\n");
return -1;
}
d->ctx = eglCreateContext(d->dpy, d->conf, EGL_NO_CONTEXT, NULL);
if (d->ctx == NULL) { if (d->ctx == NULL) {
fprintf(stderr, "failed to create context\n"); fprintf(stderr, "failed to create context\n");
return -1; return -1;

@ -64,6 +64,7 @@ display_get_image_for_egl_image_surface(struct display *display,
cairo_surface_t * cairo_surface_t *
display_create_surface(struct display *display, display_create_surface(struct display *display,
struct wl_surface *surface,
struct rectangle *rectangle); struct rectangle *rectangle);
struct wl_buffer * struct wl_buffer *
@ -167,6 +168,7 @@ void
window_create_surface(struct window *window); window_create_surface(struct window *window);
enum window_buffer_type { enum window_buffer_type {
WINDOW_BUFFER_TYPE_EGL_WINDOW,
WINDOW_BUFFER_TYPE_EGL_IMAGE, WINDOW_BUFFER_TYPE_EGL_IMAGE,
WINDOW_BUFFER_TYPE_SHM, WINDOW_BUFFER_TYPE_SHM,
}; };

@ -54,7 +54,7 @@ if test x$enable_wayland_compositor == xyes; then
fi fi
PKG_CHECK_MODULES(CAIRO_EGL, [cairo-egl], PKG_CHECK_MODULES(CAIRO_EGL, [cairo-egl >= 1.11.3],
[have_cairo_egl=yes], [have_cairo_egl=no]) [have_cairo_egl=yes], [have_cairo_egl=no])
AS_IF([test "x$have_cairo_egl" = "xyes"], AS_IF([test "x$have_cairo_egl" = "xyes"],
[AC_DEFINE([HAVE_CAIRO_EGL], [1], [Have cairo-egl])]) [AC_DEFINE([HAVE_CAIRO_EGL], [1], [Have cairo-egl])])

Loading…
Cancel
Save