aboutsummaryrefslogtreecommitdiff
path: root/render/gles2/surface.c
diff options
context:
space:
mode:
authorTony Crisci <tony@dubstepdish.com>2017-08-03 14:20:51 -0400
committerTony Crisci <tony@dubstepdish.com>2017-08-04 11:41:13 -0400
commit6610aa7ca7d170c43705c86db65f7a1f8fc8681a (patch)
tree468fb40d7833194f48e88cbcdc40afc24670faeb /render/gles2/surface.c
parent555914a13bec2d6f9ea5c48dc9a955bd397e4ea1 (diff)
Implement shm buffer surface attach interface
Implement surface_attach method. This is called when a client attaches an shm buffer with wl_surface_attach(). Implement the GLES2 interface for attaching shm buffers. This creates an opengl texture with the shm buffer contents for the surface. This commit also includes some working code to render the surfaces onto the screen for demonstration purposes.
Diffstat (limited to 'render/gles2/surface.c')
-rw-r--r--render/gles2/surface.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/render/gles2/surface.c b/render/gles2/surface.c
index f730a499..300e1e46 100644
--- a/render/gles2/surface.c
+++ b/render/gles2/surface.c
@@ -34,6 +34,35 @@ static bool gles2_surface_attach_pixels(struct wlr_surface_state *surface,
return true;
}
+static bool gles2_surface_attach_shm(struct wlr_surface_state *surface,
+ uint32_t format, struct wl_shm_buffer *buffer) {
+ 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;
+ }
+ wl_shm_buffer_begin_access(buffer);
+ uint8_t *pixels = wl_shm_buffer_get_data(buffer);
+ int width = wl_shm_buffer_get_width(buffer);
+ int height = wl_shm_buffer_get_height(buffer);
+ int pitch = wl_shm_buffer_get_stride(buffer) / (fmt->bpp / 8);
+ surface->wlr_surface->width = width;
+ surface->wlr_surface->height = height;
+ surface->wlr_surface->format = format;
+ surface->pixel_format = fmt;
+
+ GL_CALL(glActiveTexture(GL_TEXTURE0));
+ GL_CALL(glGenTextures(1, &surface->tex_id));
+ GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id));
+ GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, pitch));
+ GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, fmt->gl_format, width, height, 0,
+ fmt->gl_format, fmt->gl_type, pixels));
+
+ surface->wlr_surface->valid = true;
+ wl_shm_buffer_end_access(buffer);
+ return true;
+}
+
static void gles2_surface_get_matrix(struct wlr_surface_state *surface,
float (*matrix)[16], const float (*projection)[16], int x, int y) {
struct wlr_surface *_surface = surface->wlr_surface;
@@ -61,7 +90,7 @@ static void gles2_surface_destroy(struct wlr_surface_state *surface) {
static struct wlr_surface_impl wlr_surface_impl = {
.attach_pixels = gles2_surface_attach_pixels,
- // .attach_shm = TODO
+ .attach_shm = gles2_surface_attach_shm,
.get_matrix = gles2_surface_get_matrix,
.bind = gles2_surface_bind,
.destroy = gles2_surface_destroy,