Allow backends to group repaint flushes
Implement new repaint_begin and repaint_flush hooks inside weston_backend, allowing backends to gang together repaints which trigger at the same time. Signed-off-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
committed by
Pekka Paalanen
parent
6847b858a3
commit
b1f166d71e
@@ -760,7 +760,8 @@ drm_waitvblank_pipe(struct drm_output *output)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
drm_output_repaint(struct weston_output *output_base,
|
drm_output_repaint(struct weston_output *output_base,
|
||||||
pixman_region32_t *damage)
|
pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct drm_output *output = to_drm_output(output_base);
|
struct drm_output *output = to_drm_output(output_base);
|
||||||
struct drm_backend *backend =
|
struct drm_backend *backend =
|
||||||
@@ -1375,7 +1376,7 @@ drm_output_set_cursor(struct drm_output *output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drm_assign_planes(struct weston_output *output_base)
|
drm_assign_planes(struct weston_output *output_base, void *repaint_data)
|
||||||
{
|
{
|
||||||
struct drm_backend *b = to_drm_backend(output_base->compositor);
|
struct drm_backend *b = to_drm_backend(output_base->compositor);
|
||||||
struct drm_output *output = to_drm_output(output_base);
|
struct drm_output *output = to_drm_output(output_base);
|
||||||
|
|||||||
@@ -118,7 +118,8 @@ fbdev_output_start_repaint_loop(struct weston_output *output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fbdev_output_repaint(struct weston_output *base, pixman_region32_t *damage)
|
fbdev_output_repaint(struct weston_output *base, pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct fbdev_output *output = to_fbdev_output(base);
|
struct fbdev_output *output = to_fbdev_output(base);
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ finish_frame_handler(void *data)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
headless_output_repaint(struct weston_output *output_base,
|
headless_output_repaint(struct weston_output *output_base,
|
||||||
pixman_region32_t *damage)
|
pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct headless_output *output = to_headless_output(output_base);
|
struct headless_output *output = to_headless_output(output_base);
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
|
|||||||
@@ -355,7 +355,8 @@ rdp_output_start_repaint_loop(struct weston_output *output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
|
rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct rdp_output *output = container_of(output_base, struct rdp_output, base);
|
struct rdp_output *output = container_of(output_base, struct rdp_output, base);
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
|
|||||||
@@ -488,7 +488,8 @@ wayland_output_start_repaint_loop(struct weston_output *output_base)
|
|||||||
#ifdef ENABLE_EGL
|
#ifdef ENABLE_EGL
|
||||||
static int
|
static int
|
||||||
wayland_output_repaint_gl(struct weston_output *output_base,
|
wayland_output_repaint_gl(struct weston_output *output_base,
|
||||||
pixman_region32_t *damage)
|
pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct wayland_output *output = to_wayland_output(output_base);
|
struct wayland_output *output = to_wayland_output(output_base);
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
@@ -595,7 +596,8 @@ wayland_shm_buffer_attach(struct wayland_shm_buffer *sb)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
wayland_output_repaint_pixman(struct weston_output *output_base,
|
wayland_output_repaint_pixman(struct weston_output *output_base,
|
||||||
pixman_region32_t *damage)
|
pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct wayland_output *output = to_wayland_output(output_base);
|
struct wayland_output *output = to_wayland_output(output_base);
|
||||||
struct wayland_backend *b =
|
struct wayland_backend *b =
|
||||||
|
|||||||
@@ -389,7 +389,8 @@ x11_output_start_repaint_loop(struct weston_output *output)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
x11_output_repaint_gl(struct weston_output *output_base,
|
x11_output_repaint_gl(struct weston_output *output_base,
|
||||||
pixman_region32_t *damage)
|
pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct x11_output *output = to_x11_output(output_base);
|
struct x11_output *output = to_x11_output(output_base);
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
@@ -457,7 +458,8 @@ set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
x11_output_repaint_shm(struct weston_output *output_base,
|
x11_output_repaint_shm(struct weston_output *output_base,
|
||||||
pixman_region32_t *damage)
|
pixman_region32_t *damage,
|
||||||
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct x11_output *output = to_x11_output(output_base);
|
struct x11_output *output = to_x11_output(output_base);
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
|
|||||||
+33
-13
@@ -2254,7 +2254,7 @@ weston_output_take_feedback_list(struct weston_output *output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
weston_output_repaint(struct weston_output *output)
|
weston_output_repaint(struct weston_output *output, void *repaint_data)
|
||||||
{
|
{
|
||||||
struct weston_compositor *ec = output->compositor;
|
struct weston_compositor *ec = output->compositor;
|
||||||
struct weston_view *ev;
|
struct weston_view *ev;
|
||||||
@@ -2273,7 +2273,7 @@ weston_output_repaint(struct weston_output *output)
|
|||||||
weston_compositor_build_view_list(ec);
|
weston_compositor_build_view_list(ec);
|
||||||
|
|
||||||
if (output->assign_planes && !output->disable_planes) {
|
if (output->assign_planes && !output->disable_planes) {
|
||||||
output->assign_planes(output);
|
output->assign_planes(output, repaint_data);
|
||||||
} else {
|
} else {
|
||||||
wl_list_for_each(ev, &ec->view_list, link) {
|
wl_list_for_each(ev, &ec->view_list, link) {
|
||||||
weston_view_move_to_plane(ev, &ec->primary_plane);
|
weston_view_move_to_plane(ev, &ec->primary_plane);
|
||||||
@@ -2306,7 +2306,7 @@ weston_output_repaint(struct weston_output *output)
|
|||||||
if (output->dirty)
|
if (output->dirty)
|
||||||
weston_output_update_matrix(output);
|
weston_output_update_matrix(output);
|
||||||
|
|
||||||
r = output->repaint(output, &output_damage);
|
r = output->repaint(output, &output_damage, repaint_data);
|
||||||
|
|
||||||
pixman_region32_fini(&output_damage);
|
pixman_region32_fini(&output_damage);
|
||||||
|
|
||||||
@@ -2338,21 +2338,21 @@ weston_output_schedule_repaint_reset(struct weston_output *output)
|
|||||||
TL_POINT("core_repaint_exit_loop", TLP_OUTPUT(output), TLP_END);
|
TL_POINT("core_repaint_exit_loop", TLP_OUTPUT(output), TLP_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
weston_output_maybe_repaint(struct weston_output *output,
|
weston_output_maybe_repaint(struct weston_output *output, struct timespec *now,
|
||||||
struct timespec *now)
|
void *repaint_data)
|
||||||
{
|
{
|
||||||
struct weston_compositor *compositor = output->compositor;
|
struct weston_compositor *compositor = output->compositor;
|
||||||
int ret;
|
int ret = 0;
|
||||||
int64_t msec_to_repaint;
|
int64_t msec_to_repaint;
|
||||||
|
|
||||||
/* We're not ready yet; come back to make a decision later. */
|
/* We're not ready yet; come back to make a decision later. */
|
||||||
if (output->repaint_status != REPAINT_SCHEDULED)
|
if (output->repaint_status != REPAINT_SCHEDULED)
|
||||||
return;
|
return ret;
|
||||||
|
|
||||||
msec_to_repaint = timespec_sub_to_msec(&output->next_repaint, now);
|
msec_to_repaint = timespec_sub_to_msec(&output->next_repaint, now);
|
||||||
if (msec_to_repaint > 1)
|
if (msec_to_repaint > 1)
|
||||||
return;
|
return ret;
|
||||||
|
|
||||||
/* If we're sleeping, drop the repaint machinery entirely; we will
|
/* If we're sleeping, drop the repaint machinery entirely; we will
|
||||||
* explicitly repaint all outputs when we come back. */
|
* explicitly repaint all outputs when we come back. */
|
||||||
@@ -2370,15 +2370,16 @@ weston_output_maybe_repaint(struct weston_output *output,
|
|||||||
* something schedules a successful repaint later. As repainting may
|
* something schedules a successful repaint later. As repainting may
|
||||||
* take some time, re-read our clock as a courtesy to the next
|
* take some time, re-read our clock as a courtesy to the next
|
||||||
* output. */
|
* output. */
|
||||||
ret = weston_output_repaint(output);
|
ret = weston_output_repaint(output, repaint_data);
|
||||||
weston_compositor_read_presentation_clock(compositor, now);
|
weston_compositor_read_presentation_clock(compositor, now);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
return;
|
return ret;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
weston_output_schedule_repaint_reset(output);
|
weston_output_schedule_repaint_reset(output);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2426,10 +2427,29 @@ output_repaint_timer_handler(void *data)
|
|||||||
struct weston_compositor *compositor = data;
|
struct weston_compositor *compositor = data;
|
||||||
struct weston_output *output;
|
struct weston_output *output;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
|
void *repaint_data = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
weston_compositor_read_presentation_clock(compositor, &now);
|
weston_compositor_read_presentation_clock(compositor, &now);
|
||||||
wl_list_for_each(output, &compositor->output_list, link)
|
|
||||||
weston_output_maybe_repaint(output, &now);
|
if (compositor->backend->repaint_begin)
|
||||||
|
repaint_data = compositor->backend->repaint_begin(compositor);
|
||||||
|
|
||||||
|
wl_list_for_each(output, &compositor->output_list, link) {
|
||||||
|
ret = weston_output_maybe_repaint(output, &now, repaint_data);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
if (compositor->backend->repaint_flush)
|
||||||
|
compositor->backend->repaint_flush(compositor,
|
||||||
|
repaint_data);
|
||||||
|
} else {
|
||||||
|
if (compositor->backend->repaint_cancel)
|
||||||
|
compositor->backend->repaint_cancel(compositor,
|
||||||
|
repaint_data);
|
||||||
|
}
|
||||||
|
|
||||||
output_repaint_timer_arm(compositor);
|
output_repaint_timer_arm(compositor);
|
||||||
|
|
||||||
|
|||||||
+36
-2
@@ -212,9 +212,10 @@ struct weston_output {
|
|||||||
|
|
||||||
void (*start_repaint_loop)(struct weston_output *output);
|
void (*start_repaint_loop)(struct weston_output *output);
|
||||||
int (*repaint)(struct weston_output *output,
|
int (*repaint)(struct weston_output *output,
|
||||||
pixman_region32_t *damage);
|
pixman_region32_t *damage,
|
||||||
|
void *repaint_data);
|
||||||
void (*destroy)(struct weston_output *output);
|
void (*destroy)(struct weston_output *output);
|
||||||
void (*assign_planes)(struct weston_output *output);
|
void (*assign_planes)(struct weston_output *output, void *repaint_data);
|
||||||
int (*switch_mode)(struct weston_output *output, struct weston_mode *mode);
|
int (*switch_mode)(struct weston_output *output, struct weston_mode *mode);
|
||||||
|
|
||||||
/* backlight values are on 0-255 range, where higher is brighter */
|
/* backlight values are on 0-255 range, where higher is brighter */
|
||||||
@@ -804,6 +805,39 @@ struct weston_backend_config {
|
|||||||
struct weston_backend {
|
struct weston_backend {
|
||||||
void (*destroy)(struct weston_compositor *compositor);
|
void (*destroy)(struct weston_compositor *compositor);
|
||||||
void (*restore)(struct weston_compositor *compositor);
|
void (*restore)(struct weston_compositor *compositor);
|
||||||
|
|
||||||
|
/** Begin a repaint sequence
|
||||||
|
*
|
||||||
|
* Provides the backend with explicit markers around repaint
|
||||||
|
* sequences, which may allow the backend to aggregate state
|
||||||
|
* application. This call will be bracketed by the repaint_flush (on
|
||||||
|
* success), or repaint_cancel (when any output in the grouping fails
|
||||||
|
* repaint).
|
||||||
|
*
|
||||||
|
* Returns an opaque pointer, which the backend may use as private
|
||||||
|
* data referring to the repaint cycle.
|
||||||
|
*/
|
||||||
|
void * (*repaint_begin)(struct weston_compositor *compositor);
|
||||||
|
|
||||||
|
/** Cancel a repaint sequence
|
||||||
|
*
|
||||||
|
* Cancels a repaint sequence, when an error has occurred during
|
||||||
|
* one output's repaint; see repaint_begin.
|
||||||
|
*
|
||||||
|
* @param repaint_data Data returned by repaint_begin
|
||||||
|
*/
|
||||||
|
void (*repaint_cancel)(struct weston_compositor *compositor,
|
||||||
|
void *repaint_data);
|
||||||
|
|
||||||
|
/** Conclude a repaint sequence
|
||||||
|
*
|
||||||
|
* Called on successful completion of a repaint sequence; see
|
||||||
|
* repaint_begin.
|
||||||
|
*
|
||||||
|
* @param repaint_data Data returned by repaint_begin
|
||||||
|
*/
|
||||||
|
void (*repaint_flush)(struct weston_compositor *compositor,
|
||||||
|
void *repaint_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_desktop_xwayland;
|
struct weston_desktop_xwayland;
|
||||||
|
|||||||
Reference in New Issue
Block a user