summaryrefslogtreecommitdiff
path: root/src/common/surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/surface.c')
-rw-r--r--src/common/surface.c22
1 files changed, 20 insertions, 2 deletions
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)