diff options
author | Ilia Bozhinov <ammen99@gmail.com> | 2018-11-23 21:20:57 +0100 |
---|---|---|
committer | Ilia Bozhinov <ammen99@gmail.com> | 2018-11-24 10:54:25 +0100 |
commit | fb5691b6cc42cab42d0f15e8fbb25b2e1ff4ad0d (patch) | |
tree | ef46e76a5fa07a924ba51d1f71383d9ddec7330c | |
parent | c70b8f64b7f1ea0a603517c7e6852ef3743a483a (diff) |
output: add wlr_output_preferred_read_format()
The read format is dependent on the output, so we first need to make it
current. This fixes a race condition in wlr-screencopy-v1 where a dmabuf
client would cause EGL_NO_SURFACE to be bound at the time when
screencopy needs to query for the preferred format, causing GL errors.
-rw-r--r-- | include/wlr/render/wlr_renderer.h | 5 | ||||
-rw-r--r-- | include/wlr/types/wlr_output.h | 6 | ||||
-rw-r--r-- | render/wlr_renderer.c | 9 | ||||
-rw-r--r-- | types/wlr_output.c | 15 | ||||
-rw-r--r-- | types/wlr_screencopy_v1.c | 2 |
5 files changed, 22 insertions, 15 deletions
diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h index 02b4a11e..9c031b7f 100644 --- a/include/wlr/render/wlr_renderer.h +++ b/include/wlr/render/wlr_renderer.h @@ -97,11 +97,6 @@ int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *renderer, int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format, uint64_t **modifiers); /** - * Get the preferred format for reading pixels. - */ -bool wlr_renderer_preferred_read_format(struct wlr_renderer *renderer, - enum wl_shm_format *fmt); -/** * Reads out of pixels of the currently bound surface into data. `stride` is in * bytes. * diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 557a3895..6d38152a 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -193,6 +193,12 @@ void wlr_output_effective_resolution(struct wlr_output *output, */ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age); /** + * Get the preferred format for reading pixels. + * This function might change the current rendering context. + */ +bool wlr_output_preferred_read_format(struct wlr_output *output, + enum wl_shm_format *fmt); +/** * Swaps the output buffers. If the time of the frame isn't known, set `when` to * NULL. If the compositor doesn't support damage tracking, set `damage` to * NULL. diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index ca1a337d..58731d7f 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -139,15 +139,6 @@ int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *r, int format, return r->impl->get_dmabuf_modifiers(r, format, modifiers); } -bool wlr_renderer_preferred_read_format(struct wlr_renderer *r, - enum wl_shm_format *fmt) { - if (!r->impl->preferred_read_format || !r->impl->read_pixels) { - return false; - } - *fmt = r->impl->preferred_read_format(r); - return true; -} - bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt, uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, diff --git a/types/wlr_output.c b/types/wlr_output.c index 71cb3eba..dc8e34b8 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -6,6 +6,7 @@ #include <time.h> #include <wayland-server.h> #include <wlr/interfaces/wlr_output.h> +#include <wlr/render/interface.h> #include <wlr/render/wlr_renderer.h> #include <wlr/types/wlr_box.h> #include <wlr/types/wlr_matrix.h> @@ -339,6 +340,20 @@ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age) { return output->impl->make_current(output, buffer_age); } +bool wlr_output_preferred_read_format(struct wlr_output *output, + enum wl_shm_format *fmt) { + if (!wlr_output_make_current(output, NULL)) { + return false; + } + + struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + if (!renderer->impl->preferred_read_format || !renderer->impl->read_pixels) { + return false; + } + *fmt = renderer->impl->preferred_read_format(renderer); + return true; +} + bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when, pixman_region32_t *damage) { if (output->frame_pending) { diff --git a/types/wlr_screencopy_v1.c b/types/wlr_screencopy_v1.c index b186b89b..1d8550fe 100644 --- a/types/wlr_screencopy_v1.c +++ b/types/wlr_screencopy_v1.c @@ -219,7 +219,7 @@ static void capture_output(struct wl_client *client, struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); assert(renderer); - if (!wlr_renderer_preferred_read_format(renderer, &frame->format)) { + if (!wlr_output_preferred_read_format(frame->output, &frame->format)) { wlr_log(WLR_ERROR, "Failed to capture output: no read format supported by renderer"); goto error; |