[PATCH weston] Add calls to wl_shm_buffer_begin/end_access
Kristian Høgsberg
hoegsberg at gmail.com
Tue Nov 12 15:54:38 PST 2013
On Tue, Oct 01, 2013 at 12:52:28AM +0100, Neil Roberts wrote:
> This wraps all accesses to an SHM buffer between wl_shm_buffer_begin
> and end so that wayland-shm can install a handler for SIGBUS and catch
> attempts to pass the compositor a buffer that is too small.
>
> Note, this patch doesn't do anything to fix the pixman renderer.
This looks good. As for the pixman renderer it should be a matter of
just wrapping the calls to pixman_image_composite32() in
pixman_renderer_read_pixels() and around the last if/else in
draw_view() where we end up calling repaint_region() in either branch.
Kristian
> ---
> src/compositor-drm.c | 3 +++
> src/gl-renderer.c | 6 ++++++
> src/pixman-renderer.c | 2 ++
> src/rpi-renderer.c | 4 ++++
> src/screenshooter.c | 4 ++++
> 5 files changed, 19 insertions(+)
>
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index 2770c85..180c3ee 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -964,9 +964,12 @@ drm_output_set_cursor(struct drm_output *output)
> memset(buf, 0, sizeof buf);
> stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer);
> s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer);
> +
> + wl_shm_buffer_begin_access(es->buffer_ref.buffer->shm_buffer);
> for (i = 0; i < es->geometry.height; i++)
> memcpy(buf + i * 64, s + i * stride,
> es->geometry.width * 4);
> + wl_shm_buffer_end_access(es->buffer_ref.buffer->shm_buffer);
>
> if (gbm_bo_write(bo, buf, sizeof buf) < 0)
> weston_log("failed update cursor: %m\n");
> diff --git a/src/gl-renderer.c b/src/gl-renderer.c
> index ae69f22..90e8148 100644
> --- a/src/gl-renderer.c
> +++ b/src/gl-renderer.c
> @@ -875,10 +875,12 @@ gl_renderer_flush_damage(struct weston_surface *surface)
> glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
>
> if (!gr->has_unpack_subimage) {
> + wl_shm_buffer_begin_access(buffer->shm_buffer);
> glTexImage2D(GL_TEXTURE_2D, 0, format,
> gs->pitch, buffer->height, 0,
> format, pixel_type,
> wl_shm_buffer_get_data(buffer->shm_buffer));
> + wl_shm_buffer_end_access(buffer->shm_buffer);
>
> goto done;
> }
> @@ -890,13 +892,16 @@ gl_renderer_flush_damage(struct weston_surface *surface)
> if (gs->needs_full_upload) {
> glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0);
> glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0);
> + wl_shm_buffer_begin_access(buffer->shm_buffer);
> glTexSubImage2D(GL_TEXTURE_2D, 0,
> 0, 0, gs->pitch, buffer->height,
> format, pixel_type, data);
> + wl_shm_buffer_end_access(buffer->shm_buffer);
> goto done;
> }
>
> rectangles = pixman_region32_rectangles(&gs->texture_damage, &n);
> + wl_shm_buffer_begin_access(buffer->shm_buffer);
> for (i = 0; i < n; i++) {
> pixman_box32_t r;
>
> @@ -908,6 +913,7 @@ gl_renderer_flush_damage(struct weston_surface *surface)
> r.x2 - r.x1, r.y2 - r.y1,
> format, pixel_type, data);
> }
> + wl_shm_buffer_end_access(buffer->shm_buffer);
> #endif
>
> done:
> diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
> index 987c539..80d41a8 100644
> --- a/src/pixman-renderer.c
> +++ b/src/pixman-renderer.c
> @@ -574,6 +574,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
> buffer->width = wl_shm_buffer_get_width(shm_buffer);
> buffer->height = wl_shm_buffer_get_height(shm_buffer);
>
> + /* XXX what about wl_shm_buffer_begin_access? */
> +
> ps->image = pixman_image_create_bits(pixman_format,
> buffer->width, buffer->height,
> wl_shm_buffer_get_data(shm_buffer),
> diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c
> index 3ba5fc4..a964899 100644
> --- a/src/rpi-renderer.c
> +++ b/src/rpi-renderer.c
> @@ -277,6 +277,8 @@ rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer,
> pixman_region32_intersect(&write_region,
> &write_region, region);
>
> + wl_shm_buffer_begin_access(buffer->shm_buffer);
> +
> #ifdef HAVE_RESOURCE_WRITE_DATA_RECT
> /* XXX: Can this do a format conversion, so that scanout does not have to? */
> r = pixman_region32_rectangles(&write_region, &n);
> @@ -311,6 +313,8 @@ rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer,
> width, r->y2 - r->y1, 0, r->y1, ret);
> #endif
>
> + wl_shm_buffer_end_access(buffer->shm_buffer);
> +
> pixman_region32_fini(&write_region);
>
> return ret ? -1 : 0;
> diff --git a/src/screenshooter.c b/src/screenshooter.c
> index 645114d..0c657bc 100644
> --- a/src/screenshooter.c
> +++ b/src/screenshooter.c
> @@ -144,6 +144,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
> d = wl_shm_buffer_get_data(l->buffer->shm_buffer);
> s = pixels + stride * (l->buffer->height - 1);
>
> + wl_shm_buffer_begin_access(l->buffer->shm_buffer);
> +
> switch (compositor->read_format) {
> case PIXMAN_a8r8g8b8:
> case PIXMAN_x8r8g8b8:
> @@ -163,6 +165,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
> break;
> }
>
> + wl_shm_buffer_end_access(l->buffer->shm_buffer);
> +
> screenshooter_send_done(l->resource);
> free(pixels);
> free(l);
> --
> 1.8.3.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list