aboutsummaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/CMakeLists.txt1
-rw-r--r--render/gles2/pixel_format.c45
-rw-r--r--render/gles2/renderer.c38
-rw-r--r--render/gles2/shaders.c15
-rw-r--r--render/gles2/surface.c15
-rw-r--r--render/wlr_renderer.c5
6 files changed, 89 insertions, 30 deletions
diff --git a/render/CMakeLists.txt b/render/CMakeLists.txt
index 4058b50e..d412ddbc 100644
--- a/render/CMakeLists.txt
+++ b/render/CMakeLists.txt
@@ -5,5 +5,6 @@ add_library(wlr-render
gles2/shaders.c
gles2/renderer.c
gles2/surface.c
+ gles2/pixel_format.c
gles2/util.c
)
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) {
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);
+}