compositor: Move buffer damage fields from weston_output to gl-renderer

Move fields current_buffer and buffer_damage out of weston_output into
gl_output_state, since they are actually specific to the renderer.

Also bring back the previous_damage field so that the screenshooter
can get the damage for the previous frame in a renderer independent
way.
dev
Ander Conselvan de Oliveira 12 years ago committed by Kristian Høgsberg
parent aa628d0a7c
commit b8fcca915b
  1. 13
      src/compositor.c
  2. 3
      src/compositor.h
  3. 23
      src/gl-renderer.c
  4. 15
      src/screenshooter.c

@ -2578,13 +2578,9 @@ WL_EXPORT void
weston_output_destroy(struct weston_output *output) weston_output_destroy(struct weston_output *output)
{ {
struct weston_compositor *c = output->compositor; struct weston_compositor *c = output->compositor;
int i;
pixman_region32_fini(&output->region); pixman_region32_fini(&output->region);
pixman_region32_fini(&output->previous_damage);
for (i = 0; i < 2; i++)
pixman_region32_fini(&output->buffer_damage[i]);
output->compositor->output_id_pool &= ~(1 << output->id); output->compositor->output_id_pool &= ~(1 << output->id);
wl_display_remove_global(c->wl_display, output->global); wl_display_remove_global(c->wl_display, output->global);
@ -2708,15 +2704,10 @@ weston_output_transform_init(struct weston_output *output, uint32_t transform)
WL_EXPORT void WL_EXPORT void
weston_output_move(struct weston_output *output, int x, int y) weston_output_move(struct weston_output *output, int x, int y)
{ {
int i;
output->x = x; output->x = x;
output->y = y; output->y = y;
output->current_buffer = 0; pixman_region32_init(&output->previous_damage);
for (i = 0; i < 2; i++)
pixman_region32_init(&output->buffer_damage[i]);
pixman_region32_init_rect(&output->region, x, y, pixman_region32_init_rect(&output->region, x, y,
output->width, output->width,
output->height); output->height);

@ -160,8 +160,7 @@ struct weston_output {
int32_t mm_width, mm_height; int32_t mm_width, mm_height;
struct weston_border border; struct weston_border border;
pixman_region32_t region; pixman_region32_t region;
int current_buffer; pixman_region32_t previous_damage;
pixman_region32_t buffer_damage[2];
int repaint_needed; int repaint_needed;
int repaint_scheduled; int repaint_scheduled;
struct weston_output_zoom zoom; struct weston_output_zoom zoom;

@ -48,6 +48,8 @@ struct gl_shader {
struct gl_output_state { struct gl_output_state {
EGLSurface egl_surface; EGLSurface egl_surface;
int current_buffer;
pixman_region32_t buffer_damage[2];
}; };
struct gl_surface_state { struct gl_surface_state {
@ -723,6 +725,7 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
struct weston_compositor *ec = es->compositor; struct weston_compositor *ec = es->compositor;
struct gl_renderer *gr = get_renderer(ec); struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es); struct gl_surface_state *gs = get_surface_state(es);
struct gl_output_state *go = get_output_state(output);
/* repaint bounding region in global coordinates: */ /* repaint bounding region in global coordinates: */
pixman_region32_t repaint; pixman_region32_t repaint;
/* non-opaque region in surface coordinates: */ /* non-opaque region in surface coordinates: */
@ -739,7 +742,7 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
if (!pixman_region32_not_empty(&repaint)) if (!pixman_region32_not_empty(&repaint))
goto out; goto out;
buffer_damage = &output->buffer_damage[output->current_buffer]; buffer_damage = &go->buffer_damage[go->current_buffer];
pixman_region32_subtract(buffer_damage, buffer_damage, &repaint); pixman_region32_subtract(buffer_damage, buffer_damage, &repaint);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@ -963,18 +966,19 @@ gl_renderer_repaint_output(struct weston_output *output,
} }
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
pixman_region32_union(&output->buffer_damage[i], pixman_region32_union(&go->buffer_damage[i],
&output->buffer_damage[i], &go->buffer_damage[i],
output_damage); output_damage);
pixman_region32_union(output_damage, output_damage, pixman_region32_union(output_damage, output_damage,
&output->buffer_damage[output->current_buffer]); &go->buffer_damage[go->current_buffer]);
repaint_surfaces(output, output_damage); repaint_surfaces(output, output_damage);
if (gr->border.texture) if (gr->border.texture)
draw_border(output); draw_border(output);
pixman_region32_copy(&output->previous_damage, output_damage);
wl_signal_emit(&output->frame_signal, output); wl_signal_emit(&output->frame_signal, output);
ret = eglSwapBuffers(gr->egl_display, go->egl_surface); ret = eglSwapBuffers(gr->egl_display, go->egl_surface);
@ -984,7 +988,7 @@ gl_renderer_repaint_output(struct weston_output *output,
print_egl_error_state(); print_egl_error_state();
} }
output->current_buffer ^= 1; go->current_buffer ^= 1;
} }
@ -1552,6 +1556,7 @@ gl_renderer_output_create(struct weston_output *output,
struct weston_compositor *ec = output->compositor; struct weston_compositor *ec = output->compositor;
struct gl_renderer *gr = get_renderer(ec); struct gl_renderer *gr = get_renderer(ec);
struct gl_output_state *go = calloc(1, sizeof *go); struct gl_output_state *go = calloc(1, sizeof *go);
int i;
if (!go) if (!go)
return -1; return -1;
@ -1573,6 +1578,10 @@ gl_renderer_output_create(struct weston_output *output,
return -1; return -1;
} }
go->current_buffer = 0;
for (i = 0; i < 2; i++)
pixman_region32_init(&go->buffer_damage[i]);
output->renderer_state = go; output->renderer_state = go;
output_apply_border(output, gr); output_apply_border(output, gr);
@ -1585,6 +1594,10 @@ gl_renderer_output_destroy(struct weston_output *output)
{ {
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);
int i;
for (i = 0; i < 2; i++)
pixman_region32_fini(&go->buffer_damage[i]);
eglDestroySurface(gr->egl_display, go->egl_surface); eglDestroySurface(gr->egl_display, go->egl_surface);

@ -310,7 +310,7 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data)
struct weston_output *output = data; struct weston_output *output = data;
uint32_t msecs = output->frame_time; uint32_t msecs = output->frame_time;
pixman_box32_t *r; pixman_box32_t *r;
pixman_region32_t damage, *previous_damage; pixman_region32_t damage;
int i, j, k, n, width, height, run, stride; int i, j, k, n, width, height, run, stride;
uint32_t delta, prev, *d, *s, *p, next; uint32_t delta, prev, *d, *s, *p, next;
struct { struct {
@ -319,18 +319,9 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data)
} header; } header;
struct iovec v[2]; struct iovec v[2];
/* When recording, this will be exactly the region that was repainted
* in this frame. Since overlays are disabled, the whole primary plane
* damage is rendered. For the first frame, the whole output will be
* damaged and that damage will be added to both buffers causing the
* non-current buffer damage to be while output. Rendering will clear
* all the damage in the current buffer so in the next frame (when
* that is non-current) the only damage left will be the one added
* from the primary plane. */
previous_damage = &output->buffer_damage[output->current_buffer ^ 1];
pixman_region32_init(&damage); pixman_region32_init(&damage);
pixman_region32_intersect(&damage, &output->region, previous_damage); pixman_region32_intersect(&damage, &output->region,
&output->previous_damage);
r = pixman_region32_rectangles(&damage, &n); r = pixman_region32_rectangles(&damage, &n);
if (n == 0) if (n == 0)

Loading…
Cancel
Save