screencopy: Use linux-dmabuf if available
parent
70216b5829
commit
3fc07f571d
|
@ -47,6 +47,7 @@ struct screencopy {
|
||||||
|
|
||||||
struct zwlr_screencopy_manager_v1* manager;
|
struct zwlr_screencopy_manager_v1* manager;
|
||||||
struct zwlr_screencopy_frame_v1* frame;
|
struct zwlr_screencopy_frame_v1* frame;
|
||||||
|
int version;
|
||||||
|
|
||||||
uint64_t last_time;
|
uint64_t last_time;
|
||||||
uint64_t start_time;
|
uint64_t start_time;
|
||||||
|
@ -55,6 +56,13 @@ struct screencopy {
|
||||||
struct smooth delay_smoother;
|
struct smooth delay_smoother;
|
||||||
double delay;
|
double delay;
|
||||||
bool is_immediate_copy;
|
bool is_immediate_copy;
|
||||||
|
|
||||||
|
uint32_t wl_shm_width, wl_shm_height, wl_shm_stride;
|
||||||
|
enum wl_shm_format wl_shm_format;
|
||||||
|
|
||||||
|
bool have_linux_dmabuf;
|
||||||
|
uint32_t dmabuf_width, dmabuf_height;
|
||||||
|
uint32_t fourcc;
|
||||||
};
|
};
|
||||||
|
|
||||||
void screencopy_init(struct screencopy* self);
|
void screencopy_init(struct screencopy* self);
|
||||||
|
|
|
@ -60,25 +60,49 @@ static void screencopy_stop(struct frame_capture* fc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void screencopy_buffer(void* data,
|
static void screencopy_linux_dmabuf(void* data,
|
||||||
struct zwlr_screencopy_frame_v1* frame,
|
struct zwlr_screencopy_frame_v1* frame,
|
||||||
enum wl_shm_format format, uint32_t width,
|
uint32_t format, uint32_t width, uint32_t height)
|
||||||
uint32_t height, uint32_t stride)
|
|
||||||
{
|
{
|
||||||
struct screencopy* self = data;
|
struct screencopy* self = data;
|
||||||
|
|
||||||
uint32_t fourcc = fourcc_from_wl_shm(format);
|
self->have_linux_dmabuf = true;
|
||||||
wv_buffer_pool_resize(self->pool, WV_BUFFER_SHM, width, height, stride,
|
self->dmabuf_width = width;
|
||||||
fourcc);
|
self->dmabuf_height = height;
|
||||||
|
self->fourcc = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void screencopy_buffer_done(void* data,
|
||||||
|
struct zwlr_screencopy_frame_v1* frame)
|
||||||
|
{
|
||||||
|
struct screencopy* self = data;
|
||||||
|
uint32_t width, height, stride, fourcc;
|
||||||
|
|
||||||
|
if (self->have_linux_dmabuf) {
|
||||||
|
width = self->dmabuf_width;
|
||||||
|
height = self->dmabuf_height;
|
||||||
|
stride = 0;
|
||||||
|
fourcc = self->fourcc;
|
||||||
|
wv_buffer_pool_resize(self->pool, WV_BUFFER_DMABUF, width,
|
||||||
|
height, stride, fourcc);
|
||||||
|
} else {
|
||||||
|
width = self->wl_shm_width;
|
||||||
|
height = self->wl_shm_height;
|
||||||
|
stride = self->wl_shm_stride;
|
||||||
|
fourcc = self->fourcc;
|
||||||
|
wv_buffer_pool_resize(self->pool, WV_BUFFER_SHM, width,
|
||||||
|
height, stride, self->wl_shm_format);
|
||||||
|
}
|
||||||
|
|
||||||
struct wv_buffer* buffer = wv_buffer_pool_acquire(self->pool);
|
struct wv_buffer* buffer = wv_buffer_pool_acquire(self->pool);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
self->frame_capture.status = CAPTURE_FATAL;
|
self->frame_capture.status = CAPTURE_FATAL;
|
||||||
screencopy_stop(&self->frame_capture);
|
screencopy_stop(&self->frame_capture);
|
||||||
self->frame_capture.on_done(&self->frame_capture);
|
self->frame_capture.on_done(&self->frame_capture);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->y_inverted = true;
|
buffer->y_inverted = !self->have_linux_dmabuf;
|
||||||
|
|
||||||
assert(!self->front);
|
assert(!self->front);
|
||||||
self->front = buffer;
|
self->front = buffer;
|
||||||
|
@ -95,6 +119,25 @@ static void screencopy_buffer(void* data,
|
||||||
buffer->wl_buffer);
|
buffer->wl_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void screencopy_buffer(void* data,
|
||||||
|
struct zwlr_screencopy_frame_v1* frame,
|
||||||
|
enum wl_shm_format format, uint32_t width,
|
||||||
|
uint32_t height, uint32_t stride)
|
||||||
|
{
|
||||||
|
struct screencopy* self = data;
|
||||||
|
|
||||||
|
self->wl_shm_format = format;
|
||||||
|
self->wl_shm_width = width;
|
||||||
|
self->wl_shm_height = height;
|
||||||
|
self->wl_shm_stride = stride;
|
||||||
|
|
||||||
|
if (self->version < 3) {
|
||||||
|
self->have_linux_dmabuf = false;
|
||||||
|
screencopy_buffer_done(data, frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void screencopy_flags(void* data,
|
static void screencopy_flags(void* data,
|
||||||
struct zwlr_screencopy_frame_v1* frame,
|
struct zwlr_screencopy_frame_v1* frame,
|
||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
|
@ -177,6 +220,8 @@ static int screencopy__start_capture(struct frame_capture* fc)
|
||||||
|
|
||||||
static const struct zwlr_screencopy_frame_v1_listener frame_listener = {
|
static const struct zwlr_screencopy_frame_v1_listener frame_listener = {
|
||||||
.buffer = screencopy_buffer,
|
.buffer = screencopy_buffer,
|
||||||
|
.linux_dmabuf = screencopy_linux_dmabuf,
|
||||||
|
.buffer_done = screencopy_buffer_done,
|
||||||
.flags = screencopy_flags,
|
.flags = screencopy_flags,
|
||||||
.ready = screencopy_ready,
|
.ready = screencopy_ready,
|
||||||
.failed = screencopy_failed,
|
.failed = screencopy_failed,
|
||||||
|
|
Loading…
Reference in New Issue