From a95b2d6d41fb9cf0687f25cae57868eda9b7b04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 13 Nov 2012 19:10:21 +0100 Subject: [PATCH] compositor: Add a renderer function to read out pixels --- src/compositor.h | 4 +++ src/gles2-renderer.c | 63 +++++++++++++++++++++++++++++++++++++------- src/noop-renderer.c | 10 +++++++ 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/compositor.h b/src/compositor.h index e4ba19cd..e2dbd0d3 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -276,6 +276,10 @@ struct weston_plane { }; struct weston_renderer { + int (*read_pixels)(struct weston_output *output, + pixman_format_code_t format, void *pixels, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height); void (*repaint_output)(struct weston_output *output, pixman_region32_t *output_damage); void (*flush_damage)(struct weston_surface *surface); diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c index 818a1a32..27c23ebc 100644 --- a/src/gles2-renderer.c +++ b/src/gles2-renderer.c @@ -608,6 +608,29 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region, ec->vtxcnt.size = 0; } +static int +use_output(struct weston_output *output) +{ + static int errored; + struct gles2_output_state *go = get_output_state(output); + struct gles2_renderer *gr = get_renderer(output->compositor); + EGLBoolean ret; + + ret = eglMakeCurrent(gr->egl_display, go->egl_surface, + go->egl_surface, gr->egl_context); + + if (ret == EGL_FALSE) { + if (errored) + return -1; + errored = 1; + weston_log("Failed to make EGL context current.\n"); + print_egl_error_state(); + return -1; + } + + return 0; +} + static void weston_compositor_use_shader(struct weston_compositor *compositor, struct weston_shader *shader) @@ -863,16 +886,8 @@ gles2_renderer_repaint_output(struct weston_output *output, glViewport(0, 0, width, height); - ret = eglMakeCurrent(gr->egl_display, go->egl_surface, - go->egl_surface, gr->egl_context); - if (ret == EGL_FALSE) { - if (errored) - return; - errored = 1; - weston_log("Failed to make EGL context current.\n"); - print_egl_error_state(); + if (use_output(output) < 0) return; - } /* if debugging, redraw everything outside the damage to clean up * debug lines from the previous draw on this buffer: @@ -914,6 +929,35 @@ gles2_renderer_repaint_output(struct weston_output *output, } +static int +gles2_renderer_read_pixels(struct weston_output *output, + pixman_format_code_t format, void *pixels, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height) +{ + GLenum gl_format; + + switch (format) { + case PIXMAN_a8r8g8b8: + gl_format = GL_BGRA_EXT; + break; + case PIXMAN_a8b8g8r8: + gl_format = GL_RGBA; + break; + default: + return -1; + } + + if (use_output(output) < 0) + return -1; + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(x, y, width, height, gl_format, + GL_UNSIGNED_BYTE, pixels); + + return 0; +} + static void gles2_renderer_flush_damage(struct weston_surface *surface) { @@ -1552,6 +1596,7 @@ gles2_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display if (gr == NULL) return -1; + gr->base.read_pixels = gles2_renderer_read_pixels; gr->base.repaint_output = gles2_renderer_repaint_output; gr->base.flush_damage = gles2_renderer_flush_damage; gr->base.attach = gles2_renderer_attach; diff --git a/src/noop-renderer.c b/src/noop-renderer.c index 116fc004..76f1e8fd 100644 --- a/src/noop-renderer.c +++ b/src/noop-renderer.c @@ -26,6 +26,15 @@ #include "compositor.h" +static int +noop_renderer_read_pixels(struct weston_output *output, + pixman_format_code_t format, void *pixels, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height) +{ + return 0; +} + static void noop_renderer_repaint_output(struct weston_output *output, pixman_region32_t *output_damage) @@ -64,6 +73,7 @@ noop_renderer_init(struct weston_compositor *ec) if (renderer == NULL) return -1; + renderer->read_pixels = noop_renderer_read_pixels; renderer->repaint_output = noop_renderer_repaint_output; renderer->flush_damage = noop_renderer_flush_damage; renderer->attach = noop_renderer_attach;