mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-29 16:05:59 +01:00
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.
This commit is contained in:
parent
c70b8f64b7
commit
fb5691b6cc
5 changed files with 22 additions and 15 deletions
|
@ -96,11 +96,6 @@ int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *renderer,
|
||||||
*/
|
*/
|
||||||
int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format,
|
int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format,
|
||||||
uint64_t **modifiers);
|
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
|
* Reads out of pixels of the currently bound surface into data. `stride` is in
|
||||||
* bytes.
|
* bytes.
|
||||||
|
|
|
@ -192,6 +192,12 @@ void wlr_output_effective_resolution(struct wlr_output *output,
|
||||||
* unknown. This is useful for damage tracking.
|
* unknown. This is useful for damage tracking.
|
||||||
*/
|
*/
|
||||||
bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
|
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
|
* 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. If the compositor doesn't support damage tracking, set `damage` to
|
||||||
|
|
|
@ -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);
|
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,
|
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 *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,
|
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/interfaces/wlr_output.h>
|
#include <wlr/interfaces/wlr_output.h>
|
||||||
|
#include <wlr/render/interface.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_box.h>
|
#include <wlr/types/wlr_box.h>
|
||||||
#include <wlr/types/wlr_matrix.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);
|
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,
|
bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
||||||
pixman_region32_t *damage) {
|
pixman_region32_t *damage) {
|
||||||
if (output->frame_pending) {
|
if (output->frame_pending) {
|
||||||
|
|
|
@ -219,7 +219,7 @@ static void capture_output(struct wl_client *client,
|
||||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
|
||||||
assert(renderer);
|
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,
|
wlr_log(WLR_ERROR,
|
||||||
"Failed to capture output: no read format supported by renderer");
|
"Failed to capture output: no read format supported by renderer");
|
||||||
goto error;
|
goto error;
|
||||||
|
|
Loading…
Reference in a new issue