diff options
Diffstat (limited to 'render/gles2')
| -rw-r--r-- | render/gles2/pixel_format.c | 45 | ||||
| -rw-r--r-- | render/gles2/renderer.c | 38 | ||||
| -rw-r--r-- | render/gles2/shaders.c | 15 | ||||
| -rw-r--r-- | render/gles2/surface.c | 15 | 
4 files changed, 83 insertions, 30 deletions
| diff --git a/render/gles2/pixel_format.c b/render/gles2/pixel_format.c new file mode 100644 index 00000000..a0b9d09f --- /dev/null +++ b/render/gles2/pixel_format.c @@ -0,0 +1,45 @@ +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include "render/gles2.h" + +// Adapted from weston +struct pixel_format formats[] = { +	{ +		.wl_format = WL_SHM_FORMAT_ARGB8888, +		.depth = 32, +		.bpp = 32, +		.gl_format = GL_BGRA_EXT, +		.gl_type = GL_UNSIGNED_BYTE, +		.shader = &shaders.rgba +	}, +	{ +		.wl_format = WL_SHM_FORMAT_XRGB8888, +		.depth = 24, +		.bpp = 32, +		.gl_format = GL_BGRA_EXT, +		.gl_type = GL_UNSIGNED_BYTE, +		.shader = &shaders.rgbx +	}, +	{ +		.wl_format = WL_SHM_FORMAT_XBGR8888, +		.gl_format = GL_RGBA, +		.gl_type = GL_UNSIGNED_BYTE, +		.shader = &shaders.rgbx +	}, +	{ +		.wl_format = WL_SHM_FORMAT_ABGR8888, +		.gl_format = GL_RGBA, +		.gl_type = GL_UNSIGNED_BYTE, +		.shader = &shaders.rgba +	}, +}; +// TODO: more pixel formats + +const struct pixel_format *gl_format_for_wl_format(enum wl_shm_format fmt) { +	for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) { +		if (formats[i].wl_format == fmt) { +			return &formats[i]; +		} +	} +	return NULL; +} diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 623f378e..897dc3b8 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -10,12 +10,7 @@  #include <wlr/util/log.h>  #include "render/gles2.h" -static struct { -	bool initialized; -	GLuint rgb, rgba; -	GLuint quad; -	GLuint ellipse; -} shaders; +struct shaders shaders;  static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) {  	*shader = GL_CALL(glCreateShader(type)); @@ -58,10 +53,10 @@ static void init_default_shaders() {  	if (shaders.initialized) {  		return;  	} -	if (!compile_program(vertex_src, fragment_src_RGB, &shaders.rgb)) { +	if (!compile_program(vertex_src, fragment_src_rgba, &shaders.rgba)) {  		goto error;  	} -	if (!compile_program(vertex_src, fragment_src_RGBA, &shaders.rgba)) { +	if (!compile_program(vertex_src, fragment_src_rgbx, &shaders.rgbx)) {  		goto error;  	}  	if (!compile_program(quad_vertex_src, quad_fragment_src, &shaders.quad)) { @@ -129,20 +124,10 @@ 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); -	switch (surface->format) { -	case GL_RGB: -		GL_CALL(glUseProgram(shaders.rgb)); -		break; -	case GL_RGBA: -		GL_CALL(glUseProgram(shaders.rgba)); -		break; -	default: -		wlr_log(L_ERROR, "No shader for this surface format"); -		return false; -	} -	gles2_flush_errors();  	wlr_surface_bind(surface);  	GL_CALL(glUniformMatrix4fv(0, 1, GL_FALSE, *matrix)); +	// TODO: source alpha from somewhere else I guess +	GL_CALL(glUniform1f(2, 1.0f));  	draw_quad();  	return true;  } @@ -163,6 +148,18 @@ 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, +		WL_SHM_FORMAT_ABGR8888, +		WL_SHM_FORMAT_XBGR8888, +	}; +	*len = sizeof(formats) / sizeof(formats[0]); +	return formats; +} +  static void wlr_gles2_destroy(struct wlr_renderer_state *state) {  	// no-op  } @@ -174,6 +171,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/gles2/shaders.c b/render/gles2/shaders.c index 62712230..f5e61dd6 100644 --- a/render/gles2/shaders.c +++ b/render/gles2/shaders.c @@ -20,7 +20,6 @@ const GLchar quad_vertex_src[] =  "                 vec4(i0.z, i1.z, i2.z, i3.z),"  "                 vec4(i0.w, i1.w, i2.w, i3.w)"  "                 );" -""  "    return outMatrix;"  "}"  "void main() {" @@ -37,8 +36,7 @@ const GLchar quad_fragment_src[] =  "  gl_FragColor = v_color;"  "}"; -// Colored ellipses (TODO) - +// Colored ellipses  const GLchar ellipse_fragment_src[] =  "precision mediump float;"  "varying vec4 v_color;" @@ -74,18 +72,21 @@ const GLchar vertex_src[] =  "	v_texcoord = texcoord;"  "}"; -const GLchar fragment_src_RGB[] = +const GLchar fragment_src_rgba[] =  "precision mediump float;"  "varying vec2 v_texcoord;"  "uniform sampler2D tex;" +"uniform float alpha;"  "void main() {" -"	gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);" +"	gl_FragColor = alpha * texture2D(tex, v_texcoord);"  "}"; -const GLchar fragment_src_RGBA[] = +const GLchar fragment_src_rgbx[] =  "precision mediump float;"  "varying vec2 v_texcoord;"  "uniform sampler2D tex;" +"uniform float alpha;"  "void main() {" -"	gl_FragColor = texture2D(tex, v_texcoord);" +"   gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb;" +"   gl_FragColor.a = alpha;"  "}"; diff --git a/render/gles2/surface.c b/render/gles2/surface.c index c9be6ac2..f730a499 100644 --- a/render/gles2/surface.c +++ b/render/gles2/surface.c @@ -8,19 +8,27 @@  #include <wlr/render.h>  #include <wlr/render/interface.h>  #include <wlr/render/matrix.h> +#include <wlr/util/log.h>  #include "render/gles2.h"  static bool gles2_surface_attach_pixels(struct wlr_surface_state *surface, -		uint32_t format, int stride, int width, int height, const unsigned char *pixels) { +		enum wl_shm_format format, int stride, int width, int height, +		const unsigned char *pixels) {  	assert(surface); +	const struct pixel_format *fmt = gl_format_for_wl_format(format); +	if (!fmt || !fmt->gl_format) { +		wlr_log(L_ERROR, "No supported pixel format for this surface"); +		return false; +	}  	surface->wlr_surface->width = width;  	surface->wlr_surface->height = height;  	surface->wlr_surface->format = format; +	surface->pixel_format = fmt;  	GL_CALL(glGenTextures(1, &surface->tex_id));  	GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id));  	GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride)); -	GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, -			format, GL_UNSIGNED_BYTE, pixels)); +	GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, fmt->gl_format, width, height, 0, +			fmt->gl_format, fmt->gl_type, pixels));  	GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0));  	surface->wlr_surface->valid = true;  	return true; @@ -43,6 +51,7 @@ static void gles2_surface_bind(struct wlr_surface_state *surface) {  	GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id));  	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));  	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); +	GL_CALL(glUseProgram(*surface->pixel_format->shader));  }  static void gles2_surface_destroy(struct wlr_surface_state *surface) { | 
