Move buffer creation and buffer details into drm.c and shm.c
This commit is contained in:
parent
e4762a6ac1
commit
8525a50362
@ -354,7 +354,13 @@ drm_compositor_create(struct wl_display *display, int connector)
|
|||||||
fprintf(stderr, "failed to initialize egl\n");
|
fprintf(stderr, "failed to initialize egl\n");
|
||||||
return NULL;
|
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 */
|
/* Can't init base class until we have a current egl context */
|
||||||
if (wlsc_compositor_init(&ec->base, display) < 0)
|
if (wlsc_compositor_init(&ec->base, display) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -371,10 +377,6 @@ drm_compositor_create(struct wl_display *display, int connector)
|
|||||||
wl_event_loop_add_fd(loop, ec->base.drm.fd,
|
wl_event_loop_add_fd(loop, ec->base.drm.fd,
|
||||||
WL_EVENT_READABLE, on_drm_input, ec);
|
WL_EVENT_READABLE, on_drm_input, ec);
|
||||||
ec->tty = tty_create(&ec->base);
|
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;
|
return &ec->base;
|
||||||
}
|
}
|
||||||
|
@ -278,9 +278,7 @@ wayland_compositor_create_output(struct wayland_compositor *c,
|
|||||||
static struct wl_buffer *
|
static struct wl_buffer *
|
||||||
create_invisible_pointer(struct wayland_compositor *c)
|
create_invisible_pointer(struct wayland_compositor *c)
|
||||||
{
|
{
|
||||||
struct wlsc_drm_buffer *wlsc_buffer;
|
|
||||||
struct wl_buffer *buffer;
|
struct wl_buffer *buffer;
|
||||||
int name, stride;
|
|
||||||
struct wl_visual *visual;
|
struct wl_visual *visual;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
const int width = 1, height = 1;
|
const int width = 1, height = 1;
|
||||||
@ -294,18 +292,8 @@ create_invisible_pointer(struct wayland_compositor *c)
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
visual = wl_display_get_premultiplied_argb_visual(c->parent.display);
|
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;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,6 +676,11 @@ x11_compositor_create(struct wl_display *display, int width, int height)
|
|||||||
if (x11_compositor_init_egl(c) < 0)
|
if (x11_compositor_init_egl(c) < 0)
|
||||||
return NULL;
|
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 */
|
/* Can't init base class until we have a current egl context */
|
||||||
if (wlsc_compositor_init(&c->base, display) < 0)
|
if (wlsc_compositor_init(&c->base, display) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -693,9 +698,5 @@ x11_compositor_create(struct wl_display *display, int width, int height)
|
|||||||
WL_EVENT_READABLE,
|
WL_EVENT_READABLE,
|
||||||
x11_compositor_handle_event, c);
|
x11_compositor_handle_event, c);
|
||||||
|
|
||||||
c->base.destroy = x11_destroy;
|
|
||||||
c->base.authenticate = x11_authenticate;
|
|
||||||
c->base.present = x11_compositor_present;
|
|
||||||
|
|
||||||
return &c->base;
|
return &c->base;
|
||||||
}
|
}
|
||||||
|
@ -188,33 +188,76 @@ destroy_surface(struct wl_resource *resource, struct wl_client *client)
|
|||||||
wlsc_compositor_schedule_repaint(compositor);
|
wlsc_compositor_schedule_repaint(compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static struct wl_buffer *
|
||||||
texture_from_png(const char *filename, int width, int height)
|
create_buffer_from_png(struct wlsc_compositor *ec,
|
||||||
|
const char *filename, int width, int height)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
void *data;
|
int stride, i, n_channels;
|
||||||
GLenum format;
|
unsigned char *pixels, *end, *argb_pixels, *s, *d;
|
||||||
|
struct wl_buffer *buffer;
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
|
pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
|
||||||
width, height,
|
width, height,
|
||||||
FALSE, &error);
|
FALSE, &error);
|
||||||
if (error != NULL)
|
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))
|
argb_pixels = malloc (height * width * 4);
|
||||||
format = GL_RGBA;
|
if (argb_pixels == NULL) {
|
||||||
else
|
gdk_pixbuf_unref(pixbuf);
|
||||||
format = GL_RGB;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
|
if (n_channels == 4) {
|
||||||
format, GL_UNSIGNED_BYTE, data);
|
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);
|
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 {
|
static const struct {
|
||||||
@ -238,25 +281,15 @@ static void
|
|||||||
create_pointer_images(struct wlsc_compositor *ec)
|
create_pointer_images(struct wlsc_compositor *ec)
|
||||||
{
|
{
|
||||||
int i, count;
|
int i, count;
|
||||||
GLuint texture;
|
|
||||||
const int width = 32, height = 32;
|
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);
|
count = ARRAY_LENGTH(pointer_images);
|
||||||
ec->pointer_buffers = malloc(count * sizeof *ec->pointer_buffers);
|
ec->pointer_buffers = malloc(count * sizeof *ec->pointer_buffers);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
ec->pointer_buffers[i] =
|
ec->pointer_buffers[i] =
|
||||||
wlsc_drm_buffer_create(ec, width, height,
|
create_buffer_from_png(ec,
|
||||||
&ec->compositor.argb_visual);
|
pointer_images[i].filename,
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
|
width, height);
|
||||||
ec->pointer_buffers[i]->image);
|
|
||||||
texture_from_png(pointer_images[i].filename, width, height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,37 +297,20 @@ static struct wlsc_surface *
|
|||||||
background_create(struct wlsc_output *output, const char *filename)
|
background_create(struct wlsc_output *output, const char *filename)
|
||||||
{
|
{
|
||||||
struct wlsc_surface *background;
|
struct wlsc_surface *background;
|
||||||
GdkPixbuf *pixbuf;
|
struct wlsc_compositor *ec = output->compositor;
|
||||||
GError *error = NULL;
|
struct wl_buffer *buffer;
|
||||||
void *data;
|
|
||||||
GLenum format;
|
|
||||||
|
|
||||||
background = wlsc_surface_create(output->compositor,
|
background = wlsc_surface_create(output->compositor,
|
||||||
&output->compositor->compositor.rgb_visual,
|
&ec->compositor.premultiplied_argb_visual,
|
||||||
output->x, output->y,
|
output->x, output->y,
|
||||||
output->width, output->height);
|
output->width, output->height);
|
||||||
if (background == NULL)
|
if (background == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
|
buffer = create_buffer_from_png(output->compositor,
|
||||||
output->width,
|
filename,
|
||||||
output->height,
|
output->width, output->height);
|
||||||
FALSE, &error);
|
buffer->attach(buffer, &background->surface);
|
||||||
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);
|
|
||||||
|
|
||||||
return background;
|
return background;
|
||||||
}
|
}
|
||||||
@ -500,7 +516,7 @@ wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
|
|||||||
(struct wlsc_compositor *) device->input_device.compositor;
|
(struct wlsc_compositor *) device->input_device.compositor;
|
||||||
|
|
||||||
wlsc_input_device_attach(device,
|
wlsc_input_device_attach(device,
|
||||||
&compositor->pointer_buffers[type]->buffer,
|
compositor->pointer_buffers[type],
|
||||||
pointer_images[type].hotspot_x,
|
pointer_images[type].hotspot_x,
|
||||||
pointer_images[type].hotspot_y);
|
pointer_images[type].hotspot_y);
|
||||||
}
|
}
|
||||||
|
@ -77,21 +77,10 @@ struct wlsc_drm {
|
|||||||
char *filename;
|
char *filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlsc_drm_buffer {
|
|
||||||
struct wl_buffer buffer;
|
|
||||||
EGLImageKHR image;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wlsc_shm {
|
struct wlsc_shm {
|
||||||
struct wl_object object;
|
struct wl_object object;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlsc_shm_buffer {
|
|
||||||
struct wl_buffer buffer;
|
|
||||||
int32_t stride;
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wlsc_compositor {
|
struct wlsc_compositor {
|
||||||
struct wl_compositor compositor;
|
struct wl_compositor compositor;
|
||||||
|
|
||||||
@ -101,7 +90,7 @@ struct wlsc_compositor {
|
|||||||
EGLContext context;
|
EGLContext context;
|
||||||
GLuint fbo, vbo;
|
GLuint fbo, vbo;
|
||||||
GLuint proj_uniform, tex_uniform;
|
GLuint proj_uniform, tex_uniform;
|
||||||
struct wlsc_drm_buffer **pointer_buffers;
|
struct wl_buffer **pointer_buffers;
|
||||||
struct wl_display *wl_display;
|
struct wl_display *wl_display;
|
||||||
|
|
||||||
/* We implement the shell interface. */
|
/* We implement the shell interface. */
|
||||||
@ -125,6 +114,10 @@ struct wlsc_compositor {
|
|||||||
void (*destroy)(struct wlsc_compositor *ec);
|
void (*destroy)(struct wlsc_compositor *ec);
|
||||||
int (*authenticate)(struct wlsc_compositor *c, uint32_t id);
|
int (*authenticate)(struct wlsc_compositor *c, uint32_t id);
|
||||||
void (*present)(struct wlsc_compositor *c);
|
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)
|
#define MODIFIER_CTRL (1 << 8)
|
||||||
@ -163,9 +156,10 @@ wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs);
|
|||||||
void
|
void
|
||||||
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor);
|
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor);
|
||||||
|
|
||||||
struct wlsc_drm_buffer *
|
struct wl_buffer *
|
||||||
wlsc_drm_buffer_create(struct wlsc_compositor *ec,
|
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
|
int
|
||||||
wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display);
|
wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display);
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
|
|
||||||
#include "compositor.h"
|
#include "compositor.h"
|
||||||
|
|
||||||
|
struct wlsc_drm_buffer {
|
||||||
|
struct wl_buffer buffer;
|
||||||
|
EGLImageKHR image;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drm_authenticate(struct wl_client *client,
|
drm_authenticate(struct wl_client *client,
|
||||||
struct wl_drm *drm_base, uint32_t id)
|
struct wl_drm *drm_base, uint32_t id)
|
||||||
@ -197,12 +202,13 @@ wlsc_drm_init(struct wlsc_compositor *ec, int fd, const char *filename)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlsc_drm_buffer *
|
struct wl_buffer *
|
||||||
wlsc_drm_buffer_create(struct wlsc_compositor *ec,
|
wlsc_drm_buffer_create(struct wlsc_compositor *ec, int width, int height,
|
||||||
int width, int height, struct wl_visual *visual)
|
struct wl_visual *visual, const void *data)
|
||||||
{
|
{
|
||||||
struct wlsc_drm_buffer *buffer;
|
struct wlsc_drm_buffer *buffer;
|
||||||
EGLImageKHR image;
|
EGLImageKHR image;
|
||||||
|
GLuint texture;
|
||||||
|
|
||||||
EGLint image_attribs[] = {
|
EGLint image_attribs[] = {
|
||||||
EGL_WIDTH, 0,
|
EGL_WIDTH, 0,
|
||||||
@ -222,5 +228,19 @@ wlsc_drm_buffer_create(struct wlsc_compositor *ec,
|
|||||||
buffer = wlsc_drm_buffer_create_for_image(ec, image,
|
buffer = wlsc_drm_buffer_create_for_image(ec, image,
|
||||||
width, height, visual);
|
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;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,12 @@
|
|||||||
|
|
||||||
#include "compositor.h"
|
#include "compositor.h"
|
||||||
|
|
||||||
|
struct wlsc_shm_buffer {
|
||||||
|
struct wl_buffer buffer;
|
||||||
|
int32_t stride;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_buffer(struct wl_resource *resource, struct wl_client *client)
|
destroy_buffer(struct wl_resource *resource, struct wl_client *client)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user