summaryrefslogtreecommitdiff
path: root/src/surface.c
blob: 90e7bb03b540e3aa4ad872efc3346457b135fbd5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include "log.h"
#include "shm.h"
#include "surface.h"

#undef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))

void surface_initialise(
		struct surface *surface,
		struct wl_shm *wl_shm,
		struct image *texture)
{

	const int height = surface->height;
	const int stride = surface->stride;

	/* Double-buffered pool, so allocate space for two windows */
	surface->shm_pool_size =
		height
		* stride
		* 2;
	surface->shm_pool_fd = shm_allocate_file(surface->shm_pool_size);
	surface->shm_pool_data = mmap(
			NULL,
			surface->shm_pool_size,
			PROT_READ | PROT_WRITE,
			MAP_SHARED,
			surface->shm_pool_fd,
			0);
	surface->wl_shm_pool = wl_shm_create_pool(
			wl_shm,
			surface->shm_pool_fd,
			surface->shm_pool_size);

	for (int i = 0; i < 2; i++) {
		int offset = surface->height * surface->stride * i;
		surface->buffers[i] = wl_shm_pool_create_buffer(
				surface->wl_shm_pool,
				offset,
				surface->width,
				surface->height,
				surface->stride,
				WL_SHM_FORMAT_XRGB8888);
	}

	log_debug("Created shm file with size %d KiB.\n",
			surface->shm_pool_size / 1024);

	surface->index = 0;
}

void surface_destroy(struct surface *surface)
{
	wl_shm_pool_destroy(surface->wl_shm_pool);
	munmap(surface->shm_pool_data, surface->shm_pool_size);
	surface->shm_pool_data = NULL;
	close(surface->shm_pool_fd);
	wl_buffer_destroy(surface->buffers[0]);
	wl_buffer_destroy(surface->buffers[1]);
}

void surface_draw(
		struct surface *surface,
		struct color *color,
		struct image *texture)
{
	surface->index = !surface->index;
	int offset = surface->height * surface->stride * surface->index;
	uint32_t *pixels = (uint32_t *)&surface->shm_pool_data[offset];
	memcpy(pixels, texture->buffer, surface->height * surface->stride);

	wl_surface_attach(surface->wl_surface, surface->buffers[surface->index], 0, 0);
	wl_surface_damage_buffer(surface->wl_surface, 0, 0, INT32_MAX, INT32_MAX);
	wl_surface_commit(surface->wl_surface);
}