compositor: Repaint immediately after pageflip finishes
This commit is contained in:
+42
-66
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user