fprintf(stderr, "failed to initialize egl\n");
return NULL;
}
-
+
+ ec->base.destroy = drm_destroy;
+ ec->base.authenticate = drm_authenticate;
+ ec->base.present = drm_compositor_present;
+ ec->base.create_buffer = wlsc_drm_buffer_create;
+ ec->base.focus = 1;
+
/* Can't init base class until we have a current egl context */
if (wlsc_compositor_init(&ec->base, display) < 0)
return NULL;
wl_event_loop_add_fd(loop, ec->base.drm.fd,
WL_EVENT_READABLE, on_drm_input, ec);
ec->tty = tty_create(&ec->base);
- ec->base.destroy = drm_destroy;
- ec->base.authenticate = drm_authenticate;
- ec->base.present = drm_compositor_present;
- ec->base.focus = 1;
return &ec->base;
}
static struct wl_buffer *
create_invisible_pointer(struct wayland_compositor *c)
{
- struct wlsc_drm_buffer *wlsc_buffer;
struct wl_buffer *buffer;
- int name, stride;
struct wl_visual *visual;
GLuint texture;
const int width = 1, height = 1;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
visual = wl_display_get_premultiplied_argb_visual(c->parent.display);
- wlsc_buffer = wlsc_drm_buffer_create(&c->base, width, height, visual);
+ buffer = c->base.create_buffer(&c->base, width, height, visual, data);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, wlsc_buffer->image);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
- GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- eglExportDRMImageMESA(c->base.display, wlsc_buffer->image,
- &name, NULL, &stride);
-
- buffer = wl_drm_create_buffer(c->parent.drm, name,
- width, height,
- stride, visual);
return buffer;
}
if (x11_compositor_init_egl(c) < 0)
return NULL;
+ c->base.destroy = x11_destroy;
+ c->base.authenticate = x11_authenticate;
+ c->base.present = x11_compositor_present;
+ c->base.create_buffer = wlsc_drm_buffer_create;
+
/* Can't init base class until we have a current egl context */
if (wlsc_compositor_init(&c->base, display) < 0)
return NULL;
WL_EVENT_READABLE,
x11_compositor_handle_event, c);
- c->base.destroy = x11_destroy;
- c->base.authenticate = x11_authenticate;
- c->base.present = x11_compositor_present;
-
return &c->base;
}
wlsc_compositor_schedule_repaint(compositor);
}
-static int
-texture_from_png(const char *filename, int width, int height)
+static struct wl_buffer *
+create_buffer_from_png(struct wlsc_compositor *ec,
+ const char *filename, int width, int height)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
- void *data;
- GLenum format;
+ int stride, i, n_channels;
+ unsigned char *pixels, *end, *argb_pixels, *s, *d;
+ struct wl_buffer *buffer;
pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
width, height,
FALSE, &error);
if (error != NULL)
- return -1;
+ return NULL;
- data = gdk_pixbuf_get_pixels(pixbuf);
+ stride = gdk_pixbuf_get_rowstride(pixbuf);
+ pixels = gdk_pixbuf_get_pixels(pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels(pixbuf);
- if (gdk_pixbuf_get_has_alpha(pixbuf))
- format = GL_RGBA;
- else
- format = GL_RGB;
+ argb_pixels = malloc (height * width * 4);
+ if (argb_pixels == NULL) {
+ gdk_pixbuf_unref(pixbuf);
+ return NULL;
+ }
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
- format, GL_UNSIGNED_BYTE, data);
+ if (n_channels == 4) {
+ for (i = 0; i < height; i++) {
+ s = pixels + i * stride;
+ end = s + width * 4;
+ d = argb_pixels + i * width * 4;
+ while (s < end) {
+ unsigned int t;
+
+#define MULT(_d,c,a,t) \
+ do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
+
+ MULT(d[0], s[2], s[3], t);
+ MULT(d[1], s[1], s[3], t);
+ MULT(d[2], s[0], s[3], t);
+ d[3] = s[3];
+ s += 4;
+ d += 4;
+ }
+ }
+ } else if (n_channels == 3) {
+ for (i = 0; i < height; i++) {
+ s = pixels + i * stride;
+ end = s + width * 3;
+ d = argb_pixels + i * width * 4;
+ while (s < end) {
+ d[0] = s[2];
+ d[1] = s[1];
+ d[2] = s[0];
+ d[3] = 0xff;
+ s += 3;
+ d += 4;
+ }
+ }
+ }
gdk_pixbuf_unref(pixbuf);
- return 0;
+ buffer = ec->create_buffer(ec, width, height,
+ &ec->compositor.premultiplied_argb_visual,
+ argb_pixels);
+
+ free(argb_pixels);
+
+ return buffer;
}
static const struct {
create_pointer_images(struct wlsc_compositor *ec)
{
int i, count;
- GLuint texture;
const int width = 32, height = 32;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
count = ARRAY_LENGTH(pointer_images);
ec->pointer_buffers = malloc(count * sizeof *ec->pointer_buffers);
for (i = 0; i < count; i++) {
ec->pointer_buffers[i] =
- wlsc_drm_buffer_create(ec, width, height,
- &ec->compositor.argb_visual);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
- ec->pointer_buffers[i]->image);
- texture_from_png(pointer_images[i].filename, width, height);
+ create_buffer_from_png(ec,
+ pointer_images[i].filename,
+ width, height);
}
}
background_create(struct wlsc_output *output, const char *filename)
{
struct wlsc_surface *background;
- GdkPixbuf *pixbuf;
- GError *error = NULL;
- void *data;
- GLenum format;
+ struct wlsc_compositor *ec = output->compositor;
+ struct wl_buffer *buffer;
background = wlsc_surface_create(output->compositor,
- &output->compositor->compositor.rgb_visual,
+ &ec->compositor.premultiplied_argb_visual,
output->x, output->y,
output->width, output->height);
if (background == NULL)
return NULL;
- pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
- output->width,
- output->height,
- FALSE, &error);
- if (error != NULL) {
- free(background);
- return NULL;
- }
-
- data = gdk_pixbuf_get_pixels(pixbuf);
-
- if (gdk_pixbuf_get_has_alpha(pixbuf))
- format = GL_RGBA;
- else
- format = GL_RGB;
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
- output->width, output->height, 0,
- format, GL_UNSIGNED_BYTE, data);
+ buffer = create_buffer_from_png(output->compositor,
+ filename,
+ output->width, output->height);
+ buffer->attach(buffer, &background->surface);
return background;
}
(struct wlsc_compositor *) device->input_device.compositor;
wlsc_input_device_attach(device,
- &compositor->pointer_buffers[type]->buffer,
+ compositor->pointer_buffers[type],
pointer_images[type].hotspot_x,
pointer_images[type].hotspot_y);
}
char *filename;
};
-struct wlsc_drm_buffer {
- struct wl_buffer buffer;
- EGLImageKHR image;
-};
-
struct wlsc_shm {
struct wl_object object;
};
-struct wlsc_shm_buffer {
- struct wl_buffer buffer;
- int32_t stride;
- void *data;
-};
-
struct wlsc_compositor {
struct wl_compositor compositor;
EGLContext context;
GLuint fbo, vbo;
GLuint proj_uniform, tex_uniform;
- struct wlsc_drm_buffer **pointer_buffers;
+ struct wl_buffer **pointer_buffers;
struct wl_display *wl_display;
/* We implement the shell interface. */
void (*destroy)(struct wlsc_compositor *ec);
int (*authenticate)(struct wlsc_compositor *c, uint32_t id);
void (*present)(struct wlsc_compositor *c);
+ struct wl_buffer *(*create_buffer)(struct wlsc_compositor *c,
+ int32_t width, int32_t height,
+ struct wl_visual *visual,
+ const void *data);
};
#define MODIFIER_CTRL (1 << 8)
void
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor);
-struct wlsc_drm_buffer *
+struct wl_buffer *
wlsc_drm_buffer_create(struct wlsc_compositor *ec,
- int width, int height, struct wl_visual *visual);
+ int width, int height,
+ struct wl_visual *visual, const void *data);
int
wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display);
#include "compositor.h"
+struct wlsc_drm_buffer {
+ struct wl_buffer buffer;
+ EGLImageKHR image;
+};
+
static void
drm_authenticate(struct wl_client *client,
struct wl_drm *drm_base, uint32_t id)
return 0;
}
-struct wlsc_drm_buffer *
-wlsc_drm_buffer_create(struct wlsc_compositor *ec,
- int width, int height, struct wl_visual *visual)
+struct wl_buffer *
+wlsc_drm_buffer_create(struct wlsc_compositor *ec, int width, int height,
+ struct wl_visual *visual, const void *data)
{
struct wlsc_drm_buffer *buffer;
EGLImageKHR image;
+ GLuint texture;
EGLint image_attribs[] = {
EGL_WIDTH, 0,
buffer = wlsc_drm_buffer_create_for_image(ec, image,
width, height, visual);
- return buffer;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
+
+ glDeleteTextures(1, &texture);
+
+ return &buffer->buffer;
}
#include "compositor.h"
+struct wlsc_shm_buffer {
+ struct wl_buffer buffer;
+ int32_t stride;
+ void *data;
+};
+
static void
destroy_buffer(struct wl_resource *resource, struct wl_client *client)
{