diff --git a/clients/smoke.c b/clients/smoke.c index 1f22e59d..5d3f2db8 100644 --- a/clients/smoke.c +++ b/clients/smoke.c @@ -199,6 +199,8 @@ frame_callback(struct wl_surface *surface, void *data, uint32_t time) render(smoke); + display_surface_damage(smoke->display, smoke->surface, + 0, 0, smoke->width, smoke->height); window_damage(smoke->window, 0, 0, smoke->width, smoke->height); wl_display_frame_callback(display_get_display(smoke->display), window_get_wl_surface(smoke->window), diff --git a/clients/window.c b/clients/window.c index a3281988..9d0b753b 100644 --- a/clients/window.c +++ b/clients/window.c @@ -734,8 +734,21 @@ window_attach_surface(struct window *window) void window_flush(struct window *window) { - if (window->cairo_surface) - window_attach_surface(window); + if (window->cairo_surface) { + switch (window->buffer_type) { + case WINDOW_BUFFER_TYPE_EGL_IMAGE: + case WINDOW_BUFFER_TYPE_SHM: + display_surface_damage(window->display, + window->cairo_surface, + 0, 0, + window->allocation.width, + window->allocation.height); + break; + default: + break; + } + window_attach_surface(window); + } } void @@ -1420,6 +1433,17 @@ window_get_title(struct window *window) return window->title; } +void +display_surface_damage(struct display *display, cairo_surface_t *cairo_surface, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + struct wl_buffer *buffer; + + buffer = display_get_buffer_for_surface(display, cairo_surface); + + wl_buffer_damage(buffer, x, y, width, height); +} + void window_damage(struct window *window, int32_t x, int32_t y, int32_t width, int32_t height) diff --git a/clients/window.h b/clients/window.h index bf1516ac..2597592a 100644 --- a/clients/window.h +++ b/clients/window.h @@ -193,6 +193,10 @@ enum window_buffer_type { WINDOW_BUFFER_TYPE_SHM, }; +void +display_surface_damage(struct display *display, cairo_surface_t *cairo_surface, + int32_t x, int32_t y, int32_t width, int32_t height); + void window_set_buffer_type(struct window *window, enum window_buffer_type type); diff --git a/compositor/compositor.c b/compositor/compositor.c index 8856b7e1..a9949828 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -853,8 +853,6 @@ surface_damage(struct wl_client *client, { struct wlsc_surface *es = (struct wlsc_surface *) surface; - es->buffer->damage(es->buffer, surface, x, y, width, height); - wlsc_surface_damage_rectangle(es, x, y, width, height); } diff --git a/compositor/shm.c b/compositor/shm.c index 4c17a08d..d0b40631 100644 --- a/compositor/shm.c +++ b/compositor/shm.c @@ -36,21 +36,53 @@ destroy_buffer(struct wl_resource *resource, struct wl_client *client) { struct wlsc_shm_buffer *buffer = container_of(resource, struct wlsc_shm_buffer, buffer.resource); + struct wlsc_compositor *compositor = + (struct wlsc_compositor *) buffer->buffer.compositor; + struct wlsc_surface *es; if (buffer->mapped) munmap(buffer->data, buffer->stride * buffer->buffer.height); else free(buffer->data); + + wl_list_for_each(es, &compositor->surface_list, link) + if (es->buffer == (struct wl_buffer *) buffer) + es->buffer = NULL; + free(buffer); } +static void +buffer_damage(struct wl_client *client, struct wl_buffer *buffer_base, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + struct wlsc_shm_buffer *buffer = + (struct wlsc_shm_buffer *) buffer_base; + struct wlsc_compositor *compositor = + (struct wlsc_compositor *) buffer->buffer.compositor; + struct wlsc_surface *es; + + wl_list_for_each(es, &compositor->surface_list, link) { + if (es->buffer != buffer_base) + continue; + + glBindTexture(GL_TEXTURE_2D, es->texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, + buffer->buffer.width, buffer->buffer.height, 0, + GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer->data); + /* Hmm, should use glTexSubImage2D() here but GLES2 doesn't + * support any unpack attributes except GL_UNPACK_ALIGNMENT. */ + } +} + static void buffer_destroy(struct wl_client *client, struct wl_buffer *buffer) { - // wl_resource_destroy(&buffer->base, client); + wl_resource_destroy(&buffer->resource, client); } const static struct wl_buffer_interface buffer_interface = { + buffer_damage, buffer_destroy }; @@ -73,24 +105,6 @@ shm_buffer_attach(struct wl_buffer *buffer_base, struct wl_surface *surface) es->visual = buffer->buffer.visual; } -static void -shm_buffer_damage(struct wl_buffer *buffer_base, - struct wl_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - struct wlsc_surface *es = (struct wlsc_surface *) surface; - struct wlsc_shm_buffer *buffer = - (struct wlsc_shm_buffer *) buffer_base; - - glBindTexture(GL_TEXTURE_2D, es->texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, - buffer->buffer.width, buffer->buffer.height, 0, - GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer->data); - - /* Hmm, should use glTexSubImage2D() here but GLES2 doesn't - * support any unpack attributes except GL_UNPACK_ALIGNMENT. */ -} - static struct wlsc_shm_buffer * wlsc_shm_buffer_init(struct wlsc_compositor *compositor, int32_t width, int32_t height, @@ -108,7 +122,6 @@ wlsc_shm_buffer_init(struct wlsc_compositor *compositor, buffer->buffer.height = height; buffer->buffer.visual = visual; buffer->buffer.attach = shm_buffer_attach; - buffer->buffer.damage = shm_buffer_damage; buffer->stride = stride; buffer->data = data;