gint8 toplevel_window_type;
struct wl_surface *surface;
- struct wl_buffer *buffer;
- EGLImageKHR *pending_image;
- EGLImageKHR *next_image;
unsigned int mapped : 1;
cairo_surface_t *cairo_surface;
+ cairo_surface_t *server_surface;
GLuint texture;
- EGLImageKHR image;
-
};
struct _GdkWindowImplWaylandClass
impl->cairo_surface = NULL;
}
- if (impl->image)
- {
- if (impl->image == impl->next_image)
- impl->next_image = NULL;
-
- if (impl->image != impl->pending_image)
- display_wayland->destroy_image(display_wayland->egl_display,
- impl->image);
-
- impl->image = NULL;
-
- if (impl->buffer)
- {
- wl_buffer_destroy(impl->buffer);
- impl->buffer = NULL;
- }
-
- fprintf(stderr, " - cleared image\n");
- }
-
area.x = 0;
area.y = 0;
area.width = window->width;
}
}
-void
-_gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image)
+static const cairo_user_data_key_t gdk_wayland_cairo_key;
+
+typedef struct _GdkWaylandCairoSurfaceData {
+ EGLImageKHR image;
+ GLuint texture;
+ struct wl_buffer *buffer;
+ GdkDisplayWayland *display;
+} GdkWaylandCairoSurfaceData;
+
+struct wl_buffer *
+_gdk_wayland_surface_get_buffer (GdkDisplayWayland *display,
+ cairo_surface_t *surface)
{
- GdkDisplayWayland *display_wayland =
- GDK_DISPLAY_WAYLAND (gdk_window_get_display (window));
- GdkWindowImplWayland *impl;
+ GdkWaylandCairoSurfaceData *data;
EGLint name, stride;
- struct wl_visual *wl_visual;
+ struct wl_visual *visual;
+ int width, height;
- if (GDK_WINDOW_DESTROYED (window))
- return;
+ data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
- impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+ if (data->buffer)
+ return data->buffer;
+
+ visual =
+ wl_display_get_premultiplied_argb_visual(display->wl_display);
- wl_visual =
- wl_display_get_premultiplied_argb_visual(display_wayland->wl_display);
+ width = cairo_gl_surface_get_width (surface);
+ height = cairo_gl_surface_get_height (surface);
+ display->export_drm_image (display->egl_display,
+ data->image, &name, NULL, &stride);
+ data->buffer = wl_drm_create_buffer(display->drm,
+ name, width, height, stride, visual);
- display_wayland->export_drm_image (display_wayland->egl_display,
- image, &name, NULL, &stride);
+ return data->buffer;
+}
- impl->buffer = wl_drm_create_buffer(display_wayland->drm,
- name, window->width, window->height,
- stride, wl_visual);
- wl_surface_attach (impl->surface, impl->buffer, 0, 0);
+static void
+gdk_wayland_window_attach_image (GdkWindow *window)
+{
+ GdkDisplayWayland *display_wayland =
+ GDK_DISPLAY_WAYLAND (gdk_window_get_display (window));
+ GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+ struct wl_buffer *buffer;
- g_object_ref(impl);
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (impl->server_surface == impl->cairo_surface)
+ return;
+
+ impl->server_surface = impl->cairo_surface;
+ buffer = _gdk_wayland_surface_get_buffer (display_wayland,
+ impl->cairo_surface);
+ wl_surface_attach (impl->surface, buffer, 0, 0);
- fprintf(stderr, "attach %p %dx%d (image %p, name %d)\n",
- window, window->width, window->height, image, name);
+ fprintf(stderr, "attach %p %dx%d\n", window, window->width, window->height);
}
static void
G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
}
-static const cairo_user_data_key_t gdk_wayland_cairo_key;
-
static void
-gdk_wayland_cairo_surface_destroy (void *data)
+gdk_wayland_cairo_surface_destroy (void *p)
{
- GdkWindowImplWayland *impl = data;
+ GdkWaylandCairoSurfaceData *data = p;
- impl->cairo_surface = NULL;
+ data->display->destroy_image (data->display->egl_display, data->image);
+ cairo_device_acquire(data->display->cairo_device);
+ glDeleteTextures(1, &data->texture);
+ cairo_device_release(data->display->cairo_device);
+ if (data->buffer)
+ wl_buffer_destroy(data->buffer);
+ g_free(data);
}
static cairo_surface_t *
-gdk_wayland_create_cairo_surface (GdkWindowImplWayland *impl,
- int width,
- int height)
+gdk_wayland_create_cairo_surface (GdkDisplayWayland *display,
+ int width, int height)
{
- GdkDisplayWayland *display_wayland =
- GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper));
+ GdkWaylandCairoSurfaceData *data;
cairo_surface_t *surface;
EGLint image_attribs[] = {
EGL_NONE
};
- if (impl->image == NULL)
- {
- image_attribs[1] = width;
- image_attribs[3] = height;
- impl->image =
- display_wayland->create_drm_image(display_wayland->egl_display,
- image_attribs);
- if (impl->texture == 0)
- glGenTextures(1, &impl->texture);
-
- glBindTexture(GL_TEXTURE_2D, impl->texture);
- display_wayland->image_target_texture_2d(GL_TEXTURE_2D, impl->image);
-
- printf("allocate image %dx%d (image %p, window %p)\n",
- width, height, impl->image, impl->wrapper);
- }
+ data = g_new (GdkWaylandCairoSurfaceData, 1);
+ data->display = display;
+ data->buffer = NULL;
+ image_attribs[1] = width;
+ image_attribs[3] = height;
+ data->image = display->create_drm_image(display->egl_display, image_attribs);
+ glGenTextures(1, &data->texture);
+ glBindTexture(GL_TEXTURE_2D, data->texture);
+ display->image_target_texture_2d(GL_TEXTURE_2D, data->image);
+
+ printf("allocate image %dx%d (image %p)\n", width, height, data->image);
- surface = cairo_gl_surface_create_for_texture(display_wayland->cairo_device,
+ surface = cairo_gl_surface_create_for_texture(display->cairo_device,
CAIRO_CONTENT_COLOR_ALPHA,
- impl->texture, width, height);
+ data->texture, width, height);
+
+ cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
+ data, gdk_wayland_cairo_surface_destroy);
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
fprintf (stderr, "create gl surface failed\n");
gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+ GdkDisplayWayland *display_wayland =
+ GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper));
if (GDK_WINDOW_DESTROYED (impl->wrapper))
return NULL;
if (!impl->cairo_surface)
{
impl->cairo_surface =
- gdk_wayland_create_cairo_surface (impl,
+ gdk_wayland_create_cairo_surface (display_wayland,
impl->wrapper->width,
impl->wrapper->height);
-
- cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key,
- impl, gdk_wayland_cairo_surface_destroy);
}
- else
- cairo_surface_reference (impl->cairo_surface);
+
+ cairo_surface_reference (impl->cairo_surface);
return impl->cairo_surface;
}
cairo_rectangle_int_t rect;
int i, n;
- if (impl->buffer == NULL)
- _gdk_wayland_window_attach_image (window, impl->image);
+ gdk_wayland_window_attach_image (window);
if (!impl->mapped)
{
wl_surface_map_toplevel (impl->surface);