Merge remote-tracking branch 'bnf/buffer.release-2'

Conflicts:
	compositor/compositor.h
dev
Kristian Høgsberg 14 years ago
commit ec138901c1
  1. 102
      compositor/compositor.c
  2. 5
      compositor/compositor.h

@ -162,6 +162,32 @@ wlsc_spring_done(struct wlsc_spring *spring)
fabs(spring->current - spring->target) < 0.0002;
}
static void
surface_handle_buffer_destroy(struct wl_listener *listener,
struct wl_resource *resource, uint32_t time)
{
struct wlsc_surface *es = container_of(listener, struct wlsc_surface,
buffer_destroy_listener);
struct wl_buffer *buffer = (struct wl_buffer *) resource;
if (es->buffer == buffer)
es->buffer = NULL;
}
static void
output_handle_scanout_buffer_destroy(struct wl_listener *listener,
struct wl_resource *resource,
uint32_t time)
{
struct wlsc_output *output =
container_of(listener, struct wlsc_output,
scanout_buffer_destroy_listener);
struct wl_buffer *buffer = (struct wl_buffer *) resource;
if (output->scanout_buffer == buffer)
output->scanout_buffer = NULL;
}
WL_EXPORT struct wlsc_surface *
wlsc_surface_create(struct wlsc_compositor *compositor,
int32_t x, int32_t y, int32_t width, int32_t height)
@ -190,6 +216,11 @@ wlsc_surface_create(struct wlsc_compositor *compositor,
surface->width = width;
surface->height = height;
surface->buffer = NULL;
surface->buffer_destroy_listener.func = surface_handle_buffer_destroy;
wl_list_init(&surface->buffer_destroy_listener.link);
surface->transform = NULL;
return surface;
@ -241,6 +272,8 @@ destroy_surface(struct wl_resource *resource, struct wl_client *client)
else
glDeleteTextures(1, &surface->saved_texture);
if (surface->buffer)
wl_list_remove(&surface->buffer_destroy_listener.link);
if (surface->image != EGL_NO_IMAGE_KHR)
compositor->destroy_image(compositor->display,
@ -310,6 +343,9 @@ wlsc_sprite_attach(struct wlsc_sprite *sprite, struct wl_surface *surface)
}
es->visual = sprite->visual;
if (es->buffer)
es->buffer = NULL;
}
enum sprite_usage {
@ -580,18 +616,31 @@ wlsc_compositor_damage_all(struct wlsc_compositor *compositor)
wlsc_output_damage(output);
}
static inline void
wlsc_buffer_post_release(struct wl_buffer *buffer)
{
if (buffer->client == NULL) {
fprintf(stderr, "buffer.release warning: buffer.client: %p\n",
buffer->client);
return;
}
wl_client_post_event(buffer->client,
&buffer->resource.object,
WL_BUFFER_RELEASE);
}
WL_EXPORT void
wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
{
struct wlsc_compositor *compositor = output->compositor;
struct wlsc_surface *es;
struct wlsc_animation *animation, *next;
wl_list_for_each(es, &compositor->surface_list, link) {
if (es->output == output) {
wl_display_post_frame(compositor->wl_display,
&es->surface, msecs);
}
if (output->scanout_buffer) {
if (--output->scanout_buffer->busy_count == 0)
wlsc_buffer_post_release(output->scanout_buffer);
output->scanout_buffer = NULL;
}
output->finished = 1;
@ -604,6 +653,20 @@ wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
animation->frame(animation, output, msecs);
}
static void
wlsc_output_finish_redraw(struct wlsc_output *output, int msecs)
{
struct wlsc_compositor *compositor = output->compositor;
struct wlsc_surface *es;
wl_list_for_each(es, &compositor->surface_list, link) {
if (es->output == output) {
wl_display_post_frame(compositor->wl_display,
&es->surface, msecs);
}
}
}
WL_EXPORT void
wlsc_output_damage(struct wlsc_output *output)
{
@ -717,6 +780,16 @@ wlsc_output_repaint(struct wlsc_output *output)
pixman_region32_union(&ec->damage_region,
&ec->damage_region,
&total_damage);
output->scanout_buffer = es->buffer;
output->scanout_buffer->busy_count++;
wl_list_remove(&output->scanout_buffer_destroy_listener.link);
wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
&output->scanout_buffer_destroy_listener.link);
wlsc_output_finish_redraw(output,
wlsc_compositor_get_time());
return;
}
}
@ -755,6 +828,8 @@ wlsc_output_repaint(struct wlsc_output *output)
if (ec->fade.spring.current > 0.001)
fade_output(output, ec->fade.spring.current, &total_damage);
wlsc_output_finish_redraw(output, wlsc_compositor_get_time());
}
static int
@ -866,6 +941,17 @@ surface_attach(struct wl_client *client,
{
struct wlsc_surface *es = (struct wlsc_surface *) surface;
buffer->busy_count++;
if (es->buffer && es->buffer->busy_count > 0)
if (--es->buffer->busy_count == 0)
wlsc_buffer_post_release(es->buffer);
es->buffer = buffer;
wl_list_remove(&es->buffer_destroy_listener.link);
wl_list_insert(es->buffer->resource.destroy_listener_list.prev,
&es->buffer_destroy_listener.link);
es->x += x;
es->y += y;
es->width = buffer->width;
@ -1652,6 +1738,10 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
output->finished = 1;
wlsc_output_move(output, x, y);
output->scanout_buffer_destroy_listener.func =
output_handle_scanout_buffer_destroy;
wl_list_init(&output->scanout_buffer_destroy_listener.link);
output->object.interface = &wl_output_interface;
wl_display_add_object(c->wl_display, &output->object);
wl_display_add_global(c->wl_display, &output->object,

@ -77,6 +77,8 @@ struct wlsc_output {
struct wlsc_mode *current;
struct wl_list mode_list;
struct wl_buffer *scanout_buffer;
struct wl_listener scanout_buffer_destroy_listener;
int (*prepare_render)(struct wlsc_output *output);
int (*present)(struct wlsc_output *output);
@ -248,6 +250,9 @@ struct wlsc_surface {
struct wlsc_output *fullscreen_output;
EGLImageKHR image;
struct wl_buffer *buffer;
struct wl_listener buffer_destroy_listener;
};
void

Loading…
Cancel
Save