mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-13 08:22:16 -04:00
output: limit rate of hardware cursor texture change
A client that generates lots of cursor image changes could cause a high render load, or deplete the output's cursor swapchain on some backends. Limit to two renders per frame, and catch up after output commit if necessary.
This commit is contained in:
parent
fd870f6d27
commit
c5641f6de5
4 changed files with 22 additions and 1 deletions
|
|
@ -14,6 +14,11 @@
|
|||
#include "types/wlr_buffer.h"
|
||||
#include "types/wlr_output.h"
|
||||
|
||||
// Maximum of hardware cursor renders per frame.
|
||||
// Many clients don't regroup the buffer commit and the hotspot change in a
|
||||
// single message : typical burst of 2 must still be processed without delay
|
||||
#define MAX_UPLOADS_PER_FRAME 2
|
||||
|
||||
static bool output_set_hardware_cursor(struct wlr_output *output,
|
||||
struct wlr_buffer *buffer, int hotspot_x, int hotspot_y) {
|
||||
if (!output->impl->set_cursor) {
|
||||
|
|
@ -55,6 +60,7 @@ static void output_disable_hardware_cursor(struct wlr_output *output) {
|
|||
output_set_hardware_cursor(output, NULL, 0, 0);
|
||||
output_cursor_damage_whole(output->hardware_cursor);
|
||||
output->hardware_cursor = NULL;
|
||||
output->cursor_pending_upload = NULL;
|
||||
}
|
||||
|
||||
void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) {
|
||||
|
|
@ -288,7 +294,7 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
||||
bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
||||
struct wlr_output *output = cursor->output;
|
||||
|
||||
if (!output->impl->set_cursor || output->software_cursor_locks > 0) {
|
||||
|
|
@ -297,6 +303,11 @@ static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
|||
|
||||
struct wlr_texture *texture = cursor->texture;
|
||||
|
||||
if (texture != NULL && output->cursor_uploaded_this_frame >= MAX_UPLOADS_PER_FRAME) {
|
||||
output->cursor_pending_upload = cursor;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the cursor was hidden or was a software cursor, the hardware
|
||||
// cursor position is outdated
|
||||
output_move_hardware_cursor(cursor->output, (int)cursor->x, (int)cursor->y);
|
||||
|
|
@ -308,6 +319,7 @@ static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
|||
wlr_log(WLR_DEBUG, "Failed to render cursor buffer");
|
||||
return false;
|
||||
}
|
||||
output->cursor_uploaded_this_frame++;
|
||||
}
|
||||
|
||||
struct wlr_box hotspot = {
|
||||
|
|
|
|||
|
|
@ -841,6 +841,12 @@ bool wlr_output_commit_state(struct wlr_output *output,
|
|||
wlr_buffer_unlock(pending.buffer);
|
||||
}
|
||||
|
||||
output->cursor_uploaded_this_frame = 0;
|
||||
if (output->cursor_pending_upload) {
|
||||
output_cursor_attempt_hardware(output->cursor_pending_upload);
|
||||
output->cursor_pending_upload = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue