diff --git a/src/compositor.c b/src/compositor.c index 587fdeda..2ca48b89 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2578,13 +2578,9 @@ WL_EXPORT void weston_output_destroy(struct weston_output *output) { struct weston_compositor *c = output->compositor; - int i; pixman_region32_fini(&output->region); - - for (i = 0; i < 2; i++) - pixman_region32_fini(&output->buffer_damage[i]); - + pixman_region32_fini(&output->previous_damage); output->compositor->output_id_pool &= ~(1 << output->id); 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 weston_output_move(struct weston_output *output, int x, int y) { - int i; - output->x = x; output->y = y; - output->current_buffer = 0; - for (i = 0; i < 2; i++) - pixman_region32_init(&output->buffer_damage[i]); - + pixman_region32_init(&output->previous_damage); pixman_region32_init_rect(&output->region, x, y, output->width, output->height); diff --git a/src/compositor.h b/src/compositor.h index e5c579b4..e770664e 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -160,8 +160,7 @@ struct weston_output { int32_t mm_width, mm_height; struct weston_border border; pixman_region32_t region; - int current_buffer; - pixman_region32_t buffer_damage[2]; + pixman_region32_t previous_damage; int repaint_needed; int repaint_scheduled; struct weston_output_zoom zoom; diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 45b60dde..249efbcb 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -48,6 +48,8 @@ struct gl_shader { struct gl_output_state { EGLSurface egl_surface; + int current_buffer; + pixman_region32_t buffer_damage[2]; }; 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 gl_renderer *gr = get_renderer(ec); struct gl_surface_state *gs = get_surface_state(es); + struct gl_output_state *go = get_output_state(output); /* repaint bounding region in global coordinates: */ pixman_region32_t repaint; /* 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)) 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); 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++) - pixman_region32_union(&output->buffer_damage[i], - &output->buffer_damage[i], + pixman_region32_union(&go->buffer_damage[i], + &go->buffer_damage[i], 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); if (gr->border.texture) draw_border(output); + pixman_region32_copy(&output->previous_damage, output_damage); wl_signal_emit(&output->frame_signal, output); ret = eglSwapBuffers(gr->egl_display, go->egl_surface); @@ -984,7 +988,7 @@ gl_renderer_repaint_output(struct weston_output *output, 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 gl_renderer *gr = get_renderer(ec); struct gl_output_state *go = calloc(1, sizeof *go); + int i; if (!go) return -1; @@ -1573,6 +1578,10 @@ gl_renderer_output_create(struct weston_output *output, return -1; } + go->current_buffer = 0; + for (i = 0; i < 2; i++) + pixman_region32_init(&go->buffer_damage[i]); + output->renderer_state = go; 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_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); diff --git a/src/screenshooter.c b/src/screenshooter.c index 46f65eda..422c2a9a 100644 --- a/src/screenshooter.c +++ b/src/screenshooter.c @@ -310,7 +310,7 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) struct weston_output *output = data; uint32_t msecs = output->frame_time; pixman_box32_t *r; - pixman_region32_t damage, *previous_damage; + pixman_region32_t damage; int i, j, k, n, width, height, run, stride; uint32_t delta, prev, *d, *s, *p, next; struct { @@ -319,18 +319,9 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) } header; 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_intersect(&damage, &output->region, previous_damage); + pixman_region32_intersect(&damage, &output->region, + &output->previous_damage); r = pixman_region32_rectangles(&damage, &n); if (n == 0)