mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 12:55:58 +01:00
backend/drm: handle output layer damage
This commit is contained in:
parent
7811f22250
commit
aa1055134d
3 changed files with 39 additions and 18 deletions
|
@ -144,15 +144,12 @@ bool create_gamma_lut_blob(struct wlr_drm_backend *drm,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool create_fb_damage_clips_blob(struct wlr_drm_backend *drm,
|
bool create_fb_damage_clips_blob(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_fb *fb, const pixman_region32_t *damage, uint32_t *blob_id) {
|
int width, int height, const pixman_region32_t *damage, uint32_t *blob_id) {
|
||||||
if (!pixman_region32_not_empty(damage)) {
|
if (!pixman_region32_not_empty(damage)) {
|
||||||
*blob_id = 0;
|
*blob_id = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int width = fb->wlr_buf->width;
|
|
||||||
int height = fb->wlr_buf->height;
|
|
||||||
|
|
||||||
pixman_region32_t clipped;
|
pixman_region32_t clipped;
|
||||||
pixman_region32_init(&clipped);
|
pixman_region32_init(&clipped);
|
||||||
pixman_region32_intersect_rect(&clipped, damage, 0, 0, width, height);
|
pixman_region32_intersect_rect(&clipped, damage, 0, 0, width, height);
|
||||||
|
@ -298,8 +295,8 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
||||||
uint32_t fb_damage_clips = 0;
|
uint32_t fb_damage_clips = 0;
|
||||||
if ((state->base->committed & WLR_OUTPUT_STATE_DAMAGE) &&
|
if ((state->base->committed & WLR_OUTPUT_STATE_DAMAGE) &&
|
||||||
crtc->primary->props.fb_damage_clips != 0) {
|
crtc->primary->props.fb_damage_clips != 0) {
|
||||||
create_fb_damage_clips_blob(drm, state->primary_fb,
|
create_fb_damage_clips_blob(drm, state->primary_fb->wlr_buf->width,
|
||||||
&state->base->damage, &fb_damage_clips);
|
state->primary_fb->wlr_buf->height, &state->base->damage, &fb_damage_clips);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prev_vrr_enabled =
|
bool prev_vrr_enabled =
|
||||||
|
|
|
@ -179,7 +179,8 @@ static uint64_t to_fp16(double v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool set_layer_props(struct wlr_drm_backend *drm,
|
static bool set_layer_props(struct wlr_drm_backend *drm,
|
||||||
const struct wlr_output_layer_state *state, uint64_t zpos) {
|
const struct wlr_output_layer_state *state, uint64_t zpos,
|
||||||
|
struct wl_array *fb_damage_clips_arr) {
|
||||||
struct wlr_drm_layer *layer = get_drm_layer(drm, state->layer);
|
struct wlr_drm_layer *layer = get_drm_layer(drm, state->layer);
|
||||||
|
|
||||||
uint32_t width = 0, height = 0;
|
uint32_t width = 0, height = 0;
|
||||||
|
@ -219,6 +220,17 @@ static bool set_layer_props(struct wlr_drm_backend *drm,
|
||||||
uint64_t src_w = to_fp16(src_box.width);
|
uint64_t src_w = to_fp16(src_box.width);
|
||||||
uint64_t src_h = to_fp16(src_box.height);
|
uint64_t src_h = to_fp16(src_box.height);
|
||||||
|
|
||||||
|
uint32_t fb_damage_clips = 0;
|
||||||
|
if (state->damage != NULL) {
|
||||||
|
uint32_t *ptr = wl_array_add(fb_damage_clips_arr, sizeof(fb_damage_clips));
|
||||||
|
if (ptr == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
create_fb_damage_clips_blob(drm, width, height,
|
||||||
|
state->damage, &fb_damage_clips);
|
||||||
|
*ptr = fb_damage_clips;
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
liftoff_layer_set_property(layer->liftoff, "zpos", zpos) == 0 &&
|
liftoff_layer_set_property(layer->liftoff, "zpos", zpos) == 0 &&
|
||||||
liftoff_layer_set_property(layer->liftoff, "CRTC_X", crtc_x) == 0 &&
|
liftoff_layer_set_property(layer->liftoff, "CRTC_X", crtc_x) == 0 &&
|
||||||
|
@ -228,7 +240,8 @@ static bool set_layer_props(struct wlr_drm_backend *drm,
|
||||||
liftoff_layer_set_property(layer->liftoff, "SRC_X", src_x) == 0 &&
|
liftoff_layer_set_property(layer->liftoff, "SRC_X", src_x) == 0 &&
|
||||||
liftoff_layer_set_property(layer->liftoff, "SRC_Y", src_y) == 0 &&
|
liftoff_layer_set_property(layer->liftoff, "SRC_Y", src_y) == 0 &&
|
||||||
liftoff_layer_set_property(layer->liftoff, "SRC_W", src_w) == 0 &&
|
liftoff_layer_set_property(layer->liftoff, "SRC_W", src_w) == 0 &&
|
||||||
liftoff_layer_set_property(layer->liftoff, "SRC_H", src_h) == 0;
|
liftoff_layer_set_property(layer->liftoff, "SRC_H", src_h) == 0 &&
|
||||||
|
liftoff_layer_set_property(layer->liftoff, "FB_DAMAGE_CLIPS", fb_damage_clips) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool devid_from_fd(int fd, dev_t *devid) {
|
static bool devid_from_fd(int fd, dev_t *devid) {
|
||||||
|
@ -327,11 +340,19 @@ static bool crtc_commit(struct wlr_drm_connector *conn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fb_damage_clips = 0;
|
struct wl_array fb_damage_clips_arr = {0};
|
||||||
|
|
||||||
|
uint32_t primary_fb_damage_clips = 0;
|
||||||
if ((state->base->committed & WLR_OUTPUT_STATE_DAMAGE) &&
|
if ((state->base->committed & WLR_OUTPUT_STATE_DAMAGE) &&
|
||||||
crtc->primary->props.fb_damage_clips != 0) {
|
crtc->primary->props.fb_damage_clips != 0) {
|
||||||
create_fb_damage_clips_blob(drm, state->primary_fb,
|
uint32_t *ptr = wl_array_add(&fb_damage_clips_arr, sizeof(primary_fb_damage_clips));
|
||||||
&state->base->damage, &fb_damage_clips);
|
if (ptr == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
create_fb_damage_clips_blob(drm, state->primary_fb->wlr_buf->width,
|
||||||
|
state->primary_fb->wlr_buf->height, &state->base->damage,
|
||||||
|
&primary_fb_damage_clips);
|
||||||
|
*ptr = primary_fb_damage_clips;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prev_vrr_enabled =
|
bool prev_vrr_enabled =
|
||||||
|
@ -387,14 +408,15 @@ static bool crtc_commit(struct wlr_drm_connector *conn,
|
||||||
set_plane_props(crtc->primary, crtc->primary->liftoff_layer, state->primary_fb, 0, 0, 0) &&
|
set_plane_props(crtc->primary, crtc->primary->liftoff_layer, state->primary_fb, 0, 0, 0) &&
|
||||||
set_plane_props(crtc->primary, crtc->liftoff_composition_layer, state->primary_fb, 0, 0, 0);
|
set_plane_props(crtc->primary, crtc->liftoff_composition_layer, state->primary_fb, 0, 0, 0);
|
||||||
liftoff_layer_set_property(crtc->primary->liftoff_layer,
|
liftoff_layer_set_property(crtc->primary->liftoff_layer,
|
||||||
"FB_DAMAGE_CLIPS", fb_damage_clips);
|
"FB_DAMAGE_CLIPS", primary_fb_damage_clips);
|
||||||
liftoff_layer_set_property(crtc->liftoff_composition_layer,
|
liftoff_layer_set_property(crtc->liftoff_composition_layer,
|
||||||
"FB_DAMAGE_CLIPS", fb_damage_clips);
|
"FB_DAMAGE_CLIPS", primary_fb_damage_clips);
|
||||||
|
|
||||||
if (state->base->committed & WLR_OUTPUT_STATE_LAYERS) {
|
if (state->base->committed & WLR_OUTPUT_STATE_LAYERS) {
|
||||||
for (size_t i = 0; i < state->base->layers_len; i++) {
|
for (size_t i = 0; i < state->base->layers_len; i++) {
|
||||||
const struct wlr_output_layer_state *layer_state = &state->base->layers[i];
|
const struct wlr_output_layer_state *layer_state = &state->base->layers[i];
|
||||||
ok = ok && set_layer_props(drm, layer_state, i + 1);
|
ok = ok && set_layer_props(drm, layer_state, i + 1,
|
||||||
|
&fb_damage_clips_arr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,9 +494,11 @@ out:
|
||||||
rollback_blob(drm, &crtc->gamma_lut, gamma_lut);
|
rollback_blob(drm, &crtc->gamma_lut, gamma_lut);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fb_damage_clips != 0 &&
|
uint32_t *fb_damage_clips_ptr;
|
||||||
drmModeDestroyPropertyBlob(drm->fd, fb_damage_clips) != 0) {
|
wl_array_for_each(fb_damage_clips_ptr, &fb_damage_clips_arr) {
|
||||||
wlr_log_errno(WLR_ERROR, "Failed to destroy FB_DAMAGE_CLIPS property blob");
|
if (drmModeDestroyPropertyBlob(drm->fd, *fb_damage_clips_ptr) != 0) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "Failed to destroy FB_DAMAGE_CLIPS property blob");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|
|
@ -36,6 +36,6 @@ bool create_mode_blob(struct wlr_drm_backend *drm,
|
||||||
bool create_gamma_lut_blob(struct wlr_drm_backend *drm,
|
bool create_gamma_lut_blob(struct wlr_drm_backend *drm,
|
||||||
size_t size, const uint16_t *lut, uint32_t *blob_id);
|
size_t size, const uint16_t *lut, uint32_t *blob_id);
|
||||||
bool create_fb_damage_clips_blob(struct wlr_drm_backend *drm,
|
bool create_fb_damage_clips_blob(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_fb *fb, const pixman_region32_t *damage, uint32_t *blob_id);
|
int width, int height, const pixman_region32_t *damage, uint32_t *blob_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue