mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 21:05:58 +01:00
backend/drm: send output layer feedback events
This commit is contained in:
parent
e1335a792a
commit
22d9df2af4
4 changed files with 77 additions and 1 deletions
|
@ -349,6 +349,7 @@ static void layer_handle_addon_destroy(struct wlr_addon *addon) {
|
||||||
drm_fb_clear(&layer->pending_fb);
|
drm_fb_clear(&layer->pending_fb);
|
||||||
drm_fb_clear(&layer->queued_fb);
|
drm_fb_clear(&layer->queued_fb);
|
||||||
drm_fb_clear(&layer->current_fb);
|
drm_fb_clear(&layer->current_fb);
|
||||||
|
free(layer->candidate_planes);
|
||||||
free(layer);
|
free(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,6 +382,8 @@ static struct wlr_drm_layer *get_or_create_layer(struct wlr_drm_backend *drm,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layer->wlr = wlr_layer;
|
||||||
|
|
||||||
#if HAVE_LIBLIFTOFF
|
#if HAVE_LIBLIFTOFF
|
||||||
layer->liftoff = liftoff_layer_create(crtc->liftoff);
|
layer->liftoff = liftoff_layer_create(crtc->liftoff);
|
||||||
if (layer->liftoff == NULL) {
|
if (layer->liftoff == NULL) {
|
||||||
|
@ -391,6 +394,15 @@ static struct wlr_drm_layer *get_or_create_layer(struct wlr_drm_backend *drm,
|
||||||
abort(); // unreachable
|
abort(); // unreachable
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
layer->candidate_planes = calloc(sizeof(bool), drm->num_planes);
|
||||||
|
if (layer->candidate_planes == NULL) {
|
||||||
|
#if HAVE_LIBLIFTOFF
|
||||||
|
liftoff_layer_destroy(layer->liftoff);
|
||||||
|
#endif
|
||||||
|
free(layer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_addon_init(&layer->addon, &wlr_layer->addons, drm, &layer_impl);
|
wlr_addon_init(&layer->addon, &wlr_layer->addons, drm, &layer_impl);
|
||||||
wl_list_insert(&crtc->layers, &layer->link);
|
wl_list_insert(&crtc->layers, &layer->link);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libliftoff.h>
|
#include <libliftoff.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
@ -214,6 +215,62 @@ static bool set_layer_props(struct wlr_drm_backend *drm,
|
||||||
liftoff_layer_set_property(layer->liftoff, "SRC_H", src_h) == 0;
|
liftoff_layer_set_property(layer->liftoff, "SRC_H", src_h) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool devid_from_fd(int fd, dev_t *devid) {
|
||||||
|
struct stat stat;
|
||||||
|
if (fstat(fd, &stat) != 0) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "fstat failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*devid = stat.st_rdev;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_layer_feedback(struct wlr_drm_backend *drm,
|
||||||
|
struct wlr_drm_layer *layer) {
|
||||||
|
bool changed = false;
|
||||||
|
for (size_t i = 0; i < drm->num_planes; i++) {
|
||||||
|
struct wlr_drm_plane *plane = &drm->planes[i];
|
||||||
|
bool is_candidate = liftoff_layer_is_candidate_plane(layer->liftoff,
|
||||||
|
plane->liftoff);
|
||||||
|
if (layer->candidate_planes[i] != is_candidate) {
|
||||||
|
layer->candidate_planes[i] = is_candidate;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!changed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_t target_device;
|
||||||
|
if (!devid_from_fd(drm->fd, &target_device)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_drm_format_set formats = {0};
|
||||||
|
for (size_t i = 0; i < drm->num_planes; i++) {
|
||||||
|
struct wlr_drm_plane *plane = &drm->planes[i];
|
||||||
|
if (!layer->candidate_planes[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < plane->formats.len; j++) {
|
||||||
|
const struct wlr_drm_format *format = plane->formats.formats[j];
|
||||||
|
for (size_t k = 0; k < format->len; k++) {
|
||||||
|
wlr_drm_format_set_add(&formats, format->format,
|
||||||
|
format->modifiers[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_output_layer_feedback_event event = {
|
||||||
|
.target_device = target_device,
|
||||||
|
.formats = &formats,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&layer->wlr->events.feedback, &event);
|
||||||
|
|
||||||
|
wlr_drm_format_set_finish(&formats);
|
||||||
|
}
|
||||||
|
|
||||||
static bool crtc_commit(struct wlr_drm_connector *conn,
|
static bool crtc_commit(struct wlr_drm_connector *conn,
|
||||||
const struct wlr_drm_connector_state *state, uint32_t flags,
|
const struct wlr_drm_connector_state *state, uint32_t flags,
|
||||||
bool test_only) {
|
bool test_only) {
|
||||||
|
@ -380,6 +437,9 @@ static bool crtc_commit(struct wlr_drm_connector *conn,
|
||||||
struct wlr_drm_layer *layer = get_drm_layer(drm, layer_state->layer);
|
struct wlr_drm_layer *layer = get_drm_layer(drm, layer_state->layer);
|
||||||
layer_state->accepted =
|
layer_state->accepted =
|
||||||
!liftoff_layer_needs_composition(layer->liftoff);
|
!liftoff_layer_needs_composition(layer->liftoff);
|
||||||
|
if (!test_only && !layer_state->accepted) {
|
||||||
|
update_layer_feedback(drm, layer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ hwdata = dependency(
|
||||||
|
|
||||||
libliftoff = dependency(
|
libliftoff = dependency(
|
||||||
'libliftoff',
|
'libliftoff',
|
||||||
version: '>=0.2.0',
|
version: '>=0.4.0',
|
||||||
fallback: 'libliftoff',
|
fallback: 'libliftoff',
|
||||||
required: false,
|
required: false,
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct wlr_drm_plane {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_layer {
|
struct wlr_drm_layer {
|
||||||
|
struct wlr_output_layer *wlr;
|
||||||
struct liftoff_layer *liftoff;
|
struct liftoff_layer *liftoff;
|
||||||
struct wlr_addon addon; // wlr_output_layer.addons
|
struct wlr_addon addon; // wlr_output_layer.addons
|
||||||
struct wl_list link; // wlr_drm_crtc.layers
|
struct wl_list link; // wlr_drm_crtc.layers
|
||||||
|
@ -50,6 +51,9 @@ struct wlr_drm_layer {
|
||||||
struct wlr_drm_fb *current_fb;
|
struct wlr_drm_fb *current_fb;
|
||||||
|
|
||||||
int pending_width, pending_height;
|
int pending_width, pending_height;
|
||||||
|
|
||||||
|
// One entry per wlr_drm_backend.planes
|
||||||
|
bool *candidate_planes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_crtc {
|
struct wlr_drm_crtc {
|
||||||
|
|
Loading…
Reference in a new issue