From 536847cb5b16c9092469294d0c5a3c44d03264e3 Mon Sep 17 00:00:00 2001 From: Jack Zeal Date: Fri, 27 Mar 2026 20:57:28 -0700 Subject: [PATCH] Use cache for title bar double beveled borders --- include/common/borderset.h | 4 +- src/common/borderset.c | 127 +++++++++++++++++++++++++--- src/common/lab-scene-rect.c | 2 +- src/server.c | 6 +- src/ssd/ssd-border.c | 164 +++++------------------------------- 5 files changed, 143 insertions(+), 160 deletions(-) diff --git a/include/common/borderset.h b/include/common/borderset.h index 2339b98a..f0fc170d 100644 --- a/include/common/borderset.h +++ b/include/common/borderset.h @@ -21,9 +21,9 @@ struct borderset { extern struct borderset * borderCache; -struct borderset * getBorders(uint32_t id, int size, int type); +struct borderset * getBorders(uint32_t id, int size, int type, int bevelSize); -struct borderset * createBuffer(uint32_t id, int size, int type); +struct borderset * createBuffer(uint32_t id, int size, int type, int bevelSize); void clearBorderCache(struct borderset *borderset); diff --git a/src/common/borderset.c b/src/common/borderset.c index f4e352b5..2f80fc85 100644 --- a/src/common/borderset.c +++ b/src/common/borderset.c @@ -2,8 +2,7 @@ #include "common/mem.h" #include "common/macros.h" - -struct borderset * getBorders(uint32_t id, int size, int type) { +struct borderset * getBorders(uint32_t id, int size, int type, int bevelSize) { struct borderset * current = borderCache; struct borderset * last; while (current != NULL) { @@ -16,16 +15,16 @@ struct borderset * getBorders(uint32_t id, int size, int type) { // Fall through, we need to create a buffer. if (borderCache == NULL) { - borderCache = createBuffer(id, size, type); + borderCache = createBuffer(id, size, type, bevelSize); return borderCache; } else { - last->next = createBuffer(id, size, type); + last->next = createBuffer(id, size, type, bevelSize); return last->next; } return NULL; } -struct borderset * createBuffer(uint32_t id, int size, int type) { +struct borderset * createBuffer(uint32_t id, int size, int type, int bevelSize) { struct borderset *newBorderset = znew(*newBorderset); newBorderset->next = NULL; @@ -57,17 +56,19 @@ struct borderset * createBuffer(uint32_t id, int size, int type) { uint32_t ll32 = ((uint32_t)a << 24) | ((uint32_t)r0 << 16) | ((uint32_t)g0 << 8) | (uint32_t)b0; - + + // All borders have NxN corners newBorderset->tl = znew_n(uint32_t, size*size); newBorderset->tr = znew_n(uint32_t, size*size); newBorderset->bl = znew_n(uint32_t, size*size); newBorderset->br = znew_n(uint32_t, size*size); - newBorderset->top = znew(uint32_t); - newBorderset->left = znew(uint32_t); - newBorderset->right = znew(uint32_t); - newBorderset->bottom = znew(uint32_t); + switch(type) { - case 1: + case 1: // Single bevel borders have 1x1 sides + newBorderset->top = znew(uint32_t); + newBorderset->left = znew(uint32_t); + newBorderset->right = znew(uint32_t); + newBorderset->bottom = znew(uint32_t); *newBorderset->top = hl32; *newBorderset->left = hl32; *newBorderset->right = ll32; @@ -89,6 +90,109 @@ struct borderset * createBuffer(uint32_t id, int size, int type) { case 2: + newBorderset->top = znew_n(uint32_t, size); + newBorderset->left = znew_n(uint32_t, size); + newBorderset->right = znew_n(uint32_t, size); + newBorderset->bottom = znew_n(uint32_t, size); + + for (int i = 0; i < size; i++) { + if (ileft[i] = hl32; + newBorderset->top[i] = hl32; + newBorderset->right[i] = hl32; + newBorderset->bottom[i] = hl32; + + } else if (i > (size-bevelSize-1)) { + newBorderset->left[i] = ll32; + newBorderset->top[i] = ll32; + newBorderset->right[i] = ll32; + newBorderset->bottom[i] = ll32; + + } else { + newBorderset->left[i] = id; + newBorderset->top[i] = id; + newBorderset->right[i] = id; + newBorderset->bottom[i] = id; + } + } + + // Blank corners... + for (int i=0; itl[PIXELSIZED(i, j, size)] = id; + newBorderset->tr[PIXELSIZED(i, j, size)] = id; + newBorderset->bl[PIXELSIZED(i, j, size)] = id; + newBorderset->br[PIXELSIZED(i, j, size)] = id; + } + } + + + // Main Corners + for (int i=0; i < bevelSize; i++) { + + // Solid bar parts + for (int j=0; jtl[PIXELSIZED(j, i, size)] = hl32; + // First "bevel size" top columns are highlighted + newBorderset->tl[PIXELSIZED(i, j, size)] = hl32; + + // Bottom Right corner: Entire "bevel size" last rows are lowlight + newBorderset->br[PIXELSIZED(j, (size-1-i), size)] = ll32; + // Last "bevel size" columns are lowlight + newBorderset->br[PIXELSIZED((size-1-i), j, size)] = ll32; + + + // Bottom left corner: Entire "bevel size" last rows are lowlight + newBorderset->bl[PIXELSIZED(j, (size-1-i), size)] = ll32; + // First "bevel size" columns are highlight, except for the bottom right corner + newBorderset->bl[PIXELSIZED(i, j, size)] = hl32; + + // Top Right corner: Entire "bevel size" first rows are highlight + newBorderset->tr[PIXELSIZED(j, i, size)] = hl32; + // Last "bevel size" columns are lowlight, except for the top left + newBorderset->tr[PIXELSIZED((size-1-i), j, size)] = ll32; + + } + } + // Beveled Corner Parts + for (int i=0; i < bevelSize; i++) { + + for (int j=0; jbl[PIXELSIZED(i, (size - 1 - j), size)] = (j >= i) ? hl32 : ll32; + + // Top Right corner: + // Last "bevel size" columns are lowlight, except for the top left + newBorderset->tr[PIXELSIZED((size-1-i), j, size)] = (j > i) ? ll32 : hl32; + + + // Inner Corners + // Top left corner: Bottom right is all dark + newBorderset->tl[PIXELSIZED((size-1-i), (size - 1 - j), size)] = ll32; + + // Bottom Right corner: Top left is all light + newBorderset->br[PIXELSIZED(i, j, size)] = hl32; + + // Top Right corner: + // Interior bottom left is dark on top, light on bottom + newBorderset->tr[PIXELSIZED(i, (size-1-j), size)] = (i > j) ? hl32 : ll32; + + // Bottom Left corner: + // Interior top right is dark on top, light on bottom + newBorderset->bl[PIXELSIZED((size-1-i), j, size)] = (i > j) ? ll32 : hl32; + + + + } + + + } + + + break; @@ -103,6 +207,7 @@ void clearBorderCache(struct borderset * borderset) if (borderset->next != NULL) { clearBorderCache(borderset->next); } + free(borderset->top); free(borderset->left); free(borderset->right); diff --git a/src/common/lab-scene-rect.c b/src/common/lab-scene-rect.c index e652e452..cebab211 100644 --- a/src/common/lab-scene-rect.c +++ b/src/common/lab-scene-rect.c @@ -52,7 +52,7 @@ lab_scene_rect_create(struct wlr_scene_tree *parent, float a = color[3]; int bw = rect->border_width; uint32_t colour32 = (uint32_t)(a*255) << 24 | (uint32_t)(r*255) << 16 | (uint32_t)(g*255) << 8 | (uint32_t)(b*255); - struct borderset * renderedborders = getBorders(colour32, bw, 1); + struct borderset * renderedborders = getBorders(colour32, bw, 1, 0); diff --git a/src/server.c b/src/server.c index 4461c042..3a3c2573 100644 --- a/src/server.c +++ b/src/server.c @@ -86,6 +86,10 @@ reload_config_and_theme(void) scaled_buffer_invalidate_sharing(); rcxml_finish(); + clearBorderCache(borderCache); + borderCache = NULL; + + rcxml_read(rc.config_file); theme_finish(rc.theme); theme_init(rc.theme, rc.theme_name); @@ -101,8 +105,6 @@ reload_config_and_theme(void) } cycle_finish(/*switch_focus*/ false); - clearBorderCache(borderCache); - borderCache = NULL; menu_reconfigure(); seat_reconfigure(); regions_reconfigure(); diff --git a/src/ssd/ssd-border.c b/src/ssd/ssd-border.c index 91815409..1309e752 100644 --- a/src/ssd/ssd-border.c +++ b/src/ssd/ssd-border.c @@ -11,6 +11,7 @@ #include "ssd-internal.h" #include "theme.h" #include "view.h" +#include "common/borderset.h" @@ -56,185 +57,60 @@ ssd_border_create(struct ssd *ssd) int bevelSize = theme->border_bevel_width; // TODO: configurable /* From Pull request 3382 */ - uint8_t r = color[0] * 255; - uint8_t g = color[1] * 255; - uint8_t b = color[2] * 255; - uint8_t a = color[3] * 255; - - /* highlight */ - uint8_t r1 = MIN(r * 5 / 4, a); - uint8_t g1 = MIN(g * 5 / 4, a); - uint8_t b1 = MIN(b * 5 / 4, a); - - /* darker outline */ - uint8_t r0 = r / 2; - uint8_t g0 = g / 2; - uint8_t b0 = b / 2; - - uint32_t col = ((uint32_t)a << 24) | ((uint32_t)r << 16) - | ((uint32_t)g << 8) | b; - uint32_t col0 = ((uint32_t)a << 24) | ((uint32_t)r0 << 16) - | ((uint32_t)g0 << 8) | b0; - uint32_t col1 = ((uint32_t)a << 24) | ((uint32_t)r1 << 16) - | ((uint32_t)g1 << 8) | b1; - - - uint32_t *left_data = znew_n(uint32_t, bw); - uint32_t *top_data = znew_n(uint32_t, bw); - uint32_t *right_data = znew_n(uint32_t, theme->border_width); - uint32_t *bottom_data = znew_n(uint32_t, theme->border_width); - - for (int i = 0; i < bw; i++) { - if (i (bw-bevelSize-1)) { - left_data[i] = col0; - top_data[i] = col0; - right_data[i] = col0; - bottom_data[i] = col0; - - } else { - left_data[i] = col; - top_data[i] = col; - right_data[i] = col; - bottom_data[i] = col; - } - } - - - uint32_t *tl_data = znew_n(uint32_t, bw*bw); - uint32_t *tr_data = znew_n(uint32_t, bw*bw); - uint32_t *bl_data = znew_n(uint32_t, bw*bw); - uint32_t *br_data = znew_n(uint32_t, bw*bw); - // Fill with solid - for (int i=0; i= i) ? col1 : col0; - - // Top Right corner: - // Last "bevel size" columns are lowlight, except for the top left - tr_data[PIXEL((bw-1-i), j)] = (j > i) ? col0 : col1; - - - // Inner Corners - // Top left corner: Bottom right is all dark - tl_data[PIXEL((bw-1-i), (bw - 1 - j))] = col0; - - // Bottom Right corner: Top left is all light - br_data[PIXEL(i, j)] = col1; - - // Top Right corner: - // Interior bottom left is dark on top, light on bottom - tr_data[PIXEL(i, (bw-1-j))] = (i > j) ? col1 : col0; - - // Bottom Left corner: - // Interior top right is dark on top, light on bottom - bl_data[PIXEL((bw-1-i), j)] = (i > j) ? col0 : col1; - - - - } - - - } + float r = color[0]; + float g = color[1]; + float b = color[2]; + float a = color[3]; + uint32_t colour32 = (uint32_t)(a*255) << 24 | (uint32_t)(r*255) << 16 | (uint32_t)(g*255) << 8 | (uint32_t)(b*255); + struct borderset * renderedborders = getBorders(colour32, bw, 2, bevelSize); struct lab_data_buffer *ttexture_buffer = - buffer_create_from_data(top_data, 1,theme->border_width, + buffer_create_from_data(renderedborders->top, 1,theme->border_width, 4); subtree->ttexture = wlr_scene_buffer_create(parent, &ttexture_buffer->base); - wlr_buffer_drop(&ttexture_buffer->base); + struct lab_data_buffer *btexture_buffer = - buffer_create_from_data(bottom_data, 1,theme->border_width, + buffer_create_from_data(renderedborders->bottom, 1,theme->border_width, 4); subtree->btexture = wlr_scene_buffer_create(parent, &btexture_buffer->base); - wlr_buffer_drop(&btexture_buffer->base); + struct lab_data_buffer *ltexture_buffer = - buffer_create_from_data(left_data, theme->border_width, 1, + buffer_create_from_data(renderedborders->left, theme->border_width, 1, 4*theme->border_width); subtree->ltexture = wlr_scene_buffer_create(parent, <exture_buffer->base); - wlr_buffer_drop(<exture_buffer->base); + struct lab_data_buffer *rtexture_buffer = - buffer_create_from_data(right_data, theme->border_width, 1, + buffer_create_from_data(renderedborders->right, theme->border_width, 1, 4*theme->border_width); subtree->rtexture = wlr_scene_buffer_create(parent, &rtexture_buffer->base); - wlr_buffer_drop(&rtexture_buffer->base); + struct lab_data_buffer *tltexture_buffer = - buffer_create_from_data(tl_data, theme->border_width, theme->border_width, + buffer_create_from_data(renderedborders->tl, theme->border_width, theme->border_width, 4*theme->border_width); subtree->tlcorner = wlr_scene_buffer_create(parent, &tltexture_buffer->base); - wlr_buffer_drop(&tltexture_buffer->base); struct lab_data_buffer *trtexture_buffer = - buffer_create_from_data(tr_data, theme->border_width, theme->border_width, + buffer_create_from_data(renderedborders->tr, theme->border_width, theme->border_width, 4*theme->border_width); subtree->trcorner = wlr_scene_buffer_create(parent, &trtexture_buffer->base); - wlr_buffer_drop(&trtexture_buffer->base); + struct lab_data_buffer *bltexture_buffer = - buffer_create_from_data(bl_data, theme->border_width, theme->border_width, + buffer_create_from_data(renderedborders->bl, theme->border_width, theme->border_width, 4*theme->border_width); subtree->blcorner = wlr_scene_buffer_create(parent, &bltexture_buffer->base); - wlr_buffer_drop(&bltexture_buffer->base); struct lab_data_buffer *brtexture_buffer = - buffer_create_from_data(br_data, theme->border_width, theme->border_width, + buffer_create_from_data(renderedborders->br, theme->border_width, theme->border_width, 4*theme->border_width); subtree->brcorner = wlr_scene_buffer_create(parent, &brtexture_buffer->base); - wlr_buffer_drop(&brtexture_buffer->base); } else { subtree->left = lab_wlr_scene_rect_create(parent,