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
@ -294,7 +294,7 @@ headless_output_enable_gl(struct headless_output *output)
|
||||
output->renderbuffer =
|
||||
renderer->gl->create_fbo(&output->base, b->formats[0],
|
||||
options.fb_size.width,
|
||||
options.fb_size.height);
|
||||
options.fb_size.height, NULL);
|
||||
if (!output->renderbuffer)
|
||||
goto err_renderbuffer;
|
||||
|
||||
|
@ -94,6 +94,7 @@ struct gl_renderbuffer {
|
||||
/* The fbo value zero represents the default surface framebuffer. */
|
||||
GLuint fbo;
|
||||
GLuint rb;
|
||||
uint32_t *pixels;
|
||||
struct wl_list link;
|
||||
int age;
|
||||
};
|
||||
@ -760,7 +761,7 @@ gl_renderer_create_dummy_renderbuffer(struct weston_output *output)
|
||||
static struct weston_renderbuffer *
|
||||
gl_renderer_create_fbo(struct weston_output *output,
|
||||
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_output_state *go = get_output_state(output);
|
||||
@ -805,6 +806,8 @@ gl_renderer_create_fbo(struct weston_output *output,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renderbuffer->pixels = pixels;
|
||||
|
||||
pixman_region32_init(&renderbuffer->base.damage);
|
||||
/*
|
||||
* One reference is kept on the renderbuffer_list,
|
||||
@ -2028,7 +2031,6 @@ gl_renderer_repaint_output(struct weston_output *output,
|
||||
glFlush();
|
||||
}
|
||||
|
||||
pixman_region32_clear(&rb->base.damage);
|
||||
rb->border_damage = 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -222,12 +222,16 @@ struct gl_renderer_interface {
|
||||
* \param format The renderbuffer pixel format.
|
||||
* \param width The renderbuffer width.
|
||||
* \param height The renderbuffer height.
|
||||
* \param pixels Optional buffer to download the pixels to after rendering.
|
||||
* \return 0 on success, -1 on failure.
|
||||
*
|
||||
* 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,
|
||||
const struct pixel_format_info *format,
|
||||
int width, int height);
|
||||
int width, int height,
|
||||
uint32_t *pixels);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user