struct weston_animation *animation, *next;
struct weston_frame_callback *cb, *cnext;
struct wl_list frame_callback_list;
- pixman_region32_t opaque, output_damage, new_damage;
+ pixman_region32_t opaque, output_damage;
weston_compositor_update_drag_surfaces(ec);
pixman_region32_fini(&opaque);
pixman_region32_init(&output_damage);
-
- pixman_region32_init(&new_damage);
- pixman_region32_copy(&new_damage, &ec->primary_plane.damage);
-
- pixman_region32_union(&ec->primary_plane.damage,
- &ec->primary_plane.damage,
- &output->previous_damage);
-
- pixman_region32_intersect(&output->previous_damage,
- &new_damage, &output->region);
-
pixman_region32_intersect(&output_damage,
&ec->primary_plane.damage, &output->region);
-
- pixman_region32_fini(&new_damage);
+ pixman_region32_subtract(&ec->primary_plane.damage,
+ &ec->primary_plane.damage, &output->region);
if (output->dirty)
weston_output_update_matrix(output);
weston_output_destroy(struct weston_output *output)
{
struct weston_compositor *c = output->compositor;
+ int i;
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);
wl_display_remove_global(c->wl_display, output->global);
WL_EXPORT void
weston_output_move(struct weston_output *output, int x, int y)
{
+ int i;
+
output->x = x;
output->y = y;
- pixman_region32_init(&output->previous_damage);
+ output->current_buffer = 0;
+ for (i = 0; i < 2; i++)
+ pixman_region32_init(&output->buffer_damage[i]);
+
pixman_region32_init_rect(&output->region, x, y,
output->width,
output->height);
int32_t mm_width, mm_height;
struct weston_border border;
pixman_region32_t region;
- pixman_region32_t previous_damage;
+ int current_buffer;
+ pixman_region32_t buffer_damage[2];
int repaint_needed;
int repaint_scheduled;
struct weston_output_zoom zoom;
pixman_region32_t repaint;
/* non-opaque region in surface coordinates: */
pixman_region32_t surface_blend;
+ pixman_region32_t *buffer_damage;
GLint filter;
int i;
if (!pixman_region32_not_empty(&repaint))
goto out;
- pixman_region32_subtract(&ec->primary_plane.damage,
- &ec->primary_plane.damage, &repaint);
+ buffer_damage = &output->buffer_damage[output->current_buffer];
+ pixman_region32_subtract(buffer_damage, buffer_damage, &repaint);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
struct weston_compositor *compositor = output->compositor;
EGLBoolean ret;
static int errored;
- int32_t width, height;
+ int32_t width, height, i;
width = output->current->width +
output->border.left + output->border.right;
pixman_region32_fini(&undamaged);
}
+ for (i = 0; i < 2; i++)
+ pixman_region32_union(&output->buffer_damage[i],
+ &output->buffer_damage[i],
+ output_damage);
+
+ pixman_region32_union(output_damage, output_damage,
+ &output->buffer_damage[output->current_buffer]);
+
repaint_surfaces(output, output_damage);
wl_signal_emit(&output->frame_signal, output);
print_egl_error_state();
}
+ output->current_buffer ^= 1;
+
}
static void
struct weston_output *output = data;
uint32_t msecs = output->frame_time;
pixman_box32_t *r;
- pixman_region32_t damage;
+ pixman_region32_t damage, *previous_damage;
int i, j, k, n, width, height, run, stride;
uint32_t delta, prev, *d, *s, *p, next;
struct {
} 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,
- &output->previous_damage);
+ pixman_region32_intersect(&damage, &output->region, previous_damage);
r = pixman_region32_rectangles(&damage, &n);
if (n == 0)