mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 12:55:58 +01:00
output: add wlr_output_schedule_frame
This commit is contained in:
parent
ece2c1e4e2
commit
8d58ed502b
9 changed files with 41 additions and 31 deletions
|
@ -881,7 +881,7 @@ static void page_flip_handler(int fd, unsigned seq,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drm->session->active) {
|
if (drm->session->active) {
|
||||||
wl_signal_emit(&conn->output.events.frame, &conn->output);
|
wlr_output_send_frame(&conn->output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ bool wlr_output_is_headless(struct wlr_output *wlr_output) {
|
||||||
|
|
||||||
static int signal_frame(void *data) {
|
static int signal_frame(void *data) {
|
||||||
struct wlr_headless_output *output = data;
|
struct wlr_headless_output *output = data;
|
||||||
wl_signal_emit(&output->wlr_output.events.frame, &output->wlr_output);
|
wlr_output_send_frame(&output->wlr_output);
|
||||||
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@ int os_create_anonymous_file(off_t size);
|
||||||
|
|
||||||
static struct wl_callback_listener frame_listener;
|
static struct wl_callback_listener frame_listener;
|
||||||
|
|
||||||
static void surface_frame_callback(void *data, struct wl_callback *cb, uint32_t time) {
|
static void surface_frame_callback(void *data, struct wl_callback *cb,
|
||||||
|
uint32_t time) {
|
||||||
struct wlr_wl_backend_output *output = data;
|
struct wlr_wl_backend_output *output = data;
|
||||||
struct wlr_output *wlr_output = (struct wlr_output *)output;
|
assert(output);
|
||||||
assert(wlr_output);
|
wlr_output_send_frame(&output->wlr_output);
|
||||||
wl_signal_emit(&wlr_output->events.frame, wlr_output);
|
|
||||||
wl_callback_destroy(cb);
|
wl_callback_destroy(cb);
|
||||||
output->frame_callback = NULL;
|
output->frame_callback = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e
|
||||||
|
|
||||||
switch (event->response_type) {
|
switch (event->response_type) {
|
||||||
case XCB_EXPOSE: {
|
case XCB_EXPOSE: {
|
||||||
wl_signal_emit(&output->wlr_output.events.frame, output);
|
wlr_output_send_frame(&output->wlr_output);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XCB_KEY_PRESS:
|
case XCB_KEY_PRESS:
|
||||||
|
@ -174,7 +174,7 @@ static int x11_event(int fd, uint32_t mask, void *data) {
|
||||||
|
|
||||||
static int signal_frame(void *data) {
|
static int signal_frame(void *data) {
|
||||||
struct wlr_x11_backend *x11 = data;
|
struct wlr_x11_backend *x11 = data;
|
||||||
wl_signal_emit(&x11->output.wlr_output.events.frame, &x11->output);
|
wlr_output_send_frame(&x11->output.wlr_output);
|
||||||
wl_event_source_timer_update(x11->frame_timer, 16);
|
wl_event_source_timer_update(x11->frame_timer, 16);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ struct roots_output {
|
||||||
|
|
||||||
struct timespec last_frame;
|
struct timespec last_frame;
|
||||||
pixman_region32_t damage; // in ouput-local coordinates
|
pixman_region32_t damage; // in ouput-local coordinates
|
||||||
bool frame_pending;
|
|
||||||
|
|
||||||
// circular queue for previous damage
|
// circular queue for previous damage
|
||||||
pixman_region32_t previous_damage[ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN];
|
pixman_region32_t previous_damage[ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN];
|
||||||
|
|
|
@ -33,5 +33,6 @@ void wlr_output_update_custom_mode(struct wlr_output *output, int32_t width,
|
||||||
int32_t height, int32_t refresh);
|
int32_t height, int32_t refresh);
|
||||||
void wlr_output_update_enabled(struct wlr_output *output, bool enabled);
|
void wlr_output_update_enabled(struct wlr_output *output, bool enabled);
|
||||||
void wlr_output_update_needs_swap(struct wlr_output *output);
|
void wlr_output_update_needs_swap(struct wlr_output *output);
|
||||||
|
void wlr_output_send_frame(struct wlr_output *output);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,6 +63,7 @@ struct wlr_output {
|
||||||
bool needs_swap;
|
bool needs_swap;
|
||||||
// damage for cursors and fullscreen surface, in output-local coordinates
|
// damage for cursors and fullscreen surface, in output-local coordinates
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
|
bool frame_pending;
|
||||||
float transform_matrix[16];
|
float transform_matrix[16];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -123,6 +124,11 @@ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
|
/**
|
||||||
|
* Manually schedules a `frame` event. If a `frame` event is already pending,
|
||||||
|
* it is a no-op.
|
||||||
|
*/
|
||||||
|
void wlr_output_schedule_frame(struct wlr_output *output);
|
||||||
void wlr_output_set_gamma(struct wlr_output *output,
|
void wlr_output_set_gamma(struct wlr_output *output,
|
||||||
uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b);
|
uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b);
|
||||||
uint32_t wlr_output_get_gamma_size(struct wlr_output *output);
|
uint32_t wlr_output_get_gamma_size(struct wlr_output *output);
|
||||||
|
|
|
@ -338,7 +338,6 @@ static void render_output(struct roots_output *output) {
|
||||||
struct roots_server *server = desktop->server;
|
struct roots_server *server = desktop->server;
|
||||||
|
|
||||||
if (!wlr_output->enabled) {
|
if (!wlr_output->enabled) {
|
||||||
output->frame_pending = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +399,6 @@ static void render_output(struct roots_output *output) {
|
||||||
|
|
||||||
if (!pixman_region32_not_empty(&damage) && !wlr_output->needs_swap) {
|
if (!pixman_region32_not_empty(&damage) && !wlr_output->needs_swap) {
|
||||||
// Output doesn't need swap and isn't damaged, skip rendering completely
|
// Output doesn't need swap and isn't damaged, skip rendering completely
|
||||||
output->frame_pending = false;
|
|
||||||
goto damage_finish;
|
goto damage_finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +468,6 @@ renderer_end:
|
||||||
wlr_renderer_scissor(output->desktop->server->renderer, NULL);
|
wlr_renderer_scissor(output->desktop->server->renderer, NULL);
|
||||||
wlr_renderer_end(server->renderer);
|
wlr_renderer_end(server->renderer);
|
||||||
wlr_output_swap_buffers(wlr_output, &now, &damage);
|
wlr_output_swap_buffers(wlr_output, &now, &damage);
|
||||||
output->frame_pending = true;
|
|
||||||
// same as decrementing, but works on unsigned integers
|
// same as decrementing, but works on unsigned integers
|
||||||
output->previous_damage_idx += ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN - 1;
|
output->previous_damage_idx += ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN - 1;
|
||||||
output->previous_damage_idx %= ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN;
|
output->previous_damage_idx %= ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN;
|
||||||
|
@ -488,21 +485,6 @@ static void output_handle_frame(struct wl_listener *listener, void *data) {
|
||||||
render_output(output);
|
render_output(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_idle_render(void *data) {
|
|
||||||
struct roots_output *output = data;
|
|
||||||
render_output(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void schedule_render(struct roots_output *output) {
|
|
||||||
if (!output->frame_pending) {
|
|
||||||
// TODO: ask the backend to send a frame event when appropriate instead
|
|
||||||
struct wl_event_loop *ev =
|
|
||||||
wl_display_get_event_loop(output->desktop->server->wl_display);
|
|
||||||
wl_event_loop_add_idle(ev, handle_idle_render, output);
|
|
||||||
output->frame_pending = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void output_damage_whole(struct roots_output *output) {
|
static void output_damage_whole(struct roots_output *output) {
|
||||||
int width, height;
|
int width, height;
|
||||||
output_get_transformed_size(output->wlr_output, &width, &height);
|
output_get_transformed_size(output->wlr_output, &width, &height);
|
||||||
|
@ -510,7 +492,7 @@ static void output_damage_whole(struct roots_output *output) {
|
||||||
pixman_region32_union_rect(&output->damage, &output->damage, 0, 0,
|
pixman_region32_union_rect(&output->damage, &output->damage, 0, 0,
|
||||||
width, height);
|
width, height);
|
||||||
|
|
||||||
schedule_render(output);
|
wlr_output_schedule_frame(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool view_accept_damage(struct roots_output *output,
|
static bool view_accept_damage(struct roots_output *output,
|
||||||
|
@ -553,7 +535,7 @@ static void damage_whole_surface(struct wlr_surface *surface,
|
||||||
pixman_region32_union_rect(&output->damage, &output->damage,
|
pixman_region32_union_rect(&output->damage, &output->damage,
|
||||||
box.x, box.y, box.width, box.height);
|
box.x, box.y, box.width, box.height);
|
||||||
|
|
||||||
schedule_render(output);
|
wlr_output_schedule_frame(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void damage_whole_decoration(struct roots_view *view,
|
static void damage_whole_decoration(struct roots_view *view,
|
||||||
|
@ -608,7 +590,7 @@ static void damage_from_surface(struct wlr_surface *surface,
|
||||||
pixman_region32_union(&output->damage, &output->damage, &damage);
|
pixman_region32_union(&output->damage, &output->damage, &damage);
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
schedule_render(output);
|
wlr_output_schedule_frame(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_damage_from_view(struct roots_output *output,
|
void output_damage_from_view(struct roots_output *output,
|
||||||
|
@ -630,7 +612,7 @@ static void output_handle_needs_swap(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, output, needs_swap);
|
wl_container_of(listener, output, needs_swap);
|
||||||
pixman_region32_union(&output->damage, &output->damage,
|
pixman_region32_union(&output->damage, &output->damage,
|
||||||
&output->wlr_output->damage);
|
&output->wlr_output->damage);
|
||||||
schedule_render(output);
|
wlr_output_schedule_frame(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_mode(struct wlr_output *output,
|
static void set_mode(struct wlr_output *output,
|
||||||
|
|
|
@ -499,6 +499,7 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output->frame_pending = true;
|
||||||
output->needs_swap = false;
|
output->needs_swap = false;
|
||||||
pixman_region32_clear(&output->damage);
|
pixman_region32_clear(&output->damage);
|
||||||
|
|
||||||
|
@ -509,6 +510,27 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_output_send_frame(struct wlr_output *output) {
|
||||||
|
output->frame_pending = false;
|
||||||
|
wl_signal_emit(&output->events.frame, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void schedule_frame_handle_idle_timer(void *data) {
|
||||||
|
struct wlr_output *output = data;
|
||||||
|
wlr_output_send_frame(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_output_schedule_frame(struct wlr_output *output) {
|
||||||
|
if (output->frame_pending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ask the backend to send a frame event when appropriate instead
|
||||||
|
struct wl_event_loop *ev = wl_display_get_event_loop(output->display);
|
||||||
|
wl_event_loop_add_idle(ev, schedule_frame_handle_idle_timer, output);
|
||||||
|
output->frame_pending = true;
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_output_set_gamma(struct wlr_output *output,
|
void wlr_output_set_gamma(struct wlr_output *output,
|
||||||
uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) {
|
uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) {
|
||||||
if (output->impl->set_gamma) {
|
if (output->impl->set_gamma) {
|
||||||
|
|
Loading…
Reference in a new issue