Clean up buffer handling a bit

This commit is contained in:
Kristian Høgsberg 2011-01-07 20:49:40 -05:00
parent 846e2c0eee
commit 1149c342bf
2 changed files with 81 additions and 82 deletions

View File

@ -103,15 +103,11 @@ struct _GdkWindowImplWayland
gint8 toplevel_window_type; gint8 toplevel_window_type;
struct wl_surface *surface; struct wl_surface *surface;
struct wl_buffer *buffer;
EGLImageKHR *pending_image;
EGLImageKHR *next_image;
unsigned int mapped : 1; unsigned int mapped : 1;
cairo_surface_t *cairo_surface; cairo_surface_t *cairo_surface;
cairo_surface_t *server_surface;
GLuint texture; GLuint texture;
EGLImageKHR image;
}; };
struct _GdkWindowImplWaylandClass struct _GdkWindowImplWaylandClass
@ -171,26 +167,6 @@ _gdk_wayland_window_update_size (GdkWindow *window)
impl->cairo_surface = NULL; 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.x = 0;
area.y = 0; area.y = 0;
area.width = window->width; area.width = window->width;
@ -319,35 +295,62 @@ gdk_toplevel_wayland_free_contents (GdkDisplay *display,
} }
} }
void static const cairo_user_data_key_t gdk_wayland_cairo_key;
_gdk_wayland_window_attach_image (GdkWindow *window, EGLImageKHR image)
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)
{
GdkWaylandCairoSurfaceData *data;
EGLint name, stride;
struct wl_visual *visual;
int width, height;
data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
if (data->buffer)
return data->buffer;
visual =
wl_display_get_premultiplied_argb_visual(display->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);
return data->buffer;
}
static void
gdk_wayland_window_attach_image (GdkWindow *window)
{ {
GdkDisplayWayland *display_wayland = GdkDisplayWayland *display_wayland =
GDK_DISPLAY_WAYLAND (gdk_window_get_display (window)); GDK_DISPLAY_WAYLAND (gdk_window_get_display (window));
GdkWindowImplWayland *impl; GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
EGLint name, stride; struct wl_buffer *buffer;
struct wl_visual *wl_visual;
if (GDK_WINDOW_DESTROYED (window)) if (GDK_WINDOW_DESTROYED (window))
return; return;
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); if (impl->server_surface == impl->cairo_surface)
return;
wl_visual = impl->server_surface = impl->cairo_surface;
wl_display_get_premultiplied_argb_visual(display_wayland->wl_display); buffer = _gdk_wayland_surface_get_buffer (display_wayland,
impl->cairo_surface);
wl_surface_attach (impl->surface, buffer, 0, 0);
display_wayland->export_drm_image (display_wayland->egl_display, fprintf(stderr, "attach %p %dx%d\n", window, window->width, window->height);
image, &name, NULL, &stride);
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);
g_object_ref(impl);
fprintf(stderr, "attach %p %dx%d (image %p, name %d)\n",
window, window->width, window->height, image, name);
} }
static void static void
@ -372,23 +375,25 @@ gdk_window_impl_wayland_finalize (GObject *object)
G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object); G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
} }
static const cairo_user_data_key_t gdk_wayland_cairo_key;
static void 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 * static cairo_surface_t *
gdk_wayland_create_cairo_surface (GdkWindowImplWayland *impl, gdk_wayland_create_cairo_surface (GdkDisplayWayland *display,
int width, int width, int height)
int height)
{ {
GdkDisplayWayland *display_wayland = GdkWaylandCairoSurfaceData *data;
GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper));
cairo_surface_t *surface; cairo_surface_t *surface;
EGLint image_attribs[] = { EGLint image_attribs[] = {
@ -399,26 +404,24 @@ gdk_wayland_create_cairo_surface (GdkWindowImplWayland *impl,
EGL_NONE EGL_NONE
}; };
if (impl->image == NULL) data = g_new (GdkWaylandCairoSurfaceData, 1);
{ data->display = display;
image_attribs[1] = width; data->buffer = NULL;
image_attribs[3] = height; image_attribs[1] = width;
impl->image = image_attribs[3] = height;
display_wayland->create_drm_image(display_wayland->egl_display, data->image = display->create_drm_image(display->egl_display, image_attribs);
image_attribs); glGenTextures(1, &data->texture);
if (impl->texture == 0) glBindTexture(GL_TEXTURE_2D, data->texture);
glGenTextures(1, &impl->texture); display->image_target_texture_2d(GL_TEXTURE_2D, data->image);
glBindTexture(GL_TEXTURE_2D, impl->texture); printf("allocate image %dx%d (image %p)\n", width, height, data->image);
display_wayland->image_target_texture_2d(GL_TEXTURE_2D, impl->image);
printf("allocate image %dx%d (image %p, window %p)\n", surface = cairo_gl_surface_create_for_texture(display->cairo_device,
width, height, impl->image, impl->wrapper);
}
surface = cairo_gl_surface_create_for_texture(display_wayland->cairo_device,
CAIRO_CONTENT_COLOR_ALPHA, 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) if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
fprintf (stderr, "create gl surface failed\n"); fprintf (stderr, "create gl surface failed\n");
@ -430,6 +433,8 @@ static cairo_surface_t *
gdk_wayland_window_ref_cairo_surface (GdkWindow *window) gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
{ {
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); 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)) if (GDK_WINDOW_DESTROYED (impl->wrapper))
return NULL; return NULL;
@ -437,15 +442,12 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
if (!impl->cairo_surface) if (!impl->cairo_surface)
{ {
impl->cairo_surface = impl->cairo_surface =
gdk_wayland_create_cairo_surface (impl, gdk_wayland_create_cairo_surface (display_wayland,
impl->wrapper->width, impl->wrapper->width,
impl->wrapper->height); 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; return impl->cairo_surface;
} }
@ -1259,8 +1261,7 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window,
cairo_rectangle_int_t rect; cairo_rectangle_int_t rect;
int i, n; int i, n;
if (impl->buffer == NULL) gdk_wayland_window_attach_image (window);
_gdk_wayland_window_attach_image (window, impl->image);
if (!impl->mapped) if (!impl->mapped)
{ {
wl_surface_map_toplevel (impl->surface); wl_surface_map_toplevel (impl->surface);

View File

@ -93,8 +93,6 @@ struct _GdkToplevelWayland
GType _gdk_window_impl_wayland_get_type (void); GType _gdk_window_impl_wayland_get_type (void);
GdkToplevelWayland *_gdk_wayland_window_get_toplevel (GdkWindow *window); GdkToplevelWayland *_gdk_wayland_window_get_toplevel (GdkWindow *window);
void _gdk_wayland_window_attach_image (GdkWindow *window,
EGLImageKHR image);
GdkCursor *_gdk_wayland_window_get_cursor (GdkWindow *window); GdkCursor *_gdk_wayland_window_get_cursor (GdkWindow *window);
void _gdk_wayland_window_get_offsets (GdkWindow *window, void _gdk_wayland_window_get_offsets (GdkWindow *window,