summaryrefslogtreecommitdiff
path: root/src/x11/window.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-12 14:27:51 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-12 14:27:51 +0300
commit9ed89c17dee752154c36d71cae93d20cccfc71ef (patch)
treea32cd894643ff6f6ebce83dd745bd24b35eb6520 /src/x11/window.c
parentaedd863e6f66fd446227e9b107bc9c1970092634 (diff)
perf: optimize hot-path loops, data structures, and cache locality
Diffstat (limited to 'src/x11/window.c')
-rw-r--r--src/x11/window.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/x11/window.c b/src/x11/window.c
index 5e1b612..271c128 100644
--- a/src/x11/window.c
+++ b/src/x11/window.c
@@ -1280,10 +1280,32 @@ static bool present(struct yasl_surface *base, const struct yasl_framebuffer *fb
XImage *im = s->image;
bool direct = im->bits_per_pixel == 32 && im->red_mask == 0xff0000 &&
im->green_mask == 0xff00 && im->blue_mask == 0xff;
- for (int y = 0; y < s->size.y; y++) {
+ int y_start = 0, y_end = s->size.y;
+ int x_start = 0, x_end = s->size.x;
+ if (damage->n >= 0) {
+ y_start = s->size.y; y_end = 0;
+ x_start = s->size.x; x_end = 0;
+ for (int i = 0; i < damage->n; i++) {
+ struct yasl_rect2i r = damage->rects[i];
+ int y0 = r.y > 0 ? r.y : 0;
+ int y1 = (r.y + r.height < s->size.y) ? r.y + r.height : s->size.y;
+ int x0 = r.x > 0 ? r.x : 0;
+ int x1 = (r.x + r.width < s->size.x) ? r.x + r.width : s->size.x;
+ if (y0 < y_start) y_start = y0;
+ if (y1 > y_end) y_end = y1;
+ if (x0 < x_start) x_start = x0;
+ if (x1 > x_end) x_end = x1;
+ }
+ if (y_start >= y_end || x_start >= x_end) {
+ y_start = y_end = x_start = x_end = 0;
+ }
+ }
+ size_t copy_bytes = (size_t)(x_end - x_start) * 4;
+ for (int y = y_start; y < y_end; y++) {
const uint32_t *row = s->pixels + (size_t)y * s->size.x;
- if (direct) memcpy(im->data + (size_t)y * im->bytes_per_line, row, (size_t)s->size.x * 4);
- else for (int x = 0; x < s->size.x; x++) {
+ if (direct) memcpy(im->data + (size_t)y * im->bytes_per_line + (size_t)x_start * 4,
+ row + x_start, copy_bytes);
+ else for (int x = x_start; x < x_end; x++) {
uint32_t p = row[x];
XPutPixel(im, x, y, component((p >> 16) & 255, im->red_mask) |
component((p >> 8) & 255, im->green_mask) | component(p & 255, im->blue_mask));