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.
This commit is contained in:
committed by
Kristian Høgsberg
parent
f707e8145b
commit
e505171a32
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user