diff options
| author | Drew DeVault <sir@cmpwn.com> | 2017-06-22 16:32:47 -0400 | 
|---|---|---|
| committer | Drew DeVault <sir@cmpwn.com> | 2017-06-23 13:41:07 -0400 | 
| commit | 2aafb5dd19f8a3e3436f8843071fa2076a6d2716 (patch) | |
| tree | 6fe60ddeb499ebad270fae0c929ef4c79188e969 | |
| parent | f252c5a79214a3d3cd7ab3f239050b234e4ae9e2 (diff) | |
| download | wlroots-2aafb5dd19f8a3e3436f8843071fa2076a6d2716.tar.xz | |
Add wlcore/wl_shm (WIP)
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | example/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | example/compositor.c | 43 | ||||
| -rw-r--r-- | example/shared.h | 1 | ||||
| -rw-r--r-- | include/endian.h | 8 | ||||
| -rw-r--r-- | include/wlr/render.h | 5 | ||||
| -rw-r--r-- | include/wlr/render/interface.h | 8 | ||||
| -rw-r--r-- | include/wlr/wlcore/wl_shm.h | 13 | ||||
| -rw-r--r-- | render/gles2/renderer.c | 12 | ||||
| -rw-r--r-- | render/wlr_renderer.c | 5 | ||||
| -rw-r--r-- | wlcore/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | wlcore/wl_shm.c | 78 | 
12 files changed, 186 insertions, 4 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2397b2..571b7b61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ add_subdirectory(backend)  add_subdirectory(types)  add_subdirectory(session)  add_subdirectory(render) +add_subdirectory(wlcore)  add_subdirectory(util)  add_subdirectory(example) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index fff2e49b..6c53e923 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -65,3 +65,16 @@ target_link_libraries(tablet      wlr-render      ${XKBCOMMON_LIBRARIES}  ) + +add_executable(compositor +    compositor +    shared.c +) + +target_link_libraries(compositor +    wlr-backend +    wlr-session +    wlr-render +    wlr-wlcore +    ${XKBCOMMON_LIBRARIES} +) diff --git a/example/compositor.c b/example/compositor.c new file mode 100644 index 00000000..5106ec96 --- /dev/null +++ b/example/compositor.c @@ -0,0 +1,43 @@ +#define _POSIX_C_SOURCE 199309L +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <inttypes.h> +#include <wayland-server.h> +#include <wlr/backend.h> +#include <wlr/session.h> +#include <wlr/render.h> +#include <wlr/render/gles2.h> +#include <wlr/types/wlr_output.h> +#include <wlr/wlcore/wl_shm.h> +#include <xkbcommon/xkbcommon.h> +#include "shared.h" + +struct sample_state { +	struct wlr_renderer *renderer; +}; + +void handle_output_frame(struct output_state *output, struct timespec *ts) { +	struct compositor_state *state = output->compositor; +	struct sample_state *sample = state->data; +	struct wlr_output *wlr_output = output->output; + +	wlr_renderer_begin(sample->renderer, wlr_output); +	// TODO: render surfaces +	wlr_renderer_end(sample->renderer); +} + +int main() { +	struct sample_state state = { 0 }; +	struct compositor_state compositor = { 0, +		.data = &state, +		.output_frame_cb = handle_output_frame, +	}; +	compositor_init(&compositor); + +	state.renderer = wlr_gles2_renderer_init(); +	wlr_wl_shm_init(compositor.display); + +	compositor_run(&compositor); +} diff --git a/example/shared.h b/example/shared.h index 37f52dcc..1633f2c8 100644 --- a/example/shared.h +++ b/example/shared.h @@ -126,7 +126,6 @@ struct compositor_state {  	struct wl_listener output_remove;  	struct wl_list outputs; -	bool exit;  	void *data;  }; diff --git a/include/endian.h b/include/endian.h new file mode 100644 index 00000000..0e9b6101 --- /dev/null +++ b/include/endian.h @@ -0,0 +1,8 @@ +#ifndef _WLR_ENDIAN_H +#define _WLR_ENDIAN_H + +// https://stackoverflow.com/a/4240257 + +#define little_endian() (((union { unsigned x; unsigned char c; }){1}).c) + +#endif diff --git a/include/wlr/render.h b/include/wlr/render.h index 90967dd9..496e3638 100644 --- a/include/wlr/render.h +++ b/include/wlr/render.h @@ -39,6 +39,11 @@ void wlr_render_colored_quad(struct wlr_renderer *r,  void wlr_render_colored_ellipse(struct wlr_renderer *r,  		const float (*color)[4], const float (*matrix)[16]);  /** + * Returns a list of pixel formats supported by this renderer. + */ +const enum wl_shm_format *wlr_renderer_get_formats( +		struct wlr_renderer *r, size_t *len); +/**   * Destroys this wlr_renderer. Surfaces must be destroyed separately.   */  void wlr_renderer_destroy(struct wlr_renderer *renderer); diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index 222b0c4d..c7fa54d6 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -20,9 +20,11 @@ struct wlr_renderer_impl {  	bool (*render_with_matrix)(struct wlr_renderer_state *state,  		struct wlr_surface *surface, const float (*matrix)[16]);  	void (*render_quad)(struct wlr_renderer_state *state, -			const float (*color)[4], const float (*matrix)[16]); +		const float (*color)[4], const float (*matrix)[16]);  	void (*render_ellipse)(struct wlr_renderer_state *state, -			const float (*color)[4], const float (*matrix)[16]); +		const float (*color)[4], const float (*matrix)[16]); +	const enum wl_shm_format *(*formats)( +		struct wlr_renderer_state *state, size_t *len);  	void (*destroy)(struct wlr_renderer_state *state);  }; @@ -36,7 +38,7 @@ struct wlr_surface_impl {  		struct wl_shm_buffer *shm);  	// TODO: egl  	void (*get_matrix)(struct wlr_surface_state *state, -			float (*matrix)[16], const float (*projection)[16], int x, int y); +		float (*matrix)[16], const float (*projection)[16], int x, int y);  	void (*bind)(struct wlr_surface_state *state);  	void (*destroy)(struct wlr_surface_state *state);  }; diff --git a/include/wlr/wlcore/wl_shm.h b/include/wlr/wlcore/wl_shm.h new file mode 100644 index 00000000..12c2ef78 --- /dev/null +++ b/include/wlr/wlcore/wl_shm.h @@ -0,0 +1,13 @@ +#ifndef _WLR_WLCORE_WL_SHM_H +#define _WLR_WLCORE_WL_SHM_H +#include <wayland-server-core.h> +#include <wlr/render.h> + +struct wlr_wl_shm; + +struct wlr_wl_shm *wlr_wl_shm_init(struct wl_display *display); +void wlr_wl_shm_add_format(struct wlr_wl_shm *shm, enum wl_shm_format format); +void wlr_wl_shm_add_renderer_formats( +		struct wlr_wl_shm *shm, struct wlr_renderer *renderer); + +#endif diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 623f378e..f3906125 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -129,6 +129,7 @@ static void draw_quad() {  static bool wlr_gles2_render_surface(struct wlr_renderer_state *state,  		struct wlr_surface *surface, const float (*matrix)[16]) {  	assert(surface && surface->valid); +	// TODO: Convert GL formats to WL_SHM formats  	switch (surface->format) {  	case GL_RGB:  		GL_CALL(glUseProgram(shaders.rgb)); @@ -163,6 +164,16 @@ static void wlr_gles2_render_ellipse(struct wlr_renderer_state *state,  	draw_quad();  } +static const enum wl_shm_format *wlr_gles2_formats( +		struct wlr_renderer_state *state, size_t *len) { +	static enum wl_shm_format formats[] = { +		WL_SHM_FORMAT_ARGB8888, +		WL_SHM_FORMAT_XRGB8888, +	}; +	*len = sizeof(formats) / sizeof(formats[0]); +	return formats; +} +  static void wlr_gles2_destroy(struct wlr_renderer_state *state) {  	// no-op  } @@ -174,6 +185,7 @@ static struct wlr_renderer_impl wlr_renderer_impl = {  	.render_with_matrix = wlr_gles2_render_surface,  	.render_quad = wlr_gles2_render_quad,  	.render_ellipse = wlr_gles2_render_ellipse, +	.formats = wlr_gles2_formats,  	.destroy = wlr_gles2_destroy  }; diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index f48bb3eb..720c5254 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -41,3 +41,8 @@ void wlr_render_colored_ellipse(struct wlr_renderer *r,  		const float (*color)[4], const float (*matrix)[16]) {  	r->impl->render_ellipse(r->state, color, matrix);  } + +const enum wl_shm_format *wlr_renderer_get_formats( +		struct wlr_renderer *r, size_t *len) { +	return r->impl->formats(r->state, len); +} diff --git a/wlcore/CMakeLists.txt b/wlcore/CMakeLists.txt new file mode 100644 index 00000000..cf6233c1 --- /dev/null +++ b/wlcore/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(wlr-wlcore STATIC +	wl_shm.c +) diff --git a/wlcore/wl_shm.c b/wlcore/wl_shm.c new file mode 100644 index 00000000..824b3620 --- /dev/null +++ b/wlcore/wl_shm.c @@ -0,0 +1,78 @@ +#include <assert.h> +#include <stdlib.h> +#include <stdint.h> +#include <wayland-server.h> +#include <wlr/wlcore/wl_shm.h> +#include <wlr/util/list.h> +#include <wlr/util/log.h> +#include <wlr/render.h> + +struct wlr_wl_shm { +	struct wl_global *wl_global; +	struct wl_list resources; +	struct wl_list pools; +	list_t *formats; +}; + +static void wl_shm_destroy(struct wl_resource *resource) { +	struct wlr_wl_shm *shm = wl_resource_get_user_data(resource); +	struct wl_resource *_resource = NULL; +	wl_resource_for_each(_resource, &shm->resources) { +		if (_resource == resource) { +			struct wl_list *link = wl_resource_get_link(_resource); +			wl_list_remove(link); +			break; +		} +	} +} + +struct wl_shm_interface wl_shm_impl = { +	//.create_pool = wl_shm_create_pool +}; + +static void wl_shm_bind(struct wl_client *wl_client, void *_wlr_wl_shm, +		uint32_t version, uint32_t id) { +	struct wlr_wl_shm *wlr_shm = _wlr_wl_shm; +	assert(wl_client && wlr_shm); +	if (version > 1) { +		wlr_log(L_ERROR, "Client requested unsupported wl_shm version, disconnecting"); +		wl_client_destroy(wl_client); +		return; +	} +	struct wl_resource *wl_resource = wl_resource_create( +			wl_client, &wl_shm_interface, version, id); +	wl_resource_set_implementation(wl_resource, &wl_shm_impl, +			wlr_shm, wl_shm_destroy); +	wl_list_insert(&wlr_shm->resources, wl_resource_get_link(wl_resource)); +	for (size_t i = 0; i < wlr_shm->formats->length; ++i) { +		uint32_t *f = wlr_shm->formats->items[i]; +		wl_shm_send_format(wl_resource, *f); +	} +} + +struct wlr_wl_shm *wlr_wl_shm_init(struct wl_display *display) { +	struct wlr_wl_shm *shm = calloc(1, sizeof(struct wlr_wl_shm)); +	wl_list_init(&shm->resources); +	wl_list_init(&shm->pools); +	shm->formats = list_create(); +	shm->wl_global = wl_global_create(display, &wl_shm_interface, 1, +			shm, wl_shm_bind); +	return shm; +} + +void wlr_wl_shm_add_format(struct wlr_wl_shm *shm, enum wl_shm_format format) { +	assert(shm); +	uint32_t *f = calloc(1, sizeof(uint32_t)); +	*f = format; +	list_add(shm->formats, f); +} + +void wlr_wl_shm_add_renderer_formats(struct wlr_wl_shm *shm, +		struct wlr_renderer *renderer) { +	assert(shm && renderer); +	size_t len; +	const enum wl_shm_format *formats = wlr_renderer_get_formats(renderer, &len); +	for (size_t i = 0; i < len; ++i) { +		wlr_wl_shm_add_format(shm, formats[i]); +	} +} | 
