libweston/backends: Move damage flush into backends
Currently we flush damage for the "primary plane" every repaint, but this
is folly.
The drm backend may skip rendering entirely if using an all-planes
composition. This could leave the renderer plane in a messy state if a
surface on an overlay plane disappears.
Instead, let the backends flush the primary plane damage when they know
they need to render.
Fixes #864
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
(cherry picked from commit 2abe4efcf7
)
This commit is contained in:
parent
cebcf8ff7c
commit
0126e6f275
|
@ -548,7 +548,7 @@ struct weston_output {
|
||||||
struct weston_log_pacer pixman_overdraw_pacer;
|
struct weston_log_pacer pixman_overdraw_pacer;
|
||||||
|
|
||||||
int (*start_repaint_loop)(struct weston_output *output);
|
int (*start_repaint_loop)(struct weston_output *output);
|
||||||
int (*repaint)(struct weston_output *output, pixman_region32_t *damage);
|
int (*repaint)(struct weston_output *output);
|
||||||
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);
|
||||||
int (*switch_mode)(struct weston_output *output, struct weston_mode *mode);
|
int (*switch_mode)(struct weston_output *output, struct weston_mode *mode);
|
||||||
|
|
|
@ -965,7 +965,7 @@ bool
|
||||||
drm_plane_is_available(struct drm_plane *plane, struct drm_output *output);
|
drm_plane_is_available(struct drm_plane *plane, struct drm_output *output);
|
||||||
|
|
||||||
void
|
void
|
||||||
drm_output_render(struct drm_output_state *state, pixman_region32_t *damage);
|
drm_output_render(struct drm_output_state *state);
|
||||||
|
|
||||||
int
|
int
|
||||||
parse_gbm_format(const char *s, const struct pixel_format_info *default_format,
|
parse_gbm_format(const char *s, const struct pixel_format_info *default_format,
|
||||||
|
|
|
@ -202,8 +202,7 @@ drm_virtual_output_submit_frame(struct drm_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
drm_virtual_output_repaint(struct weston_output *output_base,
|
drm_virtual_output_repaint(struct weston_output *output_base)
|
||||||
pixman_region32_t *damage)
|
|
||||||
{
|
{
|
||||||
struct drm_output_state *state = NULL;
|
struct drm_output_state *state = NULL;
|
||||||
struct drm_output *output = to_drm_output(output_base);
|
struct drm_output *output = to_drm_output(output_base);
|
||||||
|
@ -237,7 +236,7 @@ drm_virtual_output_repaint(struct weston_output *output_base,
|
||||||
pending_state,
|
pending_state,
|
||||||
DRM_OUTPUT_STATE_CLEAR_PLANES);
|
DRM_OUTPUT_STATE_CLEAR_PLANES);
|
||||||
|
|
||||||
drm_output_render(state, damage);
|
drm_output_render(state);
|
||||||
scanout_state = drm_output_state_get_plane(state, scanout_plane);
|
scanout_state = drm_output_state_get_plane(state, scanout_plane);
|
||||||
if (!scanout_state || !scanout_state->fb)
|
if (!scanout_state || !scanout_state->fb)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -355,7 +355,7 @@ drm_output_render_pixman(struct drm_output_state *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
|
drm_output_render(struct drm_output_state *state)
|
||||||
{
|
{
|
||||||
struct drm_output *output = state->output;
|
struct drm_output *output = state->output;
|
||||||
struct drm_device *device = output->device;
|
struct drm_device *device = output->device;
|
||||||
|
@ -365,7 +365,7 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
|
||||||
struct drm_property_info *damage_info =
|
struct drm_property_info *damage_info =
|
||||||
&scanout_plane->props[WDRM_PLANE_FB_DAMAGE_CLIPS];
|
&scanout_plane->props[WDRM_PLANE_FB_DAMAGE_CLIPS];
|
||||||
struct drm_fb *fb;
|
struct drm_fb *fb;
|
||||||
pixman_region32_t scanout_damage;
|
pixman_region32_t damage, scanout_damage;
|
||||||
pixman_box32_t *rects;
|
pixman_box32_t *rects;
|
||||||
int n_rects;
|
int n_rects;
|
||||||
|
|
||||||
|
@ -375,6 +375,10 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
|
||||||
if (scanout_state->fb)
|
if (scanout_state->fb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(&output->base, &damage);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we don't have any damage on the primary plane, and we already
|
* If we don't have any damage on the primary plane, and we already
|
||||||
* have a renderer buffer active, we can reuse it; else we pass
|
* have a renderer buffer active, we can reuse it; else we pass
|
||||||
|
@ -382,7 +386,7 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
|
||||||
* area. But, we still have to call the renderer anyway if any screen
|
* area. But, we still have to call the renderer anyway if any screen
|
||||||
* capture is pending, otherwise the capture will not complete.
|
* capture is pending, otherwise the capture will not complete.
|
||||||
*/
|
*/
|
||||||
if (!pixman_region32_not_empty(damage) &&
|
if (!pixman_region32_not_empty(&damage) &&
|
||||||
wl_list_empty(&output->base.frame_signal.listener_list) &&
|
wl_list_empty(&output->base.frame_signal.listener_list) &&
|
||||||
!weston_output_has_renderer_capture_tasks(&output->base) &&
|
!weston_output_has_renderer_capture_tasks(&output->base) &&
|
||||||
scanout_plane->state_cur->fb &&
|
scanout_plane->state_cur->fb &&
|
||||||
|
@ -390,14 +394,14 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
|
||||||
scanout_plane->state_cur->fb->type == BUFFER_PIXMAN_DUMB)) {
|
scanout_plane->state_cur->fb->type == BUFFER_PIXMAN_DUMB)) {
|
||||||
fb = drm_fb_ref(scanout_plane->state_cur->fb);
|
fb = drm_fb_ref(scanout_plane->state_cur->fb);
|
||||||
} else if (c->renderer->type == WESTON_RENDERER_PIXMAN) {
|
} else if (c->renderer->type == WESTON_RENDERER_PIXMAN) {
|
||||||
fb = drm_output_render_pixman(state, damage);
|
fb = drm_output_render_pixman(state, &damage);
|
||||||
} else {
|
} else {
|
||||||
fb = drm_output_render_gl(state, damage);
|
fb = drm_output_render_gl(state, &damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
drm_plane_state_put_back(scanout_state);
|
drm_plane_state_put_back(scanout_state);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
scanout_state->fb = fb;
|
scanout_state->fb = fb;
|
||||||
|
@ -417,13 +421,13 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
|
||||||
|
|
||||||
/* Don't bother calculating plane damage if the plane doesn't support it */
|
/* Don't bother calculating plane damage if the plane doesn't support it */
|
||||||
if (damage_info->prop_id == 0)
|
if (damage_info->prop_id == 0)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
pixman_region32_init(&scanout_damage);
|
pixman_region32_init(&scanout_damage);
|
||||||
|
|
||||||
weston_region_global_to_output(&scanout_damage,
|
weston_region_global_to_output(&scanout_damage,
|
||||||
&output->base,
|
&output->base,
|
||||||
damage);
|
&damage);
|
||||||
|
|
||||||
assert(scanout_state->damage_blob_id == 0);
|
assert(scanout_state->damage_blob_id == 0);
|
||||||
|
|
||||||
|
@ -440,6 +444,8 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
|
||||||
&scanout_state->damage_blob_id);
|
&scanout_state->damage_blob_id);
|
||||||
|
|
||||||
pixman_region32_fini(&scanout_damage);
|
pixman_region32_fini(&scanout_damage);
|
||||||
|
out:
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
|
@ -651,7 +657,7 @@ cursor_bo_update(struct drm_output *output, struct weston_view *ev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
drm_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
|
drm_output_repaint(struct weston_output *output_base)
|
||||||
{
|
{
|
||||||
struct drm_output *output = to_drm_output(output_base);
|
struct drm_output *output = to_drm_output(output_base);
|
||||||
struct drm_output_state *state = NULL;
|
struct drm_output_state *state = NULL;
|
||||||
|
@ -718,7 +724,7 @@ drm_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
|
||||||
if (device->atomic_modeset)
|
if (device->atomic_modeset)
|
||||||
drm_output_pick_writeback_capture_task(output);
|
drm_output_pick_writeback_capture_task(output);
|
||||||
|
|
||||||
drm_output_render(state, damage);
|
drm_output_render(state);
|
||||||
scanout_state = drm_output_state_get_plane(state,
|
scanout_state = drm_output_state_get_plane(state,
|
||||||
output->scanout_plane);
|
output->scanout_plane);
|
||||||
if (!scanout_state || !scanout_state->fb)
|
if (!scanout_state || !scanout_state->fb)
|
||||||
|
|
|
@ -152,11 +152,11 @@ headless_output_update_gl_border(struct headless_output *output)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
headless_output_repaint(struct weston_output *output_base,
|
headless_output_repaint(struct weston_output *output_base)
|
||||||
pixman_region32_t *damage)
|
|
||||||
{
|
{
|
||||||
struct headless_output *output = to_headless_output(output_base);
|
struct headless_output *output = to_headless_output(output_base);
|
||||||
struct weston_compositor *ec;
|
struct weston_compositor *ec;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
|
@ -164,9 +164,15 @@ headless_output_repaint(struct weston_output *output_base,
|
||||||
|
|
||||||
headless_output_update_gl_border(output);
|
headless_output_update_gl_border(output);
|
||||||
|
|
||||||
ec->renderer->repaint_output(&output->base, damage,
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(output_base, &damage);
|
||||||
|
|
||||||
|
ec->renderer->repaint_output(&output->base, &damage,
|
||||||
output->renderbuffer);
|
output->renderbuffer);
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
wl_event_source_timer_update(output->finish_frame_timer, 16);
|
wl_event_source_timer_update(output->finish_frame_timer, 16);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -725,19 +725,24 @@ pipewire_submit_buffer(struct pipewire_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pipewire_output_repaint(struct weston_output *base, pixman_region32_t *damage)
|
pipewire_output_repaint(struct weston_output *base)
|
||||||
{
|
{
|
||||||
struct pipewire_output *output = to_pipewire_output(base);
|
struct pipewire_output *output = to_pipewire_output(base);
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
struct pw_buffer *buffer;
|
struct pw_buffer *buffer;
|
||||||
struct pipewire_frame_data *frame_data;
|
struct pipewire_frame_data *frame_data;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
if (pw_stream_get_state(output->stream, NULL) != PW_STREAM_STATE_STREAMING)
|
if (pw_stream_get_state(output->stream, NULL) != PW_STREAM_STATE_STREAMING)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!pixman_region32_not_empty(damage))
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(base, &damage);
|
||||||
|
|
||||||
|
if (!pixman_region32_not_empty(&damage))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
buffer = pw_stream_dequeue_buffer(output->stream);
|
buffer = pw_stream_dequeue_buffer(output->stream);
|
||||||
|
@ -748,12 +753,14 @@ pipewire_output_repaint(struct weston_output *base, pixman_region32_t *damage)
|
||||||
pipewire_output_debug(output, "dequeued buffer: %p", buffer);
|
pipewire_output_debug(output, "dequeued buffer: %p", buffer);
|
||||||
|
|
||||||
frame_data = buffer->user_data;
|
frame_data = buffer->user_data;
|
||||||
ec->renderer->repaint_output(&output->base, damage, frame_data->renderbuffer);
|
ec->renderer->repaint_output(&output->base, &damage, frame_data->renderbuffer);
|
||||||
|
|
||||||
pipewire_submit_buffer(output, buffer);
|
pipewire_submit_buffer(output, buffer);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
weston_output_arm_frame_timer(base, output->finish_frame_timer);
|
weston_output_arm_frame_timer(base, output->finish_frame_timer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -272,24 +272,29 @@ 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)
|
||||||
{
|
{
|
||||||
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;
|
||||||
struct rdp_backend *b = output->backend;
|
struct rdp_backend *b = output->backend;
|
||||||
struct rdp_peers_item *peer;
|
struct rdp_peers_item *peer;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
ec->renderer->repaint_output(&output->base, damage,
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(output_base, &damage);
|
||||||
|
|
||||||
|
ec->renderer->repaint_output(&output->base, &damage,
|
||||||
output->renderbuffer);
|
output->renderbuffer);
|
||||||
|
|
||||||
if (pixman_region32_not_empty(damage)) {
|
if (pixman_region32_not_empty(&damage)) {
|
||||||
pixman_region32_t transformed_damage;
|
pixman_region32_t transformed_damage;
|
||||||
pixman_region32_init(&transformed_damage);
|
pixman_region32_init(&transformed_damage);
|
||||||
weston_region_global_to_output(&transformed_damage,
|
weston_region_global_to_output(&transformed_damage,
|
||||||
output_base,
|
output_base,
|
||||||
damage);
|
&damage);
|
||||||
wl_list_for_each(peer, &b->peers, link) {
|
wl_list_for_each(peer, &b->peers, link) {
|
||||||
if ((peer->flags & RDP_PEER_ACTIVATED) &&
|
if ((peer->flags & RDP_PEER_ACTIVATED) &&
|
||||||
(peer->flags & RDP_PEER_OUTPUT_ENABLED)) {
|
(peer->flags & RDP_PEER_OUTPUT_ENABLED)) {
|
||||||
|
@ -299,6 +304,8 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
|
||||||
pixman_region32_fini(&transformed_damage);
|
pixman_region32_fini(&transformed_damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
weston_output_arm_frame_timer(output_base, output->finish_frame_timer);
|
weston_output_arm_frame_timer(output_base, output->finish_frame_timer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1004,10 +1004,11 @@ vnc_output_start_repaint_loop(struct weston_output *output)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vnc_output_repaint(struct weston_output *base, pixman_region32_t *damage)
|
vnc_output_repaint(struct weston_output *base)
|
||||||
{
|
{
|
||||||
struct vnc_output *output = to_vnc_output(base);
|
struct vnc_output *output = to_vnc_output(base);
|
||||||
struct vnc_backend *backend = output->backend;
|
struct vnc_backend *backend = output->backend;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
|
@ -1016,10 +1017,16 @@ vnc_output_repaint(struct weston_output *base, pixman_region32_t *damage)
|
||||||
|
|
||||||
vnc_output_update_cursor(output);
|
vnc_output_update_cursor(output);
|
||||||
|
|
||||||
if (pixman_region32_not_empty(damage)) {
|
pixman_region32_init(&damage);
|
||||||
vnc_update_buffer(output->display, damage);
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(base, &damage);
|
||||||
|
|
||||||
|
if (pixman_region32_not_empty(&damage)) {
|
||||||
|
vnc_update_buffer(output->display, &damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure damage of this (or previous) damage is handled
|
* Make sure damage of this (or previous) damage is handled
|
||||||
*
|
*
|
||||||
|
|
|
@ -498,22 +498,28 @@ 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)
|
|
||||||
{
|
{
|
||||||
struct wayland_output *output = to_wayland_output(output_base);
|
struct wayland_output *output = to_wayland_output(output_base);
|
||||||
struct weston_compositor *ec;
|
struct weston_compositor *ec;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
ec = output->base.compositor;
|
ec = output->base.compositor;
|
||||||
|
|
||||||
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(output_base, &damage);
|
||||||
|
|
||||||
output->frame_cb = wl_surface_frame(output->parent.surface);
|
output->frame_cb = wl_surface_frame(output->parent.surface);
|
||||||
wl_callback_add_listener(output->frame_cb, &frame_listener, output);
|
wl_callback_add_listener(output->frame_cb, &frame_listener, output);
|
||||||
|
|
||||||
wayland_output_update_gl_border(output);
|
wayland_output_update_gl_border(output);
|
||||||
|
|
||||||
ec->renderer->repaint_output(&output->base, damage, NULL);
|
ec->renderer->repaint_output(&output->base, &damage, NULL);
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -604,17 +610,21 @@ 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)
|
|
||||||
{
|
{
|
||||||
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;
|
||||||
struct wayland_shm_buffer *sb;
|
struct wayland_shm_buffer *sb;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
b = output->backend;
|
b = output->backend;
|
||||||
|
|
||||||
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(output_base, &damage);
|
||||||
|
|
||||||
if (output->frame) {
|
if (output->frame) {
|
||||||
if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
|
if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
|
||||||
wl_list_for_each(sb, &output->shm.buffers, link)
|
wl_list_for_each(sb, &output->shm.buffers, link)
|
||||||
|
@ -624,10 +634,12 @@ wayland_output_repaint_pixman(struct weston_output *output_base,
|
||||||
sb = wayland_output_get_shm_buffer(output);
|
sb = wayland_output_get_shm_buffer(output);
|
||||||
|
|
||||||
wayland_output_update_shm_border(sb);
|
wayland_output_update_shm_border(sb);
|
||||||
b->compositor->renderer->repaint_output(output_base, damage,
|
b->compositor->renderer->repaint_output(output_base, &damage,
|
||||||
sb->renderbuffer);
|
sb->renderbuffer);
|
||||||
|
|
||||||
wayland_shm_buffer_attach(sb, damage);
|
wayland_shm_buffer_attach(sb, &damage);
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
output->frame_cb = wl_surface_frame(output->parent.surface);
|
output->frame_cb = wl_surface_frame(output->parent.surface);
|
||||||
wl_callback_add_listener(output->frame_cb, &frame_listener, output);
|
wl_callback_add_listener(output->frame_cb, &frame_listener, output);
|
||||||
|
|
|
@ -429,17 +429,23 @@ 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)
|
|
||||||
{
|
{
|
||||||
struct x11_output *output = to_x11_output(output_base);
|
struct x11_output *output = to_x11_output(output_base);
|
||||||
struct weston_compositor *ec;
|
struct weston_compositor *ec;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
ec = output->base.compositor;
|
ec = output->base.compositor;
|
||||||
|
|
||||||
ec->renderer->repaint_output(output_base, damage, NULL);
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(output_base, &damage);
|
||||||
|
|
||||||
|
ec->renderer->repaint_output(output_base, &damage, NULL);
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
weston_output_arm_frame_timer(output_base, output->finish_frame_timer);
|
weston_output_arm_frame_timer(output_base, output->finish_frame_timer);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -498,8 +504,7 @@ 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)
|
|
||||||
{
|
{
|
||||||
struct x11_output *output = to_x11_output(output_base);
|
struct x11_output *output = to_x11_output(output_base);
|
||||||
const struct weston_renderer *renderer;
|
const struct weston_renderer *renderer;
|
||||||
|
@ -508,6 +513,7 @@ x11_output_repaint_shm(struct weston_output *output_base,
|
||||||
struct x11_backend *b;
|
struct x11_backend *b;
|
||||||
xcb_void_cookie_t cookie;
|
xcb_void_cookie_t cookie;
|
||||||
xcb_generic_error_t *err;
|
xcb_generic_error_t *err;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
|
@ -517,9 +523,16 @@ x11_output_repaint_shm(struct weston_output *output_base,
|
||||||
|
|
||||||
image = renderer->pixman->renderbuffer_get_image(output->renderbuffer);
|
image = renderer->pixman->renderbuffer_get_image(output->renderbuffer);
|
||||||
|
|
||||||
ec->renderer->repaint_output(output_base, damage, output->renderbuffer);
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
weston_output_flush_damage_for_primary_plane(output_base, &damage);
|
||||||
|
|
||||||
|
ec->renderer->repaint_output(output_base, &damage, output->renderbuffer);
|
||||||
|
|
||||||
|
set_clip_for_output(output_base, &damage);
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
set_clip_for_output(output_base, damage);
|
|
||||||
cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc,
|
cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc,
|
||||||
pixman_image_get_width(image),
|
pixman_image_get_width(image),
|
||||||
pixman_image_get_height(image),
|
pixman_image_get_height(image),
|
||||||
|
|
|
@ -327,4 +327,8 @@ weston_output_flush_damage_for_plane(struct weston_output *output,
|
||||||
struct weston_plane *plane,
|
struct weston_plane *plane,
|
||||||
pixman_region32_t *damage);
|
pixman_region32_t *damage);
|
||||||
|
|
||||||
|
void
|
||||||
|
weston_output_flush_damage_for_primary_plane(struct weston_output *output,
|
||||||
|
pixman_region32_t *damage);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3391,6 +3391,20 @@ weston_output_flush_damage_for_plane(struct weston_output *output,
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
weston_output_flush_damage_for_primary_plane(struct weston_output *output,
|
||||||
|
pixman_region32_t *damage)
|
||||||
|
{
|
||||||
|
weston_output_flush_damage_for_plane(output,
|
||||||
|
&output->primary_plane,
|
||||||
|
damage);
|
||||||
|
|
||||||
|
if (output->full_repaint_needed) {
|
||||||
|
pixman_region32_copy(damage, &output->region);
|
||||||
|
output->full_repaint_needed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
weston_output_repaint(struct weston_output *output)
|
weston_output_repaint(struct weston_output *output)
|
||||||
{
|
{
|
||||||
|
@ -3399,7 +3413,6 @@ weston_output_repaint(struct weston_output *output)
|
||||||
struct weston_animation *animation, *next;
|
struct weston_animation *animation, *next;
|
||||||
struct wl_resource *cb, *cnext;
|
struct wl_resource *cb, *cnext;
|
||||||
struct wl_list frame_callback_list;
|
struct wl_list frame_callback_list;
|
||||||
pixman_region32_t output_damage;
|
|
||||||
int r;
|
int r;
|
||||||
uint32_t frame_time_msec;
|
uint32_t frame_time_msec;
|
||||||
enum weston_hdcp_protection highest_requested = WESTON_HDCP_DISABLE;
|
enum weston_hdcp_protection highest_requested = WESTON_HDCP_DISABLE;
|
||||||
|
@ -3471,19 +3484,7 @@ weston_output_repaint(struct weston_output *output)
|
||||||
|
|
||||||
output_accumulate_damage(output);
|
output_accumulate_damage(output);
|
||||||
|
|
||||||
pixman_region32_init(&output_damage);
|
r = output->repaint(output);
|
||||||
|
|
||||||
weston_output_flush_damage_for_plane(output, &output->primary_plane,
|
|
||||||
&output_damage);
|
|
||||||
|
|
||||||
if (output->full_repaint_needed) {
|
|
||||||
pixman_region32_copy(&output_damage, &output->region);
|
|
||||||
output->full_repaint_needed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = output->repaint(output, &output_damage);
|
|
||||||
|
|
||||||
pixman_region32_fini(&output_damage);
|
|
||||||
|
|
||||||
output->repaint_needed = false;
|
output->repaint_needed = false;
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
|
|
Loading…
Reference in New Issue