summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-15 13:19:58 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-15 13:19:58 +0300
commit3d012d707d0242780cd386868ab511846dc9b0af (patch)
tree131e1621f400f78cba1541f2fbf9591ffcb4ce08 /src/common
parent8d9ee60888e01e5d88c306afe0c77bad02a29e5b (diff)
Add damage presentation and reduce CPU surface latency
Add yasl_cpu_present_damage to submit partial damage rectangles. Skip commit timers for CPU surfaces to prevent display delay. Remove frame callback gating in surface_draw_frame when free buffers exist. Flush the display immediately on CPU present. Forward tearing option to window specifications.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/backend.h1
-rw-r--r--src/common/surface.c22
2 files changed, 21 insertions, 2 deletions
diff --git a/src/common/backend.h b/src/common/backend.h
index e26f9d2..b111d3e 100644
--- a/src/common/backend.h
+++ b/src/common/backend.h
@@ -38,6 +38,7 @@ struct yasl_surface {
/* CPU canvas returned by yasl_cpu_pixels and copied into each drawn frame. */
uint32_t *canvas;
int canvas_width, canvas_height;
+ struct yasl_private_damage_list cpu_damage;
/* Window values last reported through public WINDOW events. */
struct yasl_private_vector2i reported_size;
uint32_t reported_scale_120, reported_state;
diff --git a/src/common/surface.c b/src/common/surface.c
index fa8ee3d..aeca3d8 100644
--- a/src/common/surface.c
+++ b/src/common/surface.c
@@ -195,8 +195,9 @@ static void draw_canvas(yasl_surface *s, struct yasl_private_frame *frame, void
if (!canvas_fit(s, w, h))
return;
memcpy(frame->target.pixels, s->canvas, (size_t)w * (size_t)h * sizeof(uint32_t));
- struct yasl_private_damage_list damage = {.n = -1};
+ struct yasl_private_damage_list damage = s->cpu_damage.n != 0 ? s->cpu_damage : (struct yasl_private_damage_list){.n = -1};
yasl_private_surface_present(s, &frame->target, &damage);
+ s->cpu_damage = (struct yasl_private_damage_list){0};
}
static void register_surface(yasl_surface *s, unsigned flags, yasl_surface *parent, void *userdata)
{
@@ -279,6 +280,7 @@ yasl_surface *yasl_surface_create(const struct yasl_surface_options *o)
.size = {o->width, o->height},
.flags = flags,
.external_gpu = o->type != YASL_SURFACE_CPU,
+ .tearing = o->tearing,
};
yasl_surface *s = o->type == YASL_SURFACE_GL ? create_gl(&spec, attrs, share)
: yasl_private_surface_create_toplevel(display, &spec);
@@ -936,7 +938,7 @@ uint32_t *yasl_cpu_pixels(yasl_surface *s, int *pw, int *ph)
*ph = s->canvas_height;
return s->canvas;
}
-int yasl_cpu_present(yasl_surface *s)
+int yasl_cpu_present_damage(yasl_surface *s, const struct yasl_damage *damage, int count)
{
if (!yasl_public_connected(s))
return -errno;
@@ -944,9 +946,25 @@ int yasl_cpu_present(yasl_surface *s)
return yasl_public_error(ENOTSUP);
if (!canvas_fit(s, s->size.x, s->size.y))
return -errno;
+ if (damage && count > 0) {
+ s->cpu_damage.n = count <= 16 ? count : 16;
+ for (int i = 0; i < s->cpu_damage.n; i++) {
+ s->cpu_damage.rects[i] = (struct yasl_private_rect2i){
+ .x = damage[i].x, .y = damage[i].y,
+ .width = damage[i].width, .height = damage[i].height,
+ };
+ }
+ } else {
+ s->cpu_damage.n = -1;
+ }
yasl_private_surface_request_frame(s);
+ yasl_private_display_flush(s->display);
return 0;
}
+int yasl_cpu_present(yasl_surface *s)
+{
+ return yasl_cpu_present_damage(s, NULL, 0);
+}
/* OpenGL; these may run on a rendering thread, so they read only immutable or atomic state. */
static bool gl_surface(yasl_surface *s)