Thanks for the feedback. Here is a version two of the patch which fixes some merge conflicts on master and adds support for the pixman renderer.
Kristian wrote: > 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. I think the pixman_renderer_read_pixels case doesn't need the wrapper functions because it is reading from the output's buffer into another malloc'd buffer. Both of those are allocated by the compositor and shouldn't cause any problems. I put the wrapper calls inside repaint_region in order to minimise the length of time that the wrapper is enabled. Regards, - Neil ------- >8 --------------- (use git am --scissors to automatically chop here) 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. --- src/compositor-drm.c | 11 ++++++++--- src/gl-renderer.c | 6 ++++++ src/pixman-renderer.c | 6 ++++++ src/rpi-renderer.c | 4 ++++ src/screenshooter.c | 4 ++++ 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index b929728..d4fc871 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -974,6 +974,7 @@ static void drm_output_set_cursor(struct drm_output *output) { struct weston_view *ev = output->cursor_view; + struct weston_buffer *buffer; struct drm_compositor *c = (struct drm_compositor *) output->base.compositor; EGLint handle, stride; @@ -988,18 +989,22 @@ drm_output_set_cursor(struct drm_output *output) 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_fini(&output->cursor_plane.damage); pixman_region32_init(&output->cursor_plane.damage); output->current_cursor ^= 1; bo = output->cursor_bo[output->current_cursor]; memset(buf, 0, sizeof buf); - stride = wl_shm_buffer_get_stride(ev->surface->buffer_ref.buffer->shm_buffer); - s = wl_shm_buffer_get_data(ev->surface->buffer_ref.buffer->shm_buffer); + stride = wl_shm_buffer_get_stride(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++) memcpy(buf + i * 64, s + i * stride, ev->geometry.width * 4); + wl_shm_buffer_end_access(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 68a071f..7a535c7 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -899,10 +899,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; } @@ -914,13 +916,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; @@ -932,6 +937,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 a80be5f..b719829 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -305,6 +305,9 @@ repaint_region(struct weston_view *ev, struct weston_output *output, else 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, ps->image, /* src */ 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_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) pixman_image_composite32(PIXMAN_OP_OVER, pr->debug_color, /* src */ diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c index 8fb562d..1940db7 100644 --- a/src/rpi-renderer.c +++ b/src/rpi-renderer.c @@ -342,6 +342,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); @@ -376,6 +378,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@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel