[PATCH weston-ivi-shell 01/15] This vfunc lets us read out a rectangle of pixels from the currently attached surface buffer.
Pekka Paalanen
ppaalanen at gmail.com
Mon Mar 10 01:10:22 PDT 2014
On Thu, 6 Mar 2014 18:51:15 +0900
Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp> wrote:
> From: Kristian Høgsberg <krh at bitplanet.net>
>
> ---
> 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;
More information about the wayland-devel
mailing list