---
 src/compositor.h     |  6 ++++-
 src/gles2-renderer.c | 67 +++++++++++++++++++++++++++++++++++++++++++---------
 src/screenshooter.c  | 27 +++++++++++----------
 3 files changed, 76 insertions(+), 24 deletions(-)

diff --git a/src/compositor.h b/src/compositor.h
index 48bbbc6..dfad011 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -275,6 +275,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);
@@ -347,7 +351,7 @@ struct weston_compositor {
        PFNEGLDESTROYIMAGEKHRPROC destroy_image;
 
        int has_unpack_subimage;
-       GLenum read_format;
+       pixman_format_code_t read_format;
 
        PFNEGLBINDWAYLANDDISPLAYWL bind_display;
        PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display;
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index 0f943ff..5451e60 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -606,6 +606,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)
@@ -861,16 +884,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:
@@ -912,6 +927,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)
 {
@@ -1447,6 +1491,7 @@ gles2_renderer_init(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;
@@ -1548,9 +1593,9 @@ gles2_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
        }
 
        if (strstr(extensions, "GL_EXT_read_format_bgra"))
-               ec->read_format = GL_BGRA_EXT;
+               ec->read_format = PIXMAN_a8r8g8b8;
        else
-               ec->read_format = GL_RGBA;
+               ec->read_format = PIXMAN_a8b8g8r8;
 
        if (strstr(extensions, "GL_EXT_unpack_subimage"))
                ec->has_unpack_subimage = 1;
diff --git a/src/screenshooter.c b/src/screenshooter.c
index ffcc970..23181a2 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -112,10 +112,10 @@ screenshooter_frame_notify(struct wl_listener *listener, 
void *data)
                return;
        }
 
-       glPixelStorei(GL_PACK_ALIGNMENT, 1);
-       glReadPixels(0, 0, output->current->width, output->current->height,
-                    output->compositor->read_format,
-                    GL_UNSIGNED_BYTE, pixels);
+       output->compositor->renderer->read_pixels(output,
+                            output->compositor->read_format, pixels,
+                            0, 0, output->current->width,
+                            output->current->height);
 
        stride = wl_shm_buffer_get_stride(l->buffer);
 
@@ -123,10 +123,10 @@ screenshooter_frame_notify(struct wl_listener *listener, 
void *data)
        s = pixels + stride * (l->buffer->height - 1);
 
        switch (output->compositor->read_format) {
-       case GL_BGRA_EXT:
+       case PIXMAN_a8r8g8b8:
                copy_bgra_yflip(d, s, output->current->height, stride);
                break;
-       case GL_RGBA:
+       case PIXMAN_a8b8g8r8:
                copy_rgba_yflip(d, s, output->current->height, stride);
                break;
        default:
@@ -299,10 +299,10 @@ weston_recorder_frame_notify(struct wl_listener 
*listener, void *data)
        for (i = 0; i < n; i++) {
                width = r[i].x2 - r[i].x1;
                height = r[i].y2 - r[i].y1;
-               glReadPixels(r[i].x1, output->current->height - r[i].y2,
-                            width, height,
-                            output->compositor->read_format,
-                            GL_UNSIGNED_BYTE, recorder->rect);
+               output->compositor->renderer->read_pixels(output,
+                            output->compositor->read_format, recorder->rect,
+                            r[i].x1, output->current->height - r[i].y2,
+                            width, height);
 
                s = recorder->rect;
                p = recorder->rect;
@@ -367,12 +367,15 @@ weston_recorder_create(struct weston_output *output, 
const char *filename)
        header.magic = WCAP_HEADER_MAGIC;
 
        switch (output->compositor->read_format) {
-       case GL_BGRA_EXT:
+       case PIXMAN_a8r8g8b8:
                header.format = WCAP_FORMAT_XRGB8888;
                break;
-       case GL_RGBA:
+       case PIXMAN_a8b8g8r8:
                header.format = WCAP_FORMAT_XBGR8888;
                break;
+       default:
+               weston_log("unknown recorder format\n");
+               break;
        }
 
        header.width = output->current->width;
-- 
1.7.12.4

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to