diff options
Diffstat (limited to 'src/x11')
| -rw-r--r-- | src/x11/window.c | 28 |
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)); |
