On Thu,  6 Mar 2014 18:51:15 +0900
Nobuhiko Tanibata <[email protected]> wrote:

> From: Kristian Høgsberg <[email protected]>
> 
> ---
>  src/compositor.h  |  3 +++
>  src/gl-renderer.c | 54
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files
> changed, 57 insertions(+)
> 
> diff --git a/src/compositor.h b/src/compositor.h
> index 22a485f..ace75da 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -540,6 +540,9 @@ struct weston_renderer {
>                              pixman_format_code_t format, void
> *pixels, uint32_t x, uint32_t y,
>                              uint32_t width, uint32_t height);
> +     int (*read_surface_pixels)(struct weston_surface *es,
> +                                pixman_format_code_t format, void
> *pixels,
> +                                int x, int y, int width, int
> height); void (*repaint_output)(struct weston_output *output,
>                              pixman_region32_t *output_damage);
>       void (*flush_damage)(struct weston_surface *surface);
> diff --git a/src/gl-renderer.c b/src/gl-renderer.c
> index 0e5afbe..dca2e05 100644
> --- a/src/gl-renderer.c
> +++ b/src/gl-renderer.c
> @@ -106,6 +106,8 @@ struct gl_renderer {
>       EGLContext egl_context;
>       EGLConfig egl_config;
>  
> +     GLuint fbo;
> +
>       struct wl_array vertices;
>       struct wl_array vtxcnt;
>  
> @@ -585,6 +587,54 @@ out:
>       pixman_region32_fini(&repaint);
>  }
>  
> +static int
> +gl_renderer_read_surface_pixels(struct weston_surface *es,
> +                             pixman_format_code_t format, void
> *pixels,
> +                             int x, int y, int width, int height)
> +{
> +     struct weston_buffer *buffer = es->buffer_ref.buffer;
> +     struct weston_compositor *ec = es->compositor;
> +     struct gl_renderer *gr = get_renderer(ec);
> +     struct gl_surface_state *gs = get_surface_state(es);
> +     GLenum gl_format;
> +     int size;
> +     struct wl_shm_buffer *shm_buffer = NULL;
> +
> +     switch (format) {
> +     case PIXMAN_a8r8g8b8:
> +             gl_format = GL_BGRA_EXT;
> +             break;
> +     case PIXMAN_a8b8g8r8:
> +             gl_format = GL_RGBA;
> +             break;
> +     default:
> +             return -1;
> +     }
> +
> +        if (buffer) {
> +             shm_buffer = wl_shm_buffer_get(buffer->resource);
> +     }
> +     if (shm_buffer) {
> +             size = buffer->width * 4 * buffer->height;
> +             memcpy(pixels, wl_shm_buffer_get_data(shm_buffer),
> size);

This branch completely ignores format, x, y, width, and height function
parameters, most likely corrupting random memory. This also assumes 4
bytes per pixel in the shm_buffer, which may not be true.


Thanks,
pq

> +     } else {
> +             if (gr->fbo == 0)
> +                     glGenFramebuffers(1, &gr->fbo);
> +             glBindFramebuffer(GL_FRAMEBUFFER, gr->fbo);
> +             glFramebufferTexture2D(GL_FRAMEBUFFER,
> +                                    GL_COLOR_ATTACHMENT0,
> +                                    GL_TEXTURE_2D,
> +                                    gs->textures[0], 0);
> +
> +             glReadPixels(x, y, width, height,
> +                          gl_format, GL_UNSIGNED_BYTE, pixels);
> +
> +             glBindFramebuffer(GL_FRAMEBUFFER, 0);
> +     }
> +
> +     return 0;
> +}
> +
>  static void
>  repaint_views(struct weston_output *output, pixman_region32_t
> *damage) {
> @@ -1602,6 +1652,9 @@ gl_renderer_destroy(struct weston_compositor
> *ec) 
>       wl_signal_emit(&gr->destroy_signal, gr);
>  
> +     if (gr->fbo)
> +             glDeleteFramebuffers(1, &gr->fbo);
> +
>       if (gr->has_bind_display)
>               gr->unbind_display(gr->egl_display, ec->wl_display);
>  
> @@ -1699,6 +1752,7 @@ gl_renderer_create(struct weston_compositor
> *ec, EGLNativeDisplayType display, return -1;
>  
>       gr->base.read_pixels = gl_renderer_read_pixels;
> +     gr->base.read_surface_pixels =
> gl_renderer_read_surface_pixels; gr->base.repaint_output =
> gl_renderer_repaint_output; gr->base.flush_damage =
> gl_renderer_flush_damage; gr->base.attach = gl_renderer_attach;

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

Reply via email to