summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/backend.c9
-rw-r--r--src/common/backend.h16
2 files changed, 25 insertions, 0 deletions
diff --git a/src/common/backend.c b/src/common/backend.c
index b15233f..bb5ae33 100644
--- a/src/common/backend.c
+++ b/src/common/backend.c
@@ -322,6 +322,15 @@ bool yasl_surface_poll_event(struct yasl_surface *s, struct yasl_event *ev)
return input_queue_pop(&s->input, ev);
}
+bool yasl_surface_read_pixels(struct yasl_surface *s, uint32_t *out, size_t cap,
+ struct yasl_vector2i *size)
+{
+ if (!size) return false;
+ *size = (struct yasl_vector2i){0};
+ if (!s || (!out && cap) || !s->display->ops->surface_read_pixels) return false;
+ return s->display->ops->surface_read_pixels(s, out, cap, size);
+}
+
bool yasl_surface_set_pointer_mode(struct yasl_surface *s, enum yasl_pointer_mode mode)
{
if (!s || (mode != YASL_POINTER_NORMAL && mode != YASL_POINTER_RELATIVE))
diff --git a/src/common/backend.h b/src/common/backend.h
index 96ce9e7..13ce9b5 100644
--- a/src/common/backend.h
+++ b/src/common/backend.h
@@ -7,6 +7,8 @@
#include "common/input.h"
#include "common/timing.h"
+#include <string.h>
+
struct yasl_backend_ops;
struct yasl_display {
@@ -43,6 +45,17 @@ void yasl_surface_clear_timers(struct yasl_surface *s);
struct yasl_surface *yasl_create_toplevel(struct yasl_display *d,
const struct yasl_window_spec *spec, void *graphics_device);
+/* Report a presented CPU frame's extent, and copy it when out can hold it. */
+static inline bool yasl_copy_frame(const uint32_t *pixels, struct yasl_vector2i extent,
+ uint32_t *out, size_t cap, struct yasl_vector2i *size)
+{
+ *size = extent;
+ size_t count = (size_t)extent.x * (size_t)extent.y;
+ if (!count || count > cap) return false;
+ memcpy(out, pixels, count * sizeof(*pixels));
+ return true;
+}
+
static inline uint64_t yasl_frame_begin(struct yasl_surface *s)
{
if (++s->frame_generation == 0) ++s->frame_generation;
@@ -95,6 +108,9 @@ struct yasl_backend_ops {
bool (*surface_place_under_pointer)(struct yasl_surface *s, struct yasl_vector2i at);
/* Optional; NULL means the bell is unsupported. */
bool (*surface_bell)(struct yasl_surface *s);
+ /* Optional; NULL means no readback. Fills size only for an available frame. */
+ bool (*surface_read_pixels)(struct yasl_surface *s, uint32_t *out, size_t cap,
+ struct yasl_vector2i *size);
void *(*display_get_native_handle)(struct yasl_display *d);
void *(*surface_get_native_handle)(struct yasl_surface *s);
bool (*surface_get_native_frame)(struct yasl_surface *s,