mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-18 06:47:31 -04:00
Merge branch 'drm-layer-state' into 'master'
Draft: backend/drm: move pending layer FB to wlr_drm_connector_state See merge request wlroots/wlroots!4021
This commit is contained in:
commit
63cb673de1
3 changed files with 59 additions and 42 deletions
|
|
@ -344,7 +344,6 @@ static void layer_handle_addon_destroy(struct wlr_addon *addon) {
|
|||
#if HAVE_LIBLIFTOFF
|
||||
liftoff_layer_destroy(layer->liftoff);
|
||||
#endif
|
||||
drm_fb_clear(&layer->pending_fb);
|
||||
drm_fb_clear(&layer->queued_fb);
|
||||
drm_fb_clear(&layer->current_fb);
|
||||
free(layer->candidate_planes);
|
||||
|
|
@ -425,9 +424,16 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn,
|
|||
drm_fb_move(&crtc->cursor->queued_fb, &conn->cursor_pending_fb);
|
||||
}
|
||||
|
||||
struct wlr_drm_layer *layer;
|
||||
wl_list_for_each(layer, &crtc->layers, link) {
|
||||
drm_fb_move(&layer->queued_fb, &layer->pending_fb);
|
||||
if (crtc->liftoff != NULL) {
|
||||
for (size_t i = 0; i < state->layers_len; i++) {
|
||||
struct wlr_drm_layer_state *layer_state = &state->layers[i];
|
||||
struct wlr_drm_layer *layer =
|
||||
get_drm_layer(drm, layer_state->base->layer);
|
||||
drm_fb_clear(&layer->queued_fb);
|
||||
if (layer_state->fb != NULL && layer_state->base->accepted) {
|
||||
layer->queued_fb = drm_fb_lock(layer_state->fb);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The set_cursor() hook is a bit special: it's not really synchronized
|
||||
|
|
@ -436,11 +442,6 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn,
|
|||
// risk ending up in a state where we don't have a cursor FB but
|
||||
// wlr_drm_connector.cursor_enabled is true.
|
||||
// TODO: fix our output interface to avoid this issue.
|
||||
|
||||
struct wlr_drm_layer *layer;
|
||||
wl_list_for_each(layer, &crtc->layers, link) {
|
||||
drm_fb_clear(&layer->pending_fb);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
|
@ -483,10 +484,27 @@ static void drm_connector_state_init(struct wlr_drm_connector_state *state,
|
|||
state->primary_fb = drm_fb_lock(primary->current_fb);
|
||||
}
|
||||
}
|
||||
|
||||
if (base->committed & WLR_OUTPUT_STATE_LAYERS) {
|
||||
state->layers = calloc(base->layers_len, sizeof(state->layers[0]));
|
||||
if (state->layers == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
state->layers_len = base->layers_len;
|
||||
|
||||
for (size_t i = 0; i < base->layers_len; i++) {
|
||||
state->layers[i].base = &base->layers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void drm_connector_state_finish(struct wlr_drm_connector_state *state) {
|
||||
drm_fb_clear(&state->primary_fb);
|
||||
for (size_t i = 0; i < state->layers_len; i++) {
|
||||
drm_fb_clear(&state->layers[i].fb);
|
||||
}
|
||||
free(state->layers);
|
||||
}
|
||||
|
||||
static bool drm_connector_state_update_primary_fb(struct wlr_drm_connector *conn,
|
||||
|
|
@ -538,8 +556,8 @@ static bool drm_connector_state_update_primary_fb(struct wlr_drm_connector *conn
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool drm_connector_set_pending_layer_fbs(struct wlr_drm_connector *conn,
|
||||
const struct wlr_output_state *state) {
|
||||
static bool drm_connector_state_update_layer_fbs(struct wlr_drm_connector *conn,
|
||||
struct wlr_drm_connector_state *state) {
|
||||
struct wlr_drm_backend *drm = conn->backend;
|
||||
|
||||
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||
|
|
@ -551,20 +569,18 @@ static bool drm_connector_set_pending_layer_fbs(struct wlr_drm_connector *conn,
|
|||
return true; // libliftoff is disabled
|
||||
}
|
||||
|
||||
assert(state->committed & WLR_OUTPUT_STATE_LAYERS);
|
||||
assert(state->base->committed & WLR_OUTPUT_STATE_LAYERS);
|
||||
|
||||
for (size_t i = 0; i < state->layers_len; i++) {
|
||||
struct wlr_output_layer_state *layer_state = &state->layers[i];
|
||||
struct wlr_drm_layer_state *layer_state = &state->layers[i];
|
||||
struct wlr_drm_layer *layer =
|
||||
get_or_create_layer(drm, crtc, layer_state->layer);
|
||||
get_or_create_layer(drm, crtc, layer_state->base->layer);
|
||||
if (!layer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layer_state->buffer != NULL) {
|
||||
drm_fb_import(&layer->pending_fb, drm, layer_state->buffer, NULL);
|
||||
} else {
|
||||
drm_fb_clear(&layer->pending_fb);
|
||||
if (layer_state->base->buffer != NULL) {
|
||||
drm_fb_import(&layer_state->fb, drm, layer_state->base->buffer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -647,10 +663,9 @@ static bool drm_connector_test(struct wlr_output *output,
|
|||
goto out;
|
||||
}
|
||||
}
|
||||
if (state->committed & WLR_OUTPUT_STATE_LAYERS) {
|
||||
if (!drm_connector_set_pending_layer_fbs(conn, pending.base)) {
|
||||
return false;
|
||||
}
|
||||
if ((state->committed & WLR_OUTPUT_STATE_LAYERS) &&
|
||||
!drm_connector_state_update_layer_fbs(conn, &pending)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = drm_crtc_commit(conn, &pending, 0, true);
|
||||
|
|
@ -737,10 +752,9 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
|
|||
if (pending.modeset && pending.active) {
|
||||
flags |= DRM_MODE_PAGE_FLIP_EVENT;
|
||||
}
|
||||
if (pending.base->committed & WLR_OUTPUT_STATE_LAYERS) {
|
||||
if (!drm_connector_set_pending_layer_fbs(conn, pending.base)) {
|
||||
return false;
|
||||
}
|
||||
if ((pending.base->committed & WLR_OUTPUT_STATE_LAYERS) &&
|
||||
!drm_connector_state_update_layer_fbs(conn, &pending)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pending.modeset) {
|
||||
|
|
|
|||
|
|
@ -174,18 +174,18 @@ static uint64_t to_fp16(double v) {
|
|||
}
|
||||
|
||||
static bool set_layer_props(struct wlr_drm_backend *drm,
|
||||
const struct wlr_output_layer_state *state, uint64_t zpos) {
|
||||
struct wlr_drm_layer *layer = get_drm_layer(drm, state->layer);
|
||||
const struct wlr_drm_layer_state *state, uint64_t zpos) {
|
||||
struct wlr_drm_layer *layer = get_drm_layer(drm, state->base->layer);
|
||||
|
||||
uint32_t width = 0, height = 0;
|
||||
if (state->buffer != NULL) {
|
||||
width = state->buffer->width;
|
||||
height = state->buffer->height;
|
||||
if (state->base->buffer != NULL) {
|
||||
width = state->base->buffer->width;
|
||||
height = state->base->buffer->height;
|
||||
}
|
||||
|
||||
struct wlr_drm_fb *fb = layer->pending_fb;
|
||||
struct wlr_drm_fb *fb = state->fb;
|
||||
int ret = 0;
|
||||
if (state->buffer == NULL) {
|
||||
if (state->base->buffer == NULL) {
|
||||
ret = liftoff_layer_set_property(layer->liftoff, "FB_ID", 0);
|
||||
} else if (fb == NULL) {
|
||||
liftoff_layer_set_fb_composited(layer->liftoff);
|
||||
|
|
@ -196,8 +196,8 @@ static bool set_layer_props(struct wlr_drm_backend *drm,
|
|||
return false;
|
||||
}
|
||||
|
||||
uint64_t crtc_x = (uint64_t)state->x;
|
||||
uint64_t crtc_y = (uint64_t)state->y;
|
||||
uint64_t crtc_x = (uint64_t)state->base->x;
|
||||
uint64_t crtc_y = (uint64_t)state->base->y;
|
||||
uint64_t crtc_w = (uint64_t)width;
|
||||
uint64_t crtc_h = (uint64_t)height;
|
||||
|
||||
|
|
@ -383,11 +383,9 @@ static bool crtc_commit(struct wlr_drm_connector *conn,
|
|||
liftoff_layer_set_property(crtc->liftoff_composition_layer,
|
||||
"FB_DAMAGE_CLIPS", fb_damage_clips);
|
||||
|
||||
if (state->base->committed & WLR_OUTPUT_STATE_LAYERS) {
|
||||
for (size_t i = 0; i < state->base->layers_len; i++) {
|
||||
const struct wlr_output_layer_state *layer_state = &state->base->layers[i];
|
||||
ok = ok && set_layer_props(drm, layer_state, i + 1);
|
||||
}
|
||||
for (size_t i = 0; i < state->layers_len; i++) {
|
||||
const struct wlr_drm_layer_state *layer_state = &state->layers[i];
|
||||
ok = ok && set_layer_props(drm, layer_state, i + 1);
|
||||
}
|
||||
|
||||
if (crtc->cursor) {
|
||||
|
|
|
|||
|
|
@ -43,8 +43,6 @@ struct wlr_drm_layer {
|
|||
struct wlr_addon addon; // wlr_output_layer.addons
|
||||
struct wl_list link; // wlr_drm_crtc.layers
|
||||
|
||||
/* Buffer to be submitted to the kernel on the next page-flip */
|
||||
struct wlr_drm_fb *pending_fb;
|
||||
/* Buffer submitted to the kernel, will be presented on next vblank */
|
||||
struct wlr_drm_fb *queued_fb;
|
||||
/* Buffer currently displayed on screen */
|
||||
|
|
@ -127,6 +125,13 @@ struct wlr_drm_connector_state {
|
|||
bool active;
|
||||
drmModeModeInfo mode;
|
||||
struct wlr_drm_fb *primary_fb;
|
||||
struct wlr_drm_layer_state *layers;
|
||||
size_t layers_len;
|
||||
};
|
||||
|
||||
struct wlr_drm_layer_state {
|
||||
struct wlr_output_layer_state *base;
|
||||
struct wlr_drm_fb *fb;
|
||||
};
|
||||
|
||||
struct wlr_drm_connector {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue