Skip to content

Commit 3a21d01

Browse files
committed
Cache transform buffer to reduce per-frame malloc
This implements transform buffer cache in twin_pixmap_t to eliminate malloc and free on every transform compositing operation. Previous code allocated and freed the xform buffer for each transformation, creating unnecessary allocation overhead in the render loop.
1 parent b7af724 commit 3a21d01

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

include/twin.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ typedef struct _twin_pixmap {
253253
#endif
254254

255255
twin_window_t *window; /**< Associated window (if any) */
256+
257+
/* Transform buffer cache for compositing operations */
258+
void *xform_cache; /**< Cached xform buffer */
259+
size_t xform_cache_size; /**< Cached xform buffer size in bytes */
256260
} twin_pixmap_t;
257261

258262
/**

src/draw-builtin.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -633,10 +633,22 @@ static twin_xform_t *twin_pixmap_init_xform(twin_pixmap_t *pixmap,
633633
if (fmt == TWIN_RGB16)
634634
fmt = TWIN_ARGB32;
635635

636-
twin_xform_t *xform =
637-
calloc(1, sizeof(twin_xform_t) + width * twin_bytes_per_pixel(fmt));
638-
if (!xform)
639-
return NULL;
636+
size_t required_size =
637+
sizeof(twin_xform_t) + (size_t) width * twin_bytes_per_pixel(fmt);
638+
639+
/* Reuse cached xform buffer if large enough */
640+
twin_xform_t *xform;
641+
if (pixmap->xform_cache && pixmap->xform_cache_size >= required_size) {
642+
xform = (twin_xform_t *) pixmap->xform_cache;
643+
} else {
644+
/* Need larger cache - reallocate */
645+
void *new_cache = realloc(pixmap->xform_cache, required_size);
646+
if (!new_cache)
647+
return NULL;
648+
pixmap->xform_cache = new_cache;
649+
pixmap->xform_cache_size = required_size;
650+
xform = (twin_xform_t *) new_cache;
651+
}
640652

641653
xform->span.v = (twin_argb32_t *) (char *) (xform + 1);
642654
xform->pixmap = pixmap;
@@ -650,7 +662,9 @@ static twin_xform_t *twin_pixmap_init_xform(twin_pixmap_t *pixmap,
650662

651663
static void twin_pixmap_free_xform(twin_xform_t *xform)
652664
{
653-
free(xform);
665+
/* Xform buffer is now cached in pixmap - don't free */
666+
/* This function is kept for API compatibility but does nothing */
667+
(void) xform;
654668
}
655669

656670
#define FX(x) twin_int_to_fixed(x)

src/pixmap.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ twin_pixmap_t *twin_pixmap_create(twin_format_t format,
5252
pixmap->shadow = false;
5353
#endif
5454
pixmap->window = NULL; /* Initialize window field */
55+
pixmap->xform_cache = NULL;
56+
pixmap->xform_cache_size = 0;
5557
pixmap->p.v = pixmap + 1;
5658
memset(pixmap->p.v, '\0', space);
5759
return pixmap;
@@ -82,6 +84,8 @@ twin_pixmap_t *twin_pixmap_create_const(twin_format_t format,
8284
pixmap->stride = stride;
8385
pixmap->disable = 0;
8486
pixmap->window = NULL; /* Initialize window field */
87+
pixmap->xform_cache = NULL;
88+
pixmap->xform_cache_size = 0;
8589
pixmap->p = pixels;
8690
return pixmap;
8791
}
@@ -90,6 +94,7 @@ void twin_pixmap_destroy(twin_pixmap_t *pixmap)
9094
{
9195
if (pixmap->screen)
9296
twin_pixmap_hide(pixmap);
97+
free(pixmap->xform_cache); /* Free xform buffer cache */
9398
free(pixmap);
9499
}
95100

0 commit comments

Comments
 (0)