summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2012-11-13 19:10:21 +0100
committerKristian Høgsberg <krh@bitplanet.net>2012-11-13 17:00:06 -0500
commita95b2d6d41fb9cf0687f25cae57868eda9b7b04c (patch)
tree1a2226cb6d93833b9cc02f84cfaad6d675b2ba9e
parent4415450ef1439e3a8e76244eb5d95c5a260cc621 (diff)
compositor: Add a renderer function to read out pixels
-rw-r--r--src/compositor.h4
-rw-r--r--src/gles2-renderer.c63
-rw-r--r--src/noop-renderer.c10
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;