Simplify shm buffer handling

There was a lot of code here to do a lot of work we didn't need to do.
If we damage a surface with a shm buffer attached, all we need to do
is to re-upload the damaged region to the texture.  As for drm buffers,
we don't assume anything changes on attach and only update the
regions the client tells us to update in the damage request.
dev
Kristian Høgsberg 13 years ago
parent 42b4f80116
commit 9629fe3206
  1. 1
      clients/simple-shm.c
  2. 5
      clients/simple-touch.c
  3. 2
      clients/smoke.c
  4. 26
      clients/window.c
  5. 94
      src/compositor.c
  6. 1
      src/compositor.h

@ -142,7 +142,6 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
offset = time >> 4; offset = time >> 4;
for (i = 0; i < end; i++) for (i = 0; i < end; i++)
p[i] = (i + offset) * 0x0080401; p[i] = (i + offset) * 0x0080401;
wl_buffer_damage(window->buffer, 0, 0, window->width, window->height);
wl_surface_attach(window->surface, window->buffer, 0, 0); wl_surface_attach(window->surface, window->buffer, 0, 0);
wl_surface_damage(window->surface, wl_surface_damage(window->surface,

@ -184,9 +184,7 @@ touch_paint(struct touch *touch, int32_t x, int32_t y, int32_t id)
p += touch->width; p += touch->width;
p[1] = c; p[1] = c;
wl_buffer_damage(touch->buffer, 0, 0, touch->width, touch->height); wl_surface_damage(touch->surface, 0, 0, touch->width, touch->height);
wl_surface_damage(touch->surface,
0, 0, touch->width, touch->height);
} }
static void static void
@ -312,7 +310,6 @@ touch_create(int width, int height)
wl_surface_set_user_data(touch->surface, touch); wl_surface_set_user_data(touch->surface, touch);
memset(touch->data, 64, width * height * 4); memset(touch->data, 64, width * height * 4);
wl_buffer_damage(touch->buffer, 0, 0, width, height);
wl_surface_attach(touch->surface, touch->buffer, 0, 0); wl_surface_attach(touch->surface, touch->buffer, 0, 0);
wl_surface_damage(touch->surface, 0, 0, width, height); wl_surface_damage(touch->surface, 0, 0, width, height);

@ -220,8 +220,6 @@ redraw_handler(struct widget *widget, void *data)
render(smoke, surface); render(smoke, surface);
display_surface_damage(smoke->display, surface,
0, 0, smoke->width, smoke->height);
window_damage(smoke->window, 0, 0, smoke->width, smoke->height); window_damage(smoke->window, 0, 0, smoke->width, smoke->height);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);

@ -782,21 +782,8 @@ window_attach_surface(struct window *window)
void void
window_flush(struct window *window) window_flush(struct window *window)
{ {
if (window->cairo_surface) { 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); window_attach_surface(window);
}
} }
void void
@ -2279,17 +2266,6 @@ window_get_title(struct window *window)
return window->title; 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 void
window_damage(struct window *window, int32_t x, int32_t y, window_damage(struct window *window, int32_t x, int32_t y,
int32_t width, int32_t height) int32_t width, int32_t height)

@ -212,7 +212,6 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init(&surface->link); wl_list_init(&surface->link);
wl_list_init(&surface->layer_link); wl_list_init(&surface->layer_link);
wl_list_init(&surface->buffer_link);
surface->surface.resource.client = NULL; surface->surface.resource.client = NULL;
@ -637,8 +636,6 @@ destroy_surface(struct wl_resource *resource)
compositor->destroy_image(compositor->display, compositor->destroy_image(compositor->display,
surface->image); surface->image);
wl_list_remove(&surface->buffer_link);
pixman_region32_fini(&surface->transform.boundingbox); pixman_region32_fini(&surface->transform.boundingbox);
pixman_region32_fini(&surface->damage); pixman_region32_fini(&surface->damage);
pixman_region32_fini(&surface->opaque); pixman_region32_fini(&surface->opaque);
@ -663,7 +660,6 @@ weston_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface)
{ {
struct weston_surface *es = (struct weston_surface *) surface; struct weston_surface *es = (struct weston_surface *) surface;
struct weston_compositor *ec = es->compositor; struct weston_compositor *ec = es->compositor;
struct wl_list *surfaces_attached_to;
if (!es->texture) { if (!es->texture) {
glGenTextures(1, &es->texture); glGenTextures(1, &es->texture);
@ -679,15 +675,6 @@ weston_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface)
if (wl_buffer_is_shm(buffer)) { if (wl_buffer_is_shm(buffer)) {
es->pitch = wl_shm_buffer_get_stride(buffer) / 4; es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
es->pitch, buffer->height, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE,
wl_shm_buffer_get_data(buffer));
surfaces_attached_to = buffer->user_data;
wl_list_remove(&es->buffer_link);
wl_list_insert(surfaces_attached_to, &es->buffer_link);
} else { } else {
if (es->image != EGL_NO_IMAGE_KHR) if (es->image != EGL_NO_IMAGE_KHR)
ec->destroy_image(ec->display, es->image); ec->destroy_image(ec->display, es->image);
@ -1187,6 +1174,17 @@ surface_damage(struct wl_client *client,
struct weston_surface *es = resource->data; struct weston_surface *es = resource->data;
weston_surface_damage_rectangle(es, x, y, width, height); weston_surface_damage_rectangle(es, x, y, width, height);
if (es->buffer && wl_buffer_is_shm(es->buffer)) {
glBindTexture(GL_TEXTURE_2D, es->texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
es->pitch, es->buffer->height, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE,
wl_shm_buffer_get_data(es->buffer));
/* Hmm, should use glTexSubImage2D() here but GLES2 doesn't
* support any unpack attributes except GL_UNPACK_ALIGNMENT. */
}
} }
static void static void
@ -1877,6 +1875,9 @@ input_device_attach(struct wl_client *client,
if (device->input_device.pointer_focus->resource.client != client) if (device->input_device.pointer_focus->resource.client != client)
return; return;
if (device->sprite->buffer)
wl_list_remove(&device->sprite->buffer_destroy_listener.link);
if (!buffer_resource) { if (!buffer_resource) {
if (device->sprite->output) if (device->sprite->output)
weston_surface_unmap(device->sprite); weston_surface_unmap(device->sprite);
@ -1897,8 +1898,13 @@ input_device_attach(struct wl_client *client,
device->input_device.y - device->hotspot_y, device->input_device.y - device->hotspot_y,
buffer->width, buffer->height); buffer->width, buffer->height);
device->sprite->buffer = buffer;
wl_list_insert(buffer->resource.destroy_listener_list.prev,
&device->sprite->buffer_destroy_listener.link);
weston_buffer_attach(buffer, &device->sprite->surface); weston_buffer_attach(buffer, &device->sprite->surface);
weston_surface_damage(device->sprite); surface_damage(NULL, &device->sprite->surface.resource,
0, 0, buffer->width, buffer->height);
} }
const static struct wl_input_device_interface input_device_interface = { const static struct wl_input_device_interface input_device_interface = {
@ -1946,6 +1952,7 @@ weston_input_device_init(struct weston_input_device *device,
device, bind_input_device); device, bind_input_device);
device->sprite = weston_surface_create(ec); device->sprite = weston_surface_create(ec);
device->sprite->surface.resource.data = device->sprite;
device->compositor = ec; device->compositor = ec;
device->hotspot_x = 16; device->hotspot_x = 16;
@ -2272,61 +2279,6 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
&wl_output_interface, output, bind_output); &wl_output_interface, output, bind_output);
} }
static void
shm_buffer_created(struct wl_buffer *buffer)
{
struct wl_list *surfaces_attached_to;
surfaces_attached_to = malloc(sizeof *surfaces_attached_to);
if (!surfaces_attached_to) {
buffer->user_data = NULL;
return;
}
wl_list_init(surfaces_attached_to);
buffer->user_data = surfaces_attached_to;
}
static void
shm_buffer_damaged(struct wl_buffer *buffer,
int32_t x, int32_t y, int32_t width, int32_t height)
{
struct wl_list *surfaces_attached_to = buffer->user_data;
struct weston_surface *es;
GLsizei tex_width = wl_shm_buffer_get_stride(buffer) / 4;
wl_list_for_each(es, surfaces_attached_to, buffer_link) {
glBindTexture(GL_TEXTURE_2D, es->texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
tex_width, buffer->height, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE,
wl_shm_buffer_get_data(buffer));
/* Hmm, should use glTexSubImage2D() here but GLES2 doesn't
* support any unpack attributes except GL_UNPACK_ALIGNMENT. */
}
}
static void
shm_buffer_destroyed(struct wl_buffer *buffer)
{
struct wl_list *surfaces_attached_to = buffer->user_data;
struct weston_surface *es, *next;
wl_list_for_each_safe(es, next, surfaces_attached_to, buffer_link) {
wl_list_remove(&es->buffer_link);
wl_list_init(&es->buffer_link);
}
free(surfaces_attached_to);
}
const static struct wl_shm_callbacks shm_callbacks = {
shm_buffer_created,
shm_buffer_damaged,
shm_buffer_destroyed
};
static void static void
compositor_bind(struct wl_client *client, compositor_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id) void *data, uint32_t version, uint32_t id)
@ -2349,7 +2301,7 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
ec, compositor_bind)) ec, compositor_bind))
return -1; return -1;
ec->shm = wl_shm_init(display, &shm_callbacks); wl_display_init_shm(display);
ec->image_target_texture_2d = ec->image_target_texture_2d =
(void *) eglGetProcAddress("glEGLImageTargetTexture2DOES"); (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
@ -2429,8 +2381,6 @@ weston_compositor_shutdown(struct weston_compositor *ec)
weston_binding_list_destroy_all(&ec->binding_list); weston_binding_list_destroy_all(&ec->binding_list);
wl_shm_finish(ec->shm);
wl_array_release(&ec->vertices); wl_array_release(&ec->vertices);
wl_array_release(&ec->indices); wl_array_release(&ec->indices);
} }

@ -284,7 +284,6 @@ struct weston_surface {
int32_t pitch; int32_t pitch;
struct wl_list link; struct wl_list link;
struct wl_list layer_link; struct wl_list layer_link;
struct wl_list buffer_link;
struct weston_shader *shader; struct weston_shader *shader;
GLfloat color[4]; GLfloat color[4];
uint32_t alpha; uint32_t alpha;

Loading…
Cancel
Save