mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-17 06:46:39 -04:00
scene/output: disable hardware cursors when idle
When the cursor plane is enabled, a lot of hardware will drain more power. If the screen contents don't change, perform one final render pass to blend everything onto a single plane.
This commit is contained in:
parent
670915eeea
commit
1bdecdb217
2 changed files with 33 additions and 0 deletions
|
|
@ -204,6 +204,8 @@ struct wlr_scene_output {
|
|||
struct wl_list damage_highlight_regions;
|
||||
|
||||
struct wl_array render_list;
|
||||
|
||||
struct wl_event_source *idle_timer;
|
||||
};
|
||||
|
||||
/** A layer shell scene helper */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "util/time.h"
|
||||
|
||||
#define HIGHLIGHT_DAMAGE_FADEOUT_TIME 250
|
||||
#define SCENE_OUTPUT_IDLE_DELAY_MS 10000
|
||||
|
||||
struct wlr_scene_tree *wlr_scene_tree_from_node(struct wlr_scene_node *node) {
|
||||
assert(node->type == WLR_SCENE_NODE_TREE);
|
||||
|
|
@ -1236,6 +1237,11 @@ static void scene_output_handle_commit(struct wl_listener *listener, void *data)
|
|||
WLR_OUTPUT_STATE_ENABLED)) {
|
||||
scene_output_update_geometry(scene_output);
|
||||
}
|
||||
|
||||
if (event->committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||
wl_event_source_timer_update(scene_output->idle_timer,
|
||||
SCENE_OUTPUT_IDLE_DELAY_MS);
|
||||
}
|
||||
}
|
||||
|
||||
static void scene_output_handle_damage(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -1253,6 +1259,22 @@ static void scene_output_handle_needs_frame(struct wl_listener *listener, void *
|
|||
wlr_output_schedule_frame(scene_output->output);
|
||||
}
|
||||
|
||||
static int scene_output_handle_idle(void *data) {
|
||||
struct wlr_scene_output *scene_output = data;
|
||||
|
||||
if (scene_output->output->hardware_cursor == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Paint one frame with hardware cursors disabled. This reduces the
|
||||
// bandwidth used by the hardware and brings down power usage.
|
||||
wlr_output_lock_software_cursors(scene_output->output, true);
|
||||
wlr_output_schedule_frame(scene_output->output);
|
||||
wlr_scene_output_commit(scene_output);
|
||||
wlr_output_lock_software_cursors(scene_output->output, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
|
||||
struct wlr_output *output) {
|
||||
struct wlr_scene_output *scene_output = calloc(1, sizeof(*scene_output));
|
||||
|
|
@ -1260,6 +1282,14 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct wl_event_loop *loop = wl_display_get_event_loop(output->display);
|
||||
scene_output->idle_timer =
|
||||
wl_event_loop_add_timer(loop, scene_output_handle_idle, scene_output);
|
||||
if (scene_output->idle_timer == NULL) {
|
||||
free(scene_output);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scene_output->output = output;
|
||||
scene_output->scene = scene;
|
||||
wlr_addon_init(&scene_output->addon, &output->addons, scene, &output_addon_impl);
|
||||
|
|
@ -1329,6 +1359,7 @@ void wlr_scene_output_destroy(struct wlr_scene_output *scene_output) {
|
|||
wl_list_remove(&scene_output->output_needs_frame.link);
|
||||
|
||||
wl_array_release(&scene_output->render_list);
|
||||
wl_event_source_remove(scene_output->idle_timer);
|
||||
free(scene_output);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue