Make use of wayland-server shm common code
authorBenjamin Franzke <benjaminfranzke@googlemail.com>
Tue, 8 Mar 2011 10:32:57 +0000 (11:32 +0100)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 22 Apr 2011 15:53:50 +0000 (11:53 -0400)
compositor/Makefile.am
compositor/compositor.c
compositor/compositor.h
compositor/shm.c [deleted file]

index 9c62355..47f8091 100644 (file)
@@ -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)               \
index bebf8dc..c9928c3 100644 (file)
@@ -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);
index ae0e70f..6a7c0be 100644 (file)
@@ -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 (file)
index d27056a..0000000
+++ /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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#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;
-}