From: Benjamin Franzke Date: Tue, 8 Mar 2011 10:32:57 +0000 (+0100) Subject: Make use of wayland-server shm common code X-Git-Tag: 0.85.0~528 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=315b3dc73b0639c526cdf78ddf74655e2177fa99;p=profile%2Fivi%2Fweston.git Make use of wayland-server shm common code --- diff --git a/compositor/Makefile.am b/compositor/Makefile.am index 9c62355..47f8091 100644 --- a/compositor/Makefile.am +++ b/compositor/Makefile.am @@ -37,7 +37,6 @@ compositor_SOURCES = \ screenshooter.c \ screenshooter-protocol.c \ screenshooter-server-protocol.h \ - shm.c \ $(drm_compositor_sources) \ $(openwfd_compositor_sources) \ $(x11_compositor_sources) \ diff --git a/compositor/compositor.c b/compositor/compositor.c index bebf8dc..c9928c3 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -296,17 +296,34 @@ wlsc_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface) { struct wlsc_surface *es = (struct wlsc_surface *) surface; struct wlsc_compositor *ec = es->compositor; + struct wl_list *surfaces_attached_to; - if (wlsc_is_shm_buffer(buffer)) { - wlsc_shm_buffer_attach(buffer, surface); + if (es->saved_texture != 0) + es->texture = es->saved_texture; + + glBindTexture(GL_TEXTURE_2D, es->texture); + + if (wl_buffer_is_shm(buffer)) { + /* Unbind any EGLImage texture that may be bound, so we don't + * overwrite it.*/ + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, + 0, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, + buffer->width, buffer->height, 0, + GL_BGRA_EXT, GL_UNSIGNED_BYTE, + wl_shm_buffer_get_data(buffer)); + es->visual = buffer->visual; + + surfaces_attached_to = buffer->user_data; + + if (es->buffer) + wl_list_remove(&es->buffer_link); + wl_list_insert(surfaces_attached_to, &es->buffer_link); } else { es->image = eglCreateImageKHR(ec->display, NULL, EGL_WAYLAND_BUFFER_WL, buffer, NULL); - if (es->saved_texture != 0) - es->texture = es->saved_texture; - glBindTexture(GL_TEXTURE_2D, es->texture); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, es->image); es->visual = buffer->visual; } @@ -1517,6 +1534,60 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c, wlsc_output_post_geometry); } +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 wlsc_surface *es; + + wl_list_for_each(es, surfaces_attached_to, buffer_link) { + glBindTexture(GL_TEXTURE_2D, es->texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, + buffer->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 wlsc_surface *es, *next; + + wl_list_for_each_safe(es, next, surfaces_attached_to, buffer_link) { + es->buffer = NULL; + wl_list_remove(&es->buffer_link); + } + + free(surfaces_attached_to); +} + +const static struct wl_shm_callbacks shm_callbacks = { + shm_buffer_created, + shm_buffer_damaged, + shm_buffer_destroyed +}; + int wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display) { @@ -1527,7 +1598,7 @@ wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display) wl_compositor_init(&ec->compositor, &compositor_interface, display); - wlsc_shm_init(ec); + ec->shm = wl_shm_init(display, &shm_callbacks); eglBindWaylandDisplayWL(ec->display, ec->wl_display); wl_list_init(&ec->surface_list); diff --git a/compositor/compositor.h b/compositor/compositor.h index ae0e70f..6a7c0be 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -82,10 +82,6 @@ struct wlsc_input_device { struct wl_selection *selection; }; -struct wlsc_shm { - struct wl_object object; -}; - struct wlsc_sprite { GLuint texture; EGLImageKHR image; @@ -97,7 +93,8 @@ struct wlsc_sprite { struct wlsc_compositor { struct wl_compositor compositor; - struct wlsc_shm shm; + struct wl_shm *shm; + EGLDisplay display; EGLContext context; EGLConfig config; @@ -246,18 +243,6 @@ uint32_t get_time(void); int -wlsc_is_shm_buffer(struct wl_buffer *buffer); - -void -wlsc_shm_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface); - -struct wl_buffer * -wlsc_shm_buffer_create(struct wlsc_compositor *ec, - int32_t width, int32_t height, - int32_t stride, struct wl_visual *visual, - void *data); - -int wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display); void wlsc_output_move(struct wlsc_output *output, int x, int y); @@ -272,9 +257,6 @@ wlsc_input_device_init(struct wlsc_input_device *device, struct wlsc_compositor *ec); int -wlsc_shm_init(struct wlsc_compositor *ec); - -int wlsc_shell_init(struct wlsc_compositor *ec); void diff --git a/compositor/shm.c b/compositor/shm.c deleted file mode 100644 index d27056a..0000000 --- a/compositor/shm.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright © 2010 Kristian Høgsberg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include - -#include "compositor.h" - -struct wlsc_shm_buffer { - struct wl_buffer buffer; - struct wl_list surfaces_attached_to; - int32_t stride; - void *data; - int mapped; -}; - -static void -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_surface *es, *next; - - if (buffer->mapped) - munmap(buffer->data, buffer->stride * buffer->buffer.height); - else - free(buffer->data); - - wl_list_for_each_safe(es, next, &buffer->surfaces_attached_to, - buffer_link) { - es->buffer = NULL; - wl_list_remove(&es->buffer_link); - } - - 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_surface *es; - - wl_list_for_each(es, &buffer->surfaces_attached_to, buffer_link) { - 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->resource, client); -} - -const static struct wl_buffer_interface buffer_interface = { - buffer_damage, - buffer_destroy -}; - -int -wlsc_is_shm_buffer(struct wl_buffer *buffer) -{ - return buffer->resource.object.implementation == - (void (**)(void)) &buffer_interface; -} - -void -wlsc_shm_buffer_attach(struct wl_buffer *buffer_base, - struct wl_surface *surface) -{ - 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); - - /* Unbind any EGLImage texture that may be bound, so we don't - * overwrite it.*/ - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, - 0, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, - buffer->buffer.width, buffer->buffer.height, 0, - GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer->data); - es->visual = buffer->buffer.visual; - - if (es->buffer) - wl_list_remove(&es->buffer_link); - wl_list_insert(&buffer->surfaces_attached_to, &es->buffer_link); -} - -static struct wlsc_shm_buffer * -wlsc_shm_buffer_init(struct wlsc_compositor *compositor, - int32_t width, int32_t height, - int32_t stride, struct wl_visual *visual, - void *data) -{ - struct wlsc_shm_buffer *buffer; - - buffer = malloc(sizeof *buffer); - if (buffer == NULL) - return NULL; - - buffer->buffer.compositor = &compositor->compositor; - buffer->buffer.width = width; - buffer->buffer.height = height; - buffer->buffer.visual = visual; - buffer->stride = stride; - buffer->data = data; - - wl_list_init(&buffer->surfaces_attached_to); - - buffer->buffer.resource.object.interface = &wl_buffer_interface; - buffer->buffer.resource.object.implementation = (void (**)(void)) - &buffer_interface; - - buffer->buffer.resource.destroy = destroy_buffer; - - return buffer; -} - -static void -shm_create_buffer(struct wl_client *client, struct wl_shm *shm, - uint32_t id, int fd, int32_t width, int32_t height, - uint32_t stride, struct wl_visual *visual) -{ - struct wlsc_compositor *compositor = - container_of((struct wlsc_shm *) shm, - struct wlsc_compositor, shm); - struct wlsc_shm_buffer *buffer; - void *data; - - /* FIXME: Define a real exception event instead of abusing the - * display.invalid_object error */ - if (visual->object.interface != &wl_visual_interface) { - wl_client_post_event(client, - (struct wl_object *) compositor->wl_display, - WL_DISPLAY_INVALID_OBJECT, 0); - fprintf(stderr, "invalid visual in create_buffer\n"); - close(fd); - return; - } - - if (width < 0 || height < 0 || stride < width) { - wl_client_post_event(client, - (struct wl_object *) compositor->wl_display, - WL_DISPLAY_INVALID_OBJECT, 0); - fprintf(stderr, - "invalid width, height or stride in create_buffer\n"); - close(fd); - return; - } - - data = mmap(NULL, stride * height, PROT_READ, MAP_SHARED, fd, 0); - - close(fd); - if (data == MAP_FAILED) { - /* FIXME: Define a real exception event instead of - * abusing this one */ - wl_client_post_event(client, - (struct wl_object *) compositor->wl_display, - WL_DISPLAY_INVALID_OBJECT, 0); - fprintf(stderr, "failed to create image for fd %d\n", fd); - return; - } - - buffer = wlsc_shm_buffer_init(compositor, width, height, - stride, visual, data); - if (buffer == NULL) { - munmap(data, stride * height); - wl_client_post_no_memory(client); - return; - } - buffer->mapped = 1; - - buffer->buffer.resource.object.id = id; - - wl_client_add_resource(client, &buffer->buffer.resource); -} - -const static struct wl_shm_interface shm_interface = { - shm_create_buffer -}; - -int -wlsc_shm_init(struct wlsc_compositor *ec) -{ - struct wlsc_shm *shm = &ec->shm; - - shm->object.interface = &wl_shm_interface; - shm->object.implementation = (void (**)(void)) &shm_interface; - wl_display_add_object(ec->wl_display, &shm->object); - wl_display_add_global(ec->wl_display, &shm->object, NULL); - - return 0; -}