mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	Move buffer creation and buffer details into drm.c and shm.c
This commit is contained in:
		
							parent
							
								
									e4762a6ac1
								
							
						
					
					
						commit
						8525a50362
					
				
					 7 changed files with 118 additions and 91 deletions
				
			
		| 
						 | 
				
			
			@ -355,6 +355,12 @@ drm_compositor_create(struct wl_display *display, int connector)
 | 
			
		|||
		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;
 | 
			
		||||
| 
						 | 
				
			
			@ -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_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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -278,9 +278,7 @@ wayland_compositor_create_output(struct wayland_compositor *c,
 | 
			
		|||
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;
 | 
			
		||||
| 
						 | 
				
			
			@ -294,18 +292,8 @@ create_invisible_pointer(struct wayland_compositor *c)
 | 
			
		|||
	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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -676,6 +676,11 @@ x11_compositor_create(struct wl_display *display, int width, int height)
 | 
			
		|||
	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;
 | 
			
		||||
| 
						 | 
				
			
			@ -693,9 +698,5 @@ x11_compositor_create(struct wl_display *display, int width, int height)
 | 
			
		|||
				     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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -188,33 +188,76 @@ destroy_surface(struct wl_resource *resource, struct wl_client *client)
 | 
			
		|||
	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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -238,25 +281,15 @@ static void
 | 
			
		|||
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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -264,37 +297,20 @@ static struct wlsc_surface *
 | 
			
		|||
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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +516,7 @@ wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
 | 
			
		|||
		(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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,21 +77,10 @@ struct wlsc_drm {
 | 
			
		|||
	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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -101,7 +90,7 @@ struct wlsc_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. */
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +114,10 @@ struct wlsc_compositor {
 | 
			
		|||
	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)
 | 
			
		||||
| 
						 | 
				
			
			@ -163,9 +156,10 @@ wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs);
 | 
			
		|||
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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,11 @@
 | 
			
		|||
 | 
			
		||||
#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)
 | 
			
		||||
| 
						 | 
				
			
			@ -197,12 +202,13 @@ wlsc_drm_init(struct wlsc_compositor *ec, int fd, const char *filename)
 | 
			
		|||
	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,
 | 
			
		||||
| 
						 | 
				
			
			@ -222,5 +228,19 @@ wlsc_drm_buffer_create(struct wlsc_compositor *ec,
 | 
			
		|||
	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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,12 @@
 | 
			
		|||
 | 
			
		||||
#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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue