Add calls to wl_shm_buffer_begin/end_access

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.
dev
Neil Roberts 12 years ago committed by Kristian Høgsberg
parent f707e8145b
commit e505171a32
  1. 11
      src/compositor-drm.c
  2. 6
      src/gl-renderer.c
  3. 6
      src/pixman-renderer.c
  4. 4
      src/rpi-renderer.c
  5. 4
      src/screenshooter.c

@ -974,6 +974,7 @@ static void
drm_output_set_cursor(struct drm_output *output) drm_output_set_cursor(struct drm_output *output)
{ {
struct weston_view *ev = output->cursor_view; struct weston_view *ev = output->cursor_view;
struct weston_buffer *buffer;
struct drm_compositor *c = struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor; (struct drm_compositor *) output->base.compositor;
EGLint handle, stride; EGLint handle, stride;
@ -988,18 +989,22 @@ drm_output_set_cursor(struct drm_output *output)
return; return;
} }
if (ev->surface->buffer_ref.buffer && buffer = ev->surface->buffer_ref.buffer;
if (buffer &&
pixman_region32_not_empty(&output->cursor_plane.damage)) { pixman_region32_not_empty(&output->cursor_plane.damage)) {
pixman_region32_fini(&output->cursor_plane.damage); pixman_region32_fini(&output->cursor_plane.damage);
pixman_region32_init(&output->cursor_plane.damage); pixman_region32_init(&output->cursor_plane.damage);
output->current_cursor ^= 1; output->current_cursor ^= 1;
bo = output->cursor_bo[output->current_cursor]; bo = output->cursor_bo[output->current_cursor];
memset(buf, 0, sizeof buf); memset(buf, 0, sizeof buf);
stride = wl_shm_buffer_get_stride(ev->surface->buffer_ref.buffer->shm_buffer); stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
s = wl_shm_buffer_get_data(ev->surface->buffer_ref.buffer->shm_buffer); s = wl_shm_buffer_get_data(buffer->shm_buffer);
wl_shm_buffer_begin_access(buffer->shm_buffer);
for (i = 0; i < ev->geometry.height; i++) for (i = 0; i < ev->geometry.height; i++)
memcpy(buf + i * 64, s + i * stride, memcpy(buf + i * 64, s + i * stride,
ev->geometry.width * 4); ev->geometry.width * 4);
wl_shm_buffer_end_access(buffer->shm_buffer);
if (gbm_bo_write(bo, buf, sizeof buf) < 0) if (gbm_bo_write(bo, buf, sizeof buf) < 0)
weston_log("failed update cursor: %m\n"); weston_log("failed update cursor: %m\n");

@ -899,10 +899,12 @@ gl_renderer_flush_damage(struct weston_surface *surface)
glBindTexture(GL_TEXTURE_2D, gs->textures[0]); glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
if (!gr->has_unpack_subimage) { if (!gr->has_unpack_subimage) {
wl_shm_buffer_begin_access(buffer->shm_buffer);
glTexImage2D(GL_TEXTURE_2D, 0, format, glTexImage2D(GL_TEXTURE_2D, 0, format,
gs->pitch, buffer->height, 0, gs->pitch, buffer->height, 0,
format, pixel_type, format, pixel_type,
wl_shm_buffer_get_data(buffer->shm_buffer)); wl_shm_buffer_get_data(buffer->shm_buffer));
wl_shm_buffer_end_access(buffer->shm_buffer);
goto done; goto done;
} }
@ -914,13 +916,16 @@ gl_renderer_flush_damage(struct weston_surface *surface)
if (gs->needs_full_upload) { if (gs->needs_full_upload) {
glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0);
wl_shm_buffer_begin_access(buffer->shm_buffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, gs->pitch, buffer->height, 0, 0, gs->pitch, buffer->height,
format, pixel_type, data); format, pixel_type, data);
wl_shm_buffer_end_access(buffer->shm_buffer);
goto done; goto done;
} }
rectangles = pixman_region32_rectangles(&gs->texture_damage, &n); rectangles = pixman_region32_rectangles(&gs->texture_damage, &n);
wl_shm_buffer_begin_access(buffer->shm_buffer);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
pixman_box32_t r; pixman_box32_t r;
@ -932,6 +937,7 @@ gl_renderer_flush_damage(struct weston_surface *surface)
r.x2 - r.x1, r.y2 - r.y1, r.x2 - r.x1, r.y2 - r.y1,
format, pixel_type, data); format, pixel_type, data);
} }
wl_shm_buffer_end_access(buffer->shm_buffer);
#endif #endif
done: done:

@ -305,6 +305,9 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
else else
pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0); pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0);
if (ps->buffer_ref.buffer)
wl_shm_buffer_begin_access(ps->buffer_ref.buffer->shm_buffer);
pixman_image_composite32(pixman_op, pixman_image_composite32(pixman_op,
ps->image, /* src */ ps->image, /* src */
NULL /* mask */, NULL /* mask */,
@ -315,6 +318,9 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
pixman_image_get_width (po->shadow_image), /* width */ pixman_image_get_width (po->shadow_image), /* width */
pixman_image_get_height (po->shadow_image) /* height */); pixman_image_get_height (po->shadow_image) /* height */);
if (ps->buffer_ref.buffer)
wl_shm_buffer_end_access(ps->buffer_ref.buffer->shm_buffer);
if (pr->repaint_debug) if (pr->repaint_debug)
pixman_image_composite32(PIXMAN_OP_OVER, pixman_image_composite32(PIXMAN_OP_OVER,
pr->debug_color, /* src */ pr->debug_color, /* src */

@ -342,6 +342,8 @@ rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer,
pixman_region32_intersect(&write_region, pixman_region32_intersect(&write_region,
&write_region, region); &write_region, region);
wl_shm_buffer_begin_access(buffer->shm_buffer);
#ifdef HAVE_RESOURCE_WRITE_DATA_RECT #ifdef HAVE_RESOURCE_WRITE_DATA_RECT
/* XXX: Can this do a format conversion, so that scanout does not have to? */ /* XXX: Can this do a format conversion, so that scanout does not have to? */
r = pixman_region32_rectangles(&write_region, &n); r = pixman_region32_rectangles(&write_region, &n);
@ -376,6 +378,8 @@ rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer,
width, r->y2 - r->y1, 0, r->y1, ret); width, r->y2 - r->y1, 0, r->y1, ret);
#endif #endif
wl_shm_buffer_end_access(buffer->shm_buffer);
pixman_region32_fini(&write_region); pixman_region32_fini(&write_region);
return ret ? -1 : 0; return ret ? -1 : 0;

@ -144,6 +144,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
d = wl_shm_buffer_get_data(l->buffer->shm_buffer); d = wl_shm_buffer_get_data(l->buffer->shm_buffer);
s = pixels + stride * (l->buffer->height - 1); s = pixels + stride * (l->buffer->height - 1);
wl_shm_buffer_begin_access(l->buffer->shm_buffer);
switch (compositor->read_format) { switch (compositor->read_format) {
case PIXMAN_a8r8g8b8: case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8: case PIXMAN_x8r8g8b8:
@ -163,6 +165,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
break; break;
} }
wl_shm_buffer_end_access(l->buffer->shm_buffer);
screenshooter_send_done(l->resource); screenshooter_send_done(l->resource);
free(pixels); free(pixels);
free(l); free(l);

Loading…
Cancel
Save