screencast: use wl_array for format-modifier-pairs

wl_array is a better fit than wl_list. It's less intensive on memory and
fits nicely with the flow of dmabuf_feedback announcing all format
modifier pairs at once and reseting them on change.
This commit is contained in:
columbarius 2022-05-25 21:27:25 +02:00
parent 2d54aeb36d
commit ab0a07142d
3 changed files with 10 additions and 21 deletions

View file

@ -93,7 +93,6 @@ struct xdpw_buffer {
}; };
struct xdpw_format_modifier_pair { struct xdpw_format_modifier_pair {
struct wl_list link;
uint32_t fourcc; uint32_t fourcc;
uint64_t modifier; uint64_t modifier;
}; };
@ -122,7 +121,7 @@ struct xdpw_screencast_context {
struct zwp_linux_dmabuf_v1 *linux_dmabuf; struct zwp_linux_dmabuf_v1 *linux_dmabuf;
struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback; struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback;
struct xdpw_dmabuf_feedback_data feedback_data; struct xdpw_dmabuf_feedback_data feedback_data;
struct wl_list format_modifier_pairs; struct wl_array format_modifier_pairs;
// gbm // gbm
struct gbm_device *gbm; struct gbm_device *gbm;

View file

@ -223,12 +223,12 @@ void xdpw_buffer_destroy(struct xdpw_buffer *buffer) {
bool wlr_query_dmabuf_modifiers(struct xdpw_screencast_context *ctx, uint32_t drm_format, bool wlr_query_dmabuf_modifiers(struct xdpw_screencast_context *ctx, uint32_t drm_format,
uint32_t num_modifiers, uint64_t *modifiers, uint32_t *max_modifiers) { uint32_t num_modifiers, uint64_t *modifiers, uint32_t *max_modifiers) {
if (wl_list_empty(&ctx->format_modifier_pairs)) if (ctx->format_modifier_pairs.size == 0)
return false; return false;
struct xdpw_format_modifier_pair *fm_pair; struct xdpw_format_modifier_pair *fm_pair;
if (num_modifiers == 0) { if (num_modifiers == 0) {
*max_modifiers = 0; *max_modifiers = 0;
wl_list_for_each(fm_pair, &ctx->format_modifier_pairs, link) { wl_array_for_each(fm_pair, &ctx->format_modifier_pairs) {
if (fm_pair->fourcc == drm_format && if (fm_pair->fourcc == drm_format &&
(fm_pair->modifier == DRM_FORMAT_MOD_INVALID || (fm_pair->modifier == DRM_FORMAT_MOD_INVALID ||
gbm_device_get_format_modifier_plane_count(ctx->gbm, fm_pair->fourcc, fm_pair->modifier) > 0)) gbm_device_get_format_modifier_plane_count(ctx->gbm, fm_pair->fourcc, fm_pair->modifier) > 0))
@ -238,7 +238,7 @@ bool wlr_query_dmabuf_modifiers(struct xdpw_screencast_context *ctx, uint32_t dr
} }
uint32_t i = 0; uint32_t i = 0;
wl_list_for_each(fm_pair, &ctx->format_modifier_pairs, link) { wl_array_for_each(fm_pair, &ctx->format_modifier_pairs) {
if (i == num_modifiers) if (i == num_modifiers)
break; break;
if (fm_pair->fourcc == drm_format && if (fm_pair->fourcc == drm_format &&

View file

@ -549,28 +549,17 @@ static void wlr_remove_output(struct xdpw_wlr_output *out) {
static void wlr_format_modifier_pair_add(struct xdpw_screencast_context *ctx, static void wlr_format_modifier_pair_add(struct xdpw_screencast_context *ctx,
uint32_t format, uint64_t modifier) { uint32_t format, uint64_t modifier) {
struct xdpw_format_modifier_pair *fm_pair; struct xdpw_format_modifier_pair *fm_pair;
wl_list_for_each(fm_pair, &ctx->format_modifier_pairs, link) { wl_array_for_each(fm_pair, &ctx->format_modifier_pairs) {
if (fm_pair->fourcc == format && fm_pair->modifier == modifier) { if (fm_pair->fourcc == format && fm_pair->modifier == modifier) {
logprint(TRACE, "wlroots: skipping duplicated format %u (%lu)", fm_pair->fourcc, fm_pair->modifier); logprint(TRACE, "wlroots: skipping duplicated format %u (%lu)", fm_pair->fourcc, fm_pair->modifier);
return; return;
} }
} }
fm_pair = calloc(1, sizeof(struct xdpw_format_modifier_pair)); fm_pair = wl_array_add(&ctx->format_modifier_pairs, sizeof(struct xdpw_format_modifier_pair));
fm_pair->fourcc = format; fm_pair->fourcc = format;
fm_pair->modifier = modifier; fm_pair->modifier = modifier;
logprint(TRACE, "wlroots: format %u (%lu)", fm_pair->fourcc, fm_pair->modifier); logprint(TRACE, "wlroots: format %u (%lu)", fm_pair->fourcc, fm_pair->modifier);
wl_list_insert(&ctx->format_modifier_pairs, &fm_pair->link);
}
static void wlr_format_modifier_pair_emtpy_list(struct xdpw_screencast_context *ctx) {
struct xdpw_format_modifier_pair *fm_pair, *tmp;
wl_list_for_each_safe(fm_pair, tmp, &ctx->format_modifier_pairs, link) {
wl_list_remove(&fm_pair->link);
free(fm_pair);
}
} }
static void linux_dmabuf_handle_modifier(void *data, static void linux_dmabuf_handle_modifier(void *data,
@ -616,7 +605,8 @@ static void linux_dmabuf_feedback_format_table(void *data,
logprint(DEBUG, "wlroots: linux_dmabuf_feedback_format_table called"); logprint(DEBUG, "wlroots: linux_dmabuf_feedback_format_table called");
wlr_format_modifier_pair_emtpy_list(ctx); wl_array_release(&ctx->format_modifier_pairs);
wl_array_init(&ctx->format_modifier_pairs);
ctx->feedback_data.format_table_data = mmap(NULL , size, PROT_READ, MAP_PRIVATE, fd, 0); ctx->feedback_data.format_table_data = mmap(NULL , size, PROT_READ, MAP_PRIVATE, fd, 0);
if (ctx->feedback_data.format_table_data == MAP_FAILED) { if (ctx->feedback_data.format_table_data == MAP_FAILED) {
@ -802,7 +792,7 @@ int xdpw_wlr_screencopy_init(struct xdpw_state *state) {
wl_list_init(&ctx->screencast_instances); wl_list_init(&ctx->screencast_instances);
// initialize a list of format modifier pairs // initialize a list of format modifier pairs
wl_list_init(&ctx->format_modifier_pairs); wl_array_init(&ctx->format_modifier_pairs);
// retrieve registry // retrieve registry
ctx->registry = wl_display_get_registry(state->wl_display); ctx->registry = wl_display_get_registry(state->wl_display);
@ -850,7 +840,7 @@ int xdpw_wlr_screencopy_init(struct xdpw_state *state) {
} }
void xdpw_wlr_screencopy_finish(struct xdpw_screencast_context *ctx) { void xdpw_wlr_screencopy_finish(struct xdpw_screencast_context *ctx) {
wlr_format_modifier_pair_emtpy_list(ctx); wl_array_release(&ctx->format_modifier_pairs);
struct xdpw_wlr_output *output, *tmp_o; struct xdpw_wlr_output *output, *tmp_o;
wl_list_for_each_safe(output, tmp_o, &ctx->output_list, link) { wl_list_for_each_safe(output, tmp_o, &ctx->output_list, link) {