[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