From e6879616e731e6bc2109fbe50610c8c606e8228a Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 10 May 2023 16:18:44 -0400 Subject: wlr_drm_format: Make structure constant length Don't store modifiers as part of the struct. --- include/wlr/render/drm_format_set.h | 2 +- render/drm_format_set.c | 74 +++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/include/wlr/render/drm_format_set.h b/include/wlr/render/drm_format_set.h index 364a3c8d..8ae930be 100644 --- a/include/wlr/render/drm_format_set.h +++ b/include/wlr/render/drm_format_set.h @@ -22,7 +22,7 @@ struct wlr_drm_format { // The capacity of the array; do not use. size_t capacity; // The actual modifiers - uint64_t modifiers[]; + uint64_t *modifiers; }; /** diff --git a/render/drm_format_set.c b/render/drm_format_set.c index 280d6465..6b917193 100644 --- a/render/drm_format_set.c +++ b/render/drm_format_set.c @@ -9,7 +9,11 @@ #include "render/drm_format_set.h" void wlr_drm_format_finish(struct wlr_drm_format *format) { - // For later + if (!format) { + return; + } + + free(format->modifiers); } void wlr_drm_format_set_finish(struct wlr_drm_format_set *set) { @@ -90,14 +94,14 @@ bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format, struct wlr_drm_format *wlr_drm_format_create(uint32_t format) { size_t capacity = 4; - struct wlr_drm_format *fmt = - calloc(1, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * capacity); + struct wlr_drm_format *fmt = calloc(1, sizeof(*fmt)); if (!fmt) { wlr_log_errno(WLR_ERROR, "Allocation failed"); return NULL; } fmt->format = format; fmt->capacity = capacity; + fmt->modifiers = malloc(sizeof(*fmt->modifiers) * capacity); return fmt; } @@ -120,14 +124,14 @@ bool wlr_drm_format_add(struct wlr_drm_format **fmt_ptr, uint64_t modifier) { if (fmt->len == fmt->capacity) { size_t capacity = fmt->capacity ? fmt->capacity * 2 : 4; - fmt = realloc(fmt, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * capacity); - if (!fmt) { + uint64_t *new_modifiers = realloc(fmt->modifiers, sizeof(*fmt->modifiers) * capacity); + if (!new_modifiers) { wlr_log_errno(WLR_ERROR, "Allocation failed"); return false; } fmt->capacity = capacity; - *fmt_ptr = fmt; + fmt->modifiers = new_modifiers; } fmt->modifiers[fmt->len++] = modifier; @@ -136,14 +140,24 @@ bool wlr_drm_format_add(struct wlr_drm_format **fmt_ptr, uint64_t modifier) { struct wlr_drm_format *wlr_drm_format_dup(const struct wlr_drm_format *format) { assert(format->len <= format->capacity); - size_t format_size = sizeof(struct wlr_drm_format) + - format->capacity * sizeof(format->modifiers[0]); - struct wlr_drm_format *duped_format = malloc(format_size); - if (duped_format == NULL) { + + uint64_t *modifiers = malloc(sizeof(*format->modifiers) * format->capacity); + if (!modifiers) { return NULL; } - memcpy(duped_format, format, format_size); - return duped_format; + + memcpy(modifiers, format->modifiers, sizeof(*format->modifiers) * format->len); + + struct wlr_drm_format *dst = calloc(1, sizeof(*dst)); + if (!dst) { + return NULL; + } + + dst->capacity = format->capacity; + dst->len = format->len; + dst->modifiers = modifiers; + + return dst; } bool wlr_drm_format_set_copy(struct wlr_drm_format_set *dst, const struct wlr_drm_format_set *src) { @@ -177,23 +191,24 @@ struct wlr_drm_format *wlr_drm_format_intersect( const struct wlr_drm_format *a, const struct wlr_drm_format *b) { assert(a->format == b->format); - size_t format_cap = a->len < b->len ? a->len : b->len; - size_t format_size = sizeof(struct wlr_drm_format) + - format_cap * sizeof(a->modifiers[0]); - struct wlr_drm_format *format = calloc(1, format_size); - if (format == NULL) { - wlr_log_errno(WLR_ERROR, "Allocation failed"); - return NULL; + size_t capacity = a->len < b->len ? a->len : b->len; + uint64_t *modifiers = malloc(sizeof(*modifiers) * capacity); + if (!modifiers) { + return false; } - format->format = a->format; - format->capacity = format_cap; + + struct wlr_drm_format fmt = { + .capacity = capacity, + .len = 0, + .modifiers = modifiers, + .format = a->format, + }; for (size_t i = 0; i < a->len; i++) { for (size_t j = 0; j < b->len; j++) { if (a->modifiers[i] == b->modifiers[j]) { - assert(format->len < format->capacity); - format->modifiers[format->len] = a->modifiers[i]; - format->len++; + assert(fmt.len < fmt.capacity); + fmt.modifiers[fmt.len++] = a->modifiers[i]; break; } } @@ -201,12 +216,17 @@ struct wlr_drm_format *wlr_drm_format_intersect( // If the intersection is empty, then the formats aren't compatible with // each other. - if (format->len == 0) { - wlr_drm_format_set_finish(format); - free(format); + if (fmt.len == 0) { + wlr_drm_format_finish(&fmt); return NULL; } + struct wlr_drm_format *format = calloc(1, sizeof(*format)); + if (!format) { + wlr_drm_format_finish(&fmt); + return NULL; + } + *format = fmt; return format; } -- cgit v1.2.3