mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-06 13:48:21 +02:00
gl-renderer: allow to create gl_capture_task of dma-buf type
For now we support creating gl_capture_task only for SHM buffers. This is used when the GL renderer pulls an output capture task from the queue and its buffer type is SHM. In the next commits we'll add support to allow output capture tasks to be created with dma-buf buffers, so we need to extend gl_capture_task to support that as well. Differently from the SHM case, for dma-buf we don't have to do any copy. The gl_capture_task is created just to wait for the blit to finish, and then retire the output capture task. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
parent
c0e129946e
commit
25bb9d32b1
1 changed files with 64 additions and 27 deletions
|
|
@ -188,18 +188,26 @@ struct gl_output_state {
|
|||
|
||||
struct gl_renderer;
|
||||
|
||||
struct gl_capture_task_shm_state {
|
||||
GLuint pbo;
|
||||
int stride;
|
||||
int height;
|
||||
bool reverse;
|
||||
};
|
||||
|
||||
struct gl_capture_task {
|
||||
struct weston_capture_task *task;
|
||||
struct wl_listener destroy_listener;
|
||||
struct wl_event_source *source;
|
||||
struct gl_renderer *gr;
|
||||
struct wl_list link;
|
||||
GLuint pbo;
|
||||
int stride;
|
||||
int height;
|
||||
bool reverse;
|
||||
|
||||
EGLSyncKHR sync;
|
||||
int fd;
|
||||
|
||||
/* shm_state is valid when buffer_type == WESTON_BUFFER_SHM */
|
||||
enum weston_buffer_type buffer_type;
|
||||
struct gl_capture_task_shm_state shm_state;
|
||||
};
|
||||
|
||||
#ifndef HAVE_GBM
|
||||
|
|
@ -1177,7 +1185,9 @@ destroy_capture_task(struct gl_capture_task *gl_task)
|
|||
wl_event_source_remove(gl_task->source);
|
||||
wl_list_remove(&gl_task->link);
|
||||
wl_list_remove(&gl_task->destroy_listener.link);
|
||||
glDeleteBuffers(1, &gl_task->pbo);
|
||||
|
||||
if (gl_task->buffer_type == WESTON_BUFFER_SHM)
|
||||
glDeleteBuffers(1, &gl_task->shm_state.pbo);
|
||||
|
||||
if (gl_task->sync != EGL_NO_SYNC_KHR)
|
||||
gl_task->gr->destroy_sync(gl_task->gr->egl_display,
|
||||
|
|
@ -1197,23 +1207,42 @@ capture_task_parent_destroy_handler(struct wl_listener *l, void *data)
|
|||
destroy_capture_task(gl_task);
|
||||
}
|
||||
|
||||
static struct gl_capture_task_shm_state
|
||||
create_capture_task_shm_state(struct gl_renderer *gr,
|
||||
const struct weston_geometry *rect)
|
||||
{
|
||||
struct gl_capture_task_shm_state shm_state = { 0 };
|
||||
|
||||
glGenBuffers(1, &shm_state.pbo);
|
||||
|
||||
shm_state.stride = (gr->compositor->read_format->bpp / 8) * rect->width;
|
||||
shm_state.height = rect->height;
|
||||
shm_state.reverse = !gl_extensions_has(gr, EXTENSION_ANGLE_PACK_REVERSE_ROW_ORDER);
|
||||
|
||||
return shm_state;
|
||||
}
|
||||
|
||||
static struct gl_capture_task*
|
||||
create_capture_task(struct weston_capture_task *task,
|
||||
struct gl_renderer *gr,
|
||||
const struct weston_geometry *rect)
|
||||
enum weston_buffer_type buffer_type,
|
||||
const struct gl_capture_task_shm_state *shm_state)
|
||||
{
|
||||
struct gl_capture_task *gl_task = xzalloc(sizeof *gl_task);
|
||||
|
||||
gl_task->task = task;
|
||||
gl_task->gr = gr;
|
||||
glGenBuffers(1, &gl_task->pbo);
|
||||
gl_task->stride = (gr->compositor->read_format->bpp / 8) * rect->width;
|
||||
gl_task->height = rect->height;
|
||||
gl_task->reverse =
|
||||
!gl_extensions_has(gr, EXTENSION_ANGLE_PACK_REVERSE_ROW_ORDER);
|
||||
gl_task->buffer_type = buffer_type;
|
||||
gl_task->sync = EGL_NO_SYNC_KHR;
|
||||
gl_task->fd = EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
||||
|
||||
if (buffer_type == WESTON_BUFFER_SHM) {
|
||||
gl_task->shm_state = *shm_state;
|
||||
} else {
|
||||
/* other types are not supported so far */
|
||||
weston_assert_enum(gr->compositor, buffer_type, WESTON_BUFFER_DMABUF);
|
||||
}
|
||||
|
||||
gl_task->destroy_listener.notify = capture_task_parent_destroy_handler;
|
||||
weston_capture_task_add_destroy_listener(task, &gl_task->destroy_listener);
|
||||
|
||||
|
|
@ -1221,32 +1250,34 @@ create_capture_task(struct weston_capture_task *task,
|
|||
}
|
||||
|
||||
static void
|
||||
copy_capture(struct gl_capture_task *gl_task)
|
||||
copy_capture_shm(struct gl_capture_task *gl_task)
|
||||
{
|
||||
struct weston_buffer *buffer =
|
||||
weston_capture_task_get_buffer(gl_task->task);
|
||||
struct wl_shm_buffer *shm = buffer->shm_buffer;
|
||||
struct gl_renderer *gr = gl_task->gr;
|
||||
struct weston_compositor *compositor = gr->compositor;
|
||||
uint8_t *src, *dst;
|
||||
int i;
|
||||
|
||||
assert(shm);
|
||||
weston_assert_enum(compositor, gl_task->buffer_type, WESTON_BUFFER_SHM);
|
||||
weston_assert_ptr_not_null(compositor, shm);
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, gl_task->pbo);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, gl_task->shm_state.pbo);
|
||||
src = gr->map_buffer_range(GL_PIXEL_PACK_BUFFER, 0,
|
||||
gl_task->stride * gl_task->height,
|
||||
gl_task->shm_state.stride * gl_task->shm_state.height,
|
||||
GL_MAP_READ_BIT);
|
||||
dst = wl_shm_buffer_get_data(shm);
|
||||
wl_shm_buffer_begin_access(shm);
|
||||
|
||||
if (!gl_task->reverse) {
|
||||
memcpy(dst, src, gl_task->stride * gl_task->height);
|
||||
if (!gl_task->shm_state.reverse) {
|
||||
memcpy(dst, src, gl_task->shm_state.stride * gl_task->shm_state.height);
|
||||
} else {
|
||||
src += (gl_task->height - 1) * gl_task->stride;
|
||||
for (i = 0; i < gl_task->height; i++) {
|
||||
memcpy(dst, src, gl_task->stride);
|
||||
dst += gl_task->stride;
|
||||
src -= gl_task->stride;
|
||||
src += (gl_task->shm_state.height - 1) * gl_task->shm_state.stride;
|
||||
for (i = 0; i < gl_task->shm_state.height; i++) {
|
||||
memcpy(dst, src, gl_task->shm_state.stride);
|
||||
dst += gl_task->shm_state.stride;
|
||||
src -= gl_task->shm_state.stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1265,7 +1296,9 @@ async_capture_handler(void *data)
|
|||
wl_list_remove(&gl_task->destroy_listener.link);
|
||||
wl_list_init(&gl_task->destroy_listener.link);
|
||||
|
||||
copy_capture(gl_task);
|
||||
if (gl_task->buffer_type == WESTON_BUFFER_SHM)
|
||||
copy_capture_shm(gl_task);
|
||||
|
||||
weston_capture_task_retire_complete(gl_task->task);
|
||||
destroy_capture_task(gl_task);
|
||||
|
||||
|
|
@ -1284,7 +1317,9 @@ async_capture_handler_fd(int fd, uint32_t mask, void *data)
|
|||
wl_list_init(&gl_task->destroy_listener.link);
|
||||
|
||||
if (mask & WL_EVENT_READABLE) {
|
||||
copy_capture(gl_task);
|
||||
if (gl_task->buffer_type == WESTON_BUFFER_SHM)
|
||||
copy_capture_shm(gl_task);
|
||||
|
||||
weston_capture_task_retire_complete(gl_task->task);
|
||||
} else {
|
||||
weston_capture_task_retire_failed(gl_task->task,
|
||||
|
|
@ -1305,6 +1340,7 @@ gl_renderer_do_read_pixels_async(struct gl_renderer *gr,
|
|||
struct weston_buffer *buffer = weston_capture_task_get_buffer(task);
|
||||
const struct pixel_format_info *fmt = buffer->pixel_format;
|
||||
struct gl_capture_task *gl_task;
|
||||
struct gl_capture_task_shm_state shm_state;
|
||||
struct wl_event_loop *loop;
|
||||
int refresh_mhz, refresh_msec;
|
||||
|
||||
|
|
@ -1318,16 +1354,17 @@ gl_renderer_do_read_pixels_async(struct gl_renderer *gr,
|
|||
is_y_flipped(go))
|
||||
glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
|
||||
|
||||
gl_task = create_capture_task(task, gr, rect);
|
||||
shm_state = create_capture_task_shm_state(gr, rect);
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, gl_task->pbo);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, gl_task->stride * gl_task->height,
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, shm_state.pbo);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, shm_state.stride * shm_state.height,
|
||||
NULL, gr->pbo_usage);
|
||||
glReadPixels(rect->x, rect->y, rect->width, rect->height,
|
||||
fmt->gl_format, fmt->gl_type, 0);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
|
||||
loop = wl_display_get_event_loop(gr->compositor->wl_display);
|
||||
gl_task = create_capture_task(task, gr, buffer->type, &shm_state);
|
||||
gl_task->sync = create_render_sync(gr);
|
||||
|
||||
/* Make sure the read back request is flushed. Doing so right between
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue