mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2025-12-21 06:20:09 +01:00
gl-renderer: support automatically downloading FBO renderbuffers
For software backends like VNC, support downloading the FBO renderbuffer contents via glReadPixels automatically at the end of repaint_output. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
parent
4a271bdaae
commit
b1606a9f2c
3 changed files with 44 additions and 5 deletions
|
|
@ -294,7 +294,7 @@ headless_output_enable_gl(struct headless_output *output)
|
||||||
output->renderbuffer =
|
output->renderbuffer =
|
||||||
renderer->gl->create_fbo(&output->base, b->formats[0],
|
renderer->gl->create_fbo(&output->base, b->formats[0],
|
||||||
options.fb_size.width,
|
options.fb_size.width,
|
||||||
options.fb_size.height);
|
options.fb_size.height, NULL);
|
||||||
if (!output->renderbuffer)
|
if (!output->renderbuffer)
|
||||||
goto err_renderbuffer;
|
goto err_renderbuffer;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ struct gl_renderbuffer {
|
||||||
/* The fbo value zero represents the default surface framebuffer. */
|
/* The fbo value zero represents the default surface framebuffer. */
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
GLuint rb;
|
GLuint rb;
|
||||||
|
uint32_t *pixels;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
int age;
|
int age;
|
||||||
};
|
};
|
||||||
|
|
@ -760,7 +761,7 @@ gl_renderer_create_dummy_renderbuffer(struct weston_output *output)
|
||||||
static struct weston_renderbuffer *
|
static struct weston_renderbuffer *
|
||||||
gl_renderer_create_fbo(struct weston_output *output,
|
gl_renderer_create_fbo(struct weston_output *output,
|
||||||
const struct pixel_format_info *format,
|
const struct pixel_format_info *format,
|
||||||
int width, int height)
|
int width, int height, uint32_t *pixels)
|
||||||
{
|
{
|
||||||
struct gl_renderer *gr = get_renderer(output->compositor);
|
struct gl_renderer *gr = get_renderer(output->compositor);
|
||||||
struct gl_output_state *go = get_output_state(output);
|
struct gl_output_state *go = get_output_state(output);
|
||||||
|
|
@ -805,6 +806,8 @@ gl_renderer_create_fbo(struct weston_output *output,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderbuffer->pixels = pixels;
|
||||||
|
|
||||||
pixman_region32_init(&renderbuffer->base.damage);
|
pixman_region32_init(&renderbuffer->base.damage);
|
||||||
/*
|
/*
|
||||||
* One reference is kept on the renderbuffer_list,
|
* One reference is kept on the renderbuffer_list,
|
||||||
|
|
@ -2028,7 +2031,6 @@ gl_renderer_repaint_output(struct weston_output *output,
|
||||||
glFlush();
|
glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_clear(&rb->base.damage);
|
|
||||||
rb->border_damage = BORDER_STATUS_CLEAN;
|
rb->border_damage = BORDER_STATUS_CLEAN;
|
||||||
go->border_status = BORDER_STATUS_CLEAN;
|
go->border_status = BORDER_STATUS_CLEAN;
|
||||||
|
|
||||||
|
|
@ -2040,6 +2042,39 @@ gl_renderer_repaint_output(struct weston_output *output,
|
||||||
|
|
||||||
update_buffer_release_fences(compositor, output);
|
update_buffer_release_fences(compositor, output);
|
||||||
|
|
||||||
|
if (rb->pixels) {
|
||||||
|
uint32_t *pixels = rb->pixels;
|
||||||
|
int stride = go->fb_size.width;
|
||||||
|
pixman_box32_t *extents = &rb->base.damage.extents;
|
||||||
|
struct weston_geometry rect = {
|
||||||
|
.x = go->area.x,
|
||||||
|
.width = go->area.width,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (gr->fan_debug) {
|
||||||
|
rect.y = go->fb_size.height - go->area.y - go->area.height;
|
||||||
|
rect.height = go->area.height;
|
||||||
|
} else {
|
||||||
|
rect.y = go->fb_size.height - go->area.y - extents->y2;
|
||||||
|
rect.height = extents->y2 - extents->y1;
|
||||||
|
pixels += rect.width * extents->y1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gr->gl_version >= gr_gl_version(3, 0) && ! gr->fan_debug) {
|
||||||
|
glPixelStorei(GL_PACK_ROW_LENGTH, stride);
|
||||||
|
rect.width = extents->x2 - extents->x1;
|
||||||
|
rect.x += extents->x1;
|
||||||
|
pixels += extents->x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_renderer_do_read_pixels(gr, compositor->read_format, pixels, stride, &rect);
|
||||||
|
|
||||||
|
if (gr->gl_version >= gr_gl_version(3, 0))
|
||||||
|
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixman_region32_clear(&rb->base.damage);
|
||||||
|
|
||||||
gl_renderer_garbage_collect_programs(gr);
|
gl_renderer_garbage_collect_programs(gr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -222,12 +222,16 @@ struct gl_renderer_interface {
|
||||||
* \param format The renderbuffer pixel format.
|
* \param format The renderbuffer pixel format.
|
||||||
* \param width The renderbuffer width.
|
* \param width The renderbuffer width.
|
||||||
* \param height The renderbuffer height.
|
* \param height The renderbuffer height.
|
||||||
|
* \param pixels Optional buffer to download the pixels to after rendering.
|
||||||
* \return 0 on success, -1 on failure.
|
* \return 0 on success, -1 on failure.
|
||||||
*
|
*
|
||||||
* This function creates an FBO renderbuffer that can be passed to \c
|
* This function creates an FBO renderbuffer that can be passed to \c
|
||||||
* repaint_output.
|
* repaint_output. If pixels is non-NULL, repaint_output will call
|
||||||
|
* glReadPixels to download pixel data into the provided buffer after
|
||||||
|
* repaint.
|
||||||
*/
|
*/
|
||||||
struct weston_renderbuffer *(*create_fbo)(struct weston_output *output,
|
struct weston_renderbuffer *(*create_fbo)(struct weston_output *output,
|
||||||
const struct pixel_format_info *format,
|
const struct pixel_format_info *format,
|
||||||
int width, int height);
|
int width, int height,
|
||||||
|
uint32_t *pixels);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue