compositor: Repaint immediately after pageflip finishes

dev
Kristian Høgsberg 14 years ago
parent 6f5fc69b67
commit ef04414f39
  1. 108
      compositor/compositor.c
  2. 4
      compositor/compositor.h

@ -629,39 +629,6 @@ wlsc_buffer_post_release(struct wl_buffer *buffer)
WL_BUFFER_RELEASE); WL_BUFFER_RELEASE);
} }
WL_EXPORT void
wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
{
struct wlsc_compositor *compositor = output->compositor;
struct wlsc_animation *animation, *next;
wlsc_buffer_post_release(output->scanout_buffer);
output->scanout_buffer = NULL;
output->finished = 1;
wl_event_source_timer_update(compositor->timer_source, 5);
compositor->repaint_on_timeout = 1;
wl_list_for_each_safe(animation, next,
&compositor->animation_list, link)
animation->frame(animation, output, msecs);
}
static void
wlsc_output_finish_redraw(struct wlsc_output *output, int msecs)
{
struct wlsc_compositor *compositor = output->compositor;
struct wlsc_surface *es;
wl_list_for_each(es, &compositor->surface_list, link) {
if (es->output == output) {
wl_display_post_frame(compositor->wl_display,
&es->surface, msecs);
}
}
}
WL_EXPORT void WL_EXPORT void
wlsc_output_damage(struct wlsc_output *output) wlsc_output_damage(struct wlsc_output *output)
{ {
@ -783,8 +750,6 @@ wlsc_output_repaint(struct wlsc_output *output)
wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev, wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
&output->scanout_buffer_destroy_listener.link); &output->scanout_buffer_destroy_listener.link);
wlsc_output_finish_redraw(output,
wlsc_compositor_get_time());
return; return;
} }
} }
@ -823,56 +788,69 @@ wlsc_output_repaint(struct wlsc_output *output)
if (ec->fade.spring.current > 0.001) if (ec->fade.spring.current > 0.001)
fade_output(output, ec->fade.spring.current, &total_damage); fade_output(output, ec->fade.spring.current, &total_damage);
wlsc_output_finish_redraw(output, wlsc_compositor_get_time());
} }
static int static void
repaint(void *data) repaint(void *data, int msecs)
{ {
struct wlsc_compositor *ec = data; struct wlsc_output *output = data;
struct wlsc_output *output; struct wlsc_compositor *compositor = output->compositor;
int repainted_all_outputs = 1; struct wlsc_surface *es;
struct wlsc_animation *animation, *next;
wl_list_for_each(output, &ec->output_list, link) { wlsc_output_repaint(output);
if (!output->repaint_needed) output->repaint_needed = 0;
continue; output->repaint_scheduled = 1;
output->present(output);
if (!output->finished) { /* FIXME: Keep the surfaces in an per-output list. */
repainted_all_outputs = 0; wl_list_for_each(es, &compositor->surface_list, link) {
continue; if (es->output == output) {
wl_display_post_frame(compositor->wl_display,
&es->surface, msecs);
} }
wlsc_output_repaint(output);
output->finished = 0;
output->repaint_needed = 0;
output->present(output);
} }
if (repainted_all_outputs) wl_list_for_each_safe(animation, next,
ec->repaint_on_timeout = 0; &compositor->animation_list, link)
else animation->frame(animation, output, msecs);
wl_event_source_timer_update(ec->timer_source, 1); }
return 1; static void
idle_repaint(void *data)
{
repaint(data, wlsc_compositor_get_time());
}
WL_EXPORT void
wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
{
wlsc_buffer_post_release(output->scanout_buffer);
output->scanout_buffer = NULL;
output->repaint_scheduled = 0;
if (output->repaint_needed)
repaint(output, msecs);
} }
WL_EXPORT void WL_EXPORT void
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor) wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
{ {
struct wlsc_output *output; struct wlsc_output *output;
struct wl_event_loop *loop;
if (compositor->state == WLSC_COMPOSITOR_SLEEPING) if (compositor->state == WLSC_COMPOSITOR_SLEEPING)
return; return;
wl_list_for_each(output, &compositor->output_list, link) loop = wl_display_get_event_loop(compositor->wl_display);
wl_list_for_each(output, &compositor->output_list, link) {
output->repaint_needed = 1; output->repaint_needed = 1;
if (output->repaint_scheduled)
continue;
if (compositor->repaint_on_timeout) wl_event_loop_add_idle(loop, idle_repaint, output);
return; output->repaint_scheduled = 1;
}
wl_event_source_timer_update(compositor->timer_source, 1);
compositor->repaint_on_timeout = 1;
} }
WL_EXPORT void WL_EXPORT void
@ -1727,7 +1705,6 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
background_create(output, option_background); background_create(output, option_background);
output->flags = flags; output->flags = flags;
output->finished = 1;
wlsc_output_move(output, x, y); wlsc_output_move(output, x, y);
output->scanout_buffer_destroy_listener.func = output->scanout_buffer_destroy_listener.func =
@ -1863,7 +1840,6 @@ wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display)
ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec); ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
wl_event_source_timer_update(ec->idle_source, option_idle_time * 1000); wl_event_source_timer_update(ec->idle_source, option_idle_time * 1000);
ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec);
pixman_region32_init(&ec->damage_region); pixman_region32_init(&ec->damage_region);
wlsc_compositor_schedule_repaint(ec); wlsc_compositor_schedule_repaint(ec);

@ -70,7 +70,7 @@ struct wlsc_output {
pixman_region32_t previous_damage_region; pixman_region32_t previous_damage_region;
uint32_t flags; uint32_t flags;
int repaint_needed; int repaint_needed;
int finished; int repaint_scheduled;
char *make, *model; char *make, *model;
uint32_t subpixel; uint32_t subpixel;
@ -190,8 +190,6 @@ struct wlsc_compositor {
uint32_t idle_inhibit; uint32_t idle_inhibit;
/* Repaint state. */ /* Repaint state. */
struct wl_event_source *timer_source;
int repaint_on_timeout;
struct timespec previous_swap; struct timespec previous_swap;
pixman_region32_t damage_region; pixman_region32_t damage_region;
struct wl_array vertices, indices; struct wl_array vertices, indices;

Loading…
Cancel
Save