libweston: Store shm buffer stride in weston_buffer
After c08a6ff8
moved attach to the render loop, we have a bad situation
when clients delete an attached shm buffer. We try to query the stride
at attach time, but the shm_buffer has been destroyed, and we crash.
Instead of carefully fixing that, I've instead stored the stride at
buffer creation time (as we already do with buffer width and height).
This lets attach succeed in the gl-renderer, keeping the old texture data
available for any upcoming rendering.
Fixes: #927
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Tested-by: Connor Abbott <cwabbott0@gmail.com>
This commit is contained in:
parent
0a483706d9
commit
376b3952a0
|
@ -1636,6 +1636,7 @@ struct weston_buffer {
|
|||
};
|
||||
|
||||
int32_t width, height;
|
||||
int32_t stride;
|
||||
uint32_t busy_count;
|
||||
uint32_t passive_count;
|
||||
enum {
|
||||
|
|
|
@ -649,7 +649,6 @@ cursor_bo_update(struct drm_output *output, struct weston_view *ev)
|
|||
struct gbm_bo *bo = output->gbm_cursor_fb[output->current_cursor]->bo;
|
||||
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
|
||||
uint32_t buf[device->cursor_width * device->cursor_height];
|
||||
int32_t stride;
|
||||
uint8_t *s;
|
||||
int i;
|
||||
|
||||
|
@ -659,13 +658,12 @@ cursor_bo_update(struct drm_output *output, struct weston_view *ev)
|
|||
|
||||
memset(buf, 0, sizeof buf);
|
||||
|
||||
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 < buffer->height; i++)
|
||||
memcpy(buf + i * device->cursor_width,
|
||||
s + i * stride,
|
||||
s + i * buffer->stride,
|
||||
buffer->width * 4);
|
||||
wl_shm_buffer_end_access(buffer->shm_buffer);
|
||||
|
||||
|
@ -2887,7 +2885,7 @@ drm_writeback_success_screenshot(struct drm_writeback_state *state)
|
|||
src_stride = state->fb->strides[0];
|
||||
|
||||
dst = wl_shm_buffer_get_data(buffer->shm_buffer);
|
||||
dst_stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
|
||||
dst_stride = buffer->stride;
|
||||
|
||||
width = state->fb->width;
|
||||
height = state->fb->height;
|
||||
|
|
|
@ -539,7 +539,6 @@ vnc_output_update_cursor(struct vnc_output *output)
|
|||
struct weston_buffer *buffer;
|
||||
struct weston_surface *cursor_surface;
|
||||
struct nvnc_fb *fb;
|
||||
int32_t stride;
|
||||
uint8_t *src, *dst;
|
||||
int i;
|
||||
|
||||
|
@ -556,8 +555,6 @@ vnc_output_update_cursor(struct vnc_output *output)
|
|||
cursor_surface = output->cursor_surface;
|
||||
buffer = cursor_surface->buffer_ref.buffer;
|
||||
|
||||
stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
|
||||
|
||||
fb = nvnc_fb_new(buffer->width, buffer->height, DRM_FORMAT_ARGB8888,
|
||||
buffer->width);
|
||||
assert(fb);
|
||||
|
@ -567,7 +564,7 @@ vnc_output_update_cursor(struct vnc_output *output)
|
|||
|
||||
wl_shm_buffer_begin_access(buffer->shm_buffer);
|
||||
for (i = 0; i < buffer->height; i++)
|
||||
memcpy(dst + i * 4 * buffer->width, src + i * stride,
|
||||
memcpy(dst + i * 4 * buffer->width, src + i * buffer->stride,
|
||||
4 * buffer->width);
|
||||
wl_shm_buffer_end_access(buffer->shm_buffer);
|
||||
|
||||
|
|
|
@ -2839,6 +2839,7 @@ weston_buffer_from_resource(struct weston_compositor *ec,
|
|||
buffer->shm_buffer = shm;
|
||||
buffer->width = wl_shm_buffer_get_width(shm);
|
||||
buffer->height = wl_shm_buffer_get_height(shm);
|
||||
buffer->stride = wl_shm_buffer_get_stride(shm);
|
||||
buffer->buffer_origin = ORIGIN_TOP_LEFT;
|
||||
/* wl_shm might create a buffer with an unknown format, so check
|
||||
* and reject */
|
||||
|
|
|
@ -95,7 +95,7 @@ noop_renderer_attach(struct weston_paint_node *pnode)
|
|||
|
||||
shm_buffer = buffer->shm_buffer;
|
||||
data = wl_shm_buffer_get_data(shm_buffer);
|
||||
stride = wl_shm_buffer_get_stride(shm_buffer);
|
||||
stride = buffer->stride;
|
||||
height = buffer->height;
|
||||
size = stride * height;
|
||||
|
||||
|
|
|
@ -594,7 +594,7 @@ pixman_renderer_do_capture(struct weston_buffer *into, pixman_image_t *from)
|
|||
dest = pixman_image_create_bits(into->pixel_format->pixman_format,
|
||||
into->width, into->height,
|
||||
wl_shm_buffer_get_data(shm),
|
||||
wl_shm_buffer_get_stride(shm));
|
||||
into->stride);
|
||||
abort_oom_if_null(dest);
|
||||
|
||||
pixman_image_composite32(PIXMAN_OP_SRC, from, NULL /* mask */, dest,
|
||||
|
@ -798,7 +798,7 @@ pixman_renderer_attach_internal(struct weston_surface *es,
|
|||
ps->image = pixman_image_create_bits(pixel_info->pixman_format,
|
||||
buffer->width, buffer->height,
|
||||
wl_shm_buffer_get_data(shm_buffer),
|
||||
wl_shm_buffer_get_stride(shm_buffer));
|
||||
buffer->stride);
|
||||
|
||||
ps->buffer_destroy_listener.notify =
|
||||
buffer_state_handle_buffer_destroy;
|
||||
|
|
|
@ -760,7 +760,7 @@ gl_renderer_do_capture(struct gl_renderer *gr, struct weston_buffer *into,
|
|||
wl_shm_buffer_begin_access(shm);
|
||||
|
||||
ret = gl_renderer_do_read_pixels(gr, fmt, wl_shm_buffer_get_data(shm),
|
||||
wl_shm_buffer_get_stride(shm), rect);
|
||||
into->stride, rect);
|
||||
|
||||
wl_shm_buffer_end_access(shm);
|
||||
|
||||
|
@ -980,7 +980,7 @@ gl_renderer_do_capture_tasks(struct gl_renderer *gr,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (wl_shm_buffer_get_stride(buffer->shm_buffer) % 4 != 0) {
|
||||
if (buffer->stride % 4 != 0) {
|
||||
weston_capture_task_retire_failed(ct, "GL: buffer stride not multiple of 4");
|
||||
continue;
|
||||
}
|
||||
|
@ -2576,7 +2576,6 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
struct gl_renderer *gr = get_renderer(ec);
|
||||
struct gl_surface_state *gs = get_surface_state(es);
|
||||
struct gl_buffer_state *gb;
|
||||
struct wl_shm_buffer *shm_buffer = buffer->shm_buffer;
|
||||
struct weston_buffer *old_buffer = gs->buffer_ref.buffer;
|
||||
GLenum gl_format[3] = {0, 0, 0};
|
||||
GLenum gl_pixel_type;
|
||||
|
@ -2614,7 +2613,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
*/
|
||||
if (!bpp)
|
||||
bpp = pixel_format_get_info(yuv->plane[0].format)->bpp;
|
||||
pitch = wl_shm_buffer_get_stride(shm_buffer) / (bpp / 8);
|
||||
pitch = buffer->stride / (bpp / 8);
|
||||
|
||||
/* well, they all are so far ... */
|
||||
gl_pixel_type = GL_UNSIGNED_BYTE;
|
||||
|
@ -2655,7 +2654,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
shader_variant = SHADER_VARIANT_RGBA;
|
||||
|
||||
assert(bpp > 0 && !(bpp & 7));
|
||||
pitch = wl_shm_buffer_get_stride(shm_buffer) / (bpp / 8);
|
||||
pitch = buffer->stride / (bpp / 8);
|
||||
|
||||
gl_format[0] = buffer->pixel_format->gl_format;
|
||||
gl_pixel_type = buffer->pixel_format->gl_type;
|
||||
|
|
|
@ -148,7 +148,7 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data)
|
|||
0, 0, output->current_mode->width,
|
||||
output->current_mode->height);
|
||||
|
||||
stride = wl_shm_buffer_get_stride(l->buffer->shm_buffer);
|
||||
stride = l->buffer->stride;
|
||||
|
||||
d = wl_shm_buffer_get_data(l->buffer->shm_buffer);
|
||||
s = pixels + stride * (l->buffer->height - 1);
|
||||
|
|
Loading…
Reference in New Issue