compositor: Accumulate damage per plane
When we analyze and accumulate damage prior to repainting, we need to accumulate damage per plane, so that whatever damage a surface contributes is accumulated in the plane that it's assigned to. Before, we would always accumulate damge in the primary plane, which caused repaints in the primary plane whenever a surface in a sprite or framebuffer was damaged. Eliminating this repaint is a big win for cases where we pageflip to a client surface or use a sprite overlay. This also prepares for fixing the missing cursor updates, since we now track damage to the cursor surface in a dedicated sprite plane.
This commit is contained in:
parent
2a1aa4efce
commit
65a11e1039
@ -65,12 +65,6 @@ struct drm_configured_output {
|
|||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
WESTON_PLANE_DRM_CURSOR = 0x100,
|
|
||||||
WESTON_PLANE_DRM_PLANE = 0x101,
|
|
||||||
WESTON_PLANE_DRM_FB = 0x102
|
|
||||||
};
|
|
||||||
|
|
||||||
struct drm_compositor {
|
struct drm_compositor {
|
||||||
struct weston_compositor base;
|
struct weston_compositor base;
|
||||||
|
|
||||||
@ -129,7 +123,9 @@ struct drm_output {
|
|||||||
|
|
||||||
struct gbm_surface *surface;
|
struct gbm_surface *surface;
|
||||||
struct gbm_bo *cursor_bo[2];
|
struct gbm_bo *cursor_bo[2];
|
||||||
int current_cursor, cursor_free, cursor_x, cursor_y;
|
struct weston_plane cursor_plane;
|
||||||
|
struct weston_plane fb_plane;
|
||||||
|
int current_cursor, cursor_free;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
struct drm_fb *current, *next;
|
struct drm_fb *current, *next;
|
||||||
struct backlight *backlight;
|
struct backlight *backlight;
|
||||||
@ -146,6 +142,7 @@ struct drm_sprite {
|
|||||||
uint32_t pending_fb_id;
|
uint32_t pending_fb_id;
|
||||||
struct weston_surface *surface;
|
struct weston_surface *surface;
|
||||||
struct weston_surface *pending_surface;
|
struct weston_surface *pending_surface;
|
||||||
|
struct weston_plane plane;
|
||||||
|
|
||||||
struct drm_output *output;
|
struct drm_output *output;
|
||||||
|
|
||||||
@ -252,7 +249,7 @@ fb_handle_buffer_destroy(struct wl_listener *listener, void *data)
|
|||||||
weston_output_schedule_repaint(&fb->output->base);
|
weston_output_schedule_repaint(&fb->output->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static struct weston_plane *
|
||||||
drm_output_prepare_scanout_surface(struct weston_output *_output,
|
drm_output_prepare_scanout_surface(struct weston_output *_output,
|
||||||
struct weston_surface *es)
|
struct weston_surface *es)
|
||||||
{
|
{
|
||||||
@ -267,7 +264,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output,
|
|||||||
es->geometry.height != output->base.current->height ||
|
es->geometry.height != output->base.current->height ||
|
||||||
es->transform.enabled ||
|
es->transform.enabled ||
|
||||||
es->buffer == NULL)
|
es->buffer == NULL)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||||
es->buffer, GBM_BO_USE_SCANOUT);
|
es->buffer, GBM_BO_USE_SCANOUT);
|
||||||
@ -277,13 +274,13 @@ drm_output_prepare_scanout_surface(struct weston_output *_output,
|
|||||||
* For now, scanout only if format is XRGB8888. */
|
* For now, scanout only if format is XRGB8888. */
|
||||||
if (gbm_bo_get_format(bo) != GBM_FORMAT_XRGB8888) {
|
if (gbm_bo_get_format(bo) != GBM_FORMAT_XRGB8888) {
|
||||||
gbm_bo_destroy(bo);
|
gbm_bo_destroy(bo);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->next = drm_fb_get_from_bo(bo, output);
|
output->next = drm_fb_get_from_bo(bo, output);
|
||||||
if (!output->next) {
|
if (!output->next) {
|
||||||
gbm_bo_destroy(bo);
|
gbm_bo_destroy(bo);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->next->is_client_buffer = 1;
|
output->next->is_client_buffer = 1;
|
||||||
@ -294,9 +291,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output,
|
|||||||
wl_signal_add(&output->next->buffer->resource.destroy_signal,
|
wl_signal_add(&output->next->buffer->resource.destroy_signal,
|
||||||
&output->next->buffer_destroy_listener);
|
&output->next->buffer_destroy_listener);
|
||||||
|
|
||||||
es->plane = WESTON_PLANE_DRM_FB;
|
return &output->fb_plane;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -315,7 +310,7 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
|
wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
|
||||||
if (surface->plane == WESTON_PLANE_PRIMARY)
|
if (surface->plane == &compositor->base.primary_plane)
|
||||||
weston_surface_draw(surface, &output->base, damage);
|
weston_surface_draw(surface, &output->base, damage);
|
||||||
|
|
||||||
wl_signal_emit(&output->base.frame_signal, output);
|
wl_signal_emit(&output->base.frame_signal, output);
|
||||||
@ -554,7 +549,7 @@ drm_disable_unused_sprites(struct weston_output *output_base)
|
|||||||
* if the sprite ends up binding to a different surface than in the
|
* if the sprite ends up binding to a different surface than in the
|
||||||
* previous frame.
|
* previous frame.
|
||||||
*/
|
*/
|
||||||
static int
|
static struct weston_plane *
|
||||||
drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
||||||
struct weston_surface *es)
|
struct weston_surface *es)
|
||||||
{
|
{
|
||||||
@ -573,16 +568,16 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
|||||||
wl_fixed_t sx1, sy1, sx2, sy2;
|
wl_fixed_t sx1, sy1, sx2, sy2;
|
||||||
|
|
||||||
if (c->sprites_are_broken)
|
if (c->sprites_are_broken)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
if (es->output_mask != (1u << output_base->id))
|
if (es->output_mask != (1u << output_base->id))
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
if (es->buffer == NULL)
|
if (es->buffer == NULL)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
if (!drm_surface_transform_supported(es))
|
if (!drm_surface_transform_supported(es))
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
wl_list_for_each(s, &c->sprite_list, link) {
|
wl_list_for_each(s, &c->sprite_list, link) {
|
||||||
if (!drm_sprite_crtc_supported(output_base, s->possible_crtcs))
|
if (!drm_sprite_crtc_supported(output_base, s->possible_crtcs))
|
||||||
@ -596,12 +591,12 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
|||||||
|
|
||||||
/* No sprites available */
|
/* No sprites available */
|
||||||
if (!found)
|
if (!found)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||||
es->buffer, GBM_BO_USE_SCANOUT);
|
es->buffer, GBM_BO_USE_SCANOUT);
|
||||||
if (!bo)
|
if (!bo)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
format = gbm_bo_get_format(bo);
|
format = gbm_bo_get_format(bo);
|
||||||
handle = gbm_bo_get_handle(bo).s32;
|
handle = gbm_bo_get_handle(bo).s32;
|
||||||
@ -610,10 +605,10 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
|||||||
gbm_bo_destroy(bo);
|
gbm_bo_destroy(bo);
|
||||||
|
|
||||||
if (!drm_surface_format_supported(s, format))
|
if (!drm_surface_format_supported(s, format))
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
handles[0] = handle;
|
handles[0] = handle;
|
||||||
pitches[0] = stride;
|
pitches[0] = stride;
|
||||||
@ -625,13 +620,17 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
weston_log("addfb2 failed: %d\n", ret);
|
weston_log("addfb2 failed: %d\n", ret);
|
||||||
c->sprites_are_broken = 1;
|
c->sprites_are_broken = 1;
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->pending_fb_id = fb_id;
|
s->pending_fb_id = fb_id;
|
||||||
s->pending_surface = es;
|
s->pending_surface = es;
|
||||||
es->buffer->busy_count++;
|
es->buffer->busy_count++;
|
||||||
|
|
||||||
|
box = pixman_region32_extents(&es->transform.boundingbox);
|
||||||
|
s->plane.x = box->x1;
|
||||||
|
s->plane.y = box->y1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the source & dest rects properly based on actual
|
* Calculate the source & dest rects properly based on actual
|
||||||
* postion (note the caller has called weston_surface_update_transform()
|
* postion (note the caller has called weston_surface_update_transform()
|
||||||
@ -677,15 +676,13 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
|
|||||||
s->src_h = (sy2 - sy1) << 8;
|
s->src_h = (sy2 - sy1) << 8;
|
||||||
pixman_region32_fini(&src_rect);
|
pixman_region32_fini(&src_rect);
|
||||||
|
|
||||||
es->plane = WESTON_PLANE_DRM_PLANE;
|
|
||||||
|
|
||||||
wl_signal_add(&es->buffer->resource.destroy_signal,
|
wl_signal_add(&es->buffer->resource.destroy_signal,
|
||||||
&s->pending_destroy_listener);
|
&s->pending_destroy_listener);
|
||||||
|
|
||||||
return 0;
|
return &s->plane;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static struct weston_plane *
|
||||||
drm_output_set_cursor(struct weston_output *output_base,
|
drm_output_set_cursor(struct weston_output *output_base,
|
||||||
struct weston_surface *es)
|
struct weston_surface *es)
|
||||||
{
|
{
|
||||||
@ -699,13 +696,14 @@ drm_output_set_cursor(struct weston_output *output_base,
|
|||||||
int i, x, y;
|
int i, x, y;
|
||||||
|
|
||||||
if (!output->cursor_free)
|
if (!output->cursor_free)
|
||||||
return;
|
return NULL;
|
||||||
if (es->output_mask != (1u << output_base->id))
|
if (es->output_mask != (1u << output_base->id))
|
||||||
return;
|
return NULL;
|
||||||
if (es->buffer == NULL || !wl_buffer_is_shm(es->buffer) ||
|
if (es->buffer == NULL || !wl_buffer_is_shm(es->buffer) ||
|
||||||
es->geometry.width > 64 || es->geometry.height > 64)
|
es->geometry.width > 64 || es->geometry.height > 64)
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
|
output->cursor_free = 0;
|
||||||
if (es->buffer && pixman_region32_not_empty(&es->damage)) {
|
if (es->buffer && pixman_region32_not_empty(&es->damage)) {
|
||||||
output->current_cursor ^= 1;
|
output->current_cursor ^= 1;
|
||||||
bo = output->cursor_bo[output->current_cursor];
|
bo = output->cursor_bo[output->current_cursor];
|
||||||
@ -717,29 +715,24 @@ drm_output_set_cursor(struct weston_output *output_base,
|
|||||||
es->geometry.width * 4);
|
es->geometry.width * 4);
|
||||||
|
|
||||||
if (gbm_bo_write(bo, buf, sizeof buf) < 0)
|
if (gbm_bo_write(bo, buf, sizeof buf) < 0)
|
||||||
return;
|
weston_log("failed update cursor: %n\n");
|
||||||
|
|
||||||
handle = gbm_bo_get_handle(bo).s32;
|
handle = gbm_bo_get_handle(bo).s32;
|
||||||
if (drmModeSetCursor(c->drm.fd,
|
if (drmModeSetCursor(c->drm.fd,
|
||||||
output->crtc_id, handle, 64, 64)) {
|
output->crtc_id, handle, 64, 64))
|
||||||
weston_log("failed to set cursor: %n\n");
|
weston_log("failed to set cursor: %n\n");
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x = es->geometry.x - output->base.x;
|
x = es->geometry.x - output->base.x;
|
||||||
y = es->geometry.y - output->base.y;
|
y = es->geometry.y - output->base.y;
|
||||||
if (output->cursor_x != x || output->cursor_y != y) {
|
if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
|
||||||
if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
|
if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y))
|
||||||
weston_log("failed to move cursor: %m\n");
|
weston_log("failed to move cursor: %m\n");
|
||||||
return;
|
output->cursor_plane.x = x;
|
||||||
}
|
output->cursor_plane.y = y;
|
||||||
output->cursor_x = x;
|
|
||||||
output->cursor_y = y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
es->plane = WESTON_PLANE_DRM_CURSOR;
|
return &output->cursor_plane;
|
||||||
output->cursor_free = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -750,7 +743,7 @@ drm_assign_planes(struct weston_output *output)
|
|||||||
struct drm_output *drm_output = (struct drm_output *) output;
|
struct drm_output *drm_output = (struct drm_output *) output;
|
||||||
struct weston_surface *es, *next;
|
struct weston_surface *es, *next;
|
||||||
pixman_region32_t overlap, surface_overlap;
|
pixman_region32_t overlap, surface_overlap;
|
||||||
int prev_plane;
|
struct weston_plane *primary, *next_plane;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a surface for each sprite in the output using some heuristics:
|
* Find a surface for each sprite in the output using some heuristics:
|
||||||
@ -767,35 +760,28 @@ drm_assign_planes(struct weston_output *output)
|
|||||||
*/
|
*/
|
||||||
pixman_region32_init(&overlap);
|
pixman_region32_init(&overlap);
|
||||||
drm_output->cursor_free = 1;
|
drm_output->cursor_free = 1;
|
||||||
|
primary = &c->base.primary_plane;
|
||||||
wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
|
wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
|
||||||
pixman_region32_init(&surface_overlap);
|
pixman_region32_init(&surface_overlap);
|
||||||
pixman_region32_intersect(&surface_overlap, &overlap,
|
pixman_region32_intersect(&surface_overlap, &overlap,
|
||||||
&es->transform.boundingbox);
|
&es->transform.boundingbox);
|
||||||
|
|
||||||
prev_plane = es->plane;
|
next_plane = NULL;
|
||||||
es->plane = WESTON_PLANE_PRIMARY;
|
|
||||||
if (pixman_region32_not_empty(&surface_overlap))
|
if (pixman_region32_not_empty(&surface_overlap))
|
||||||
goto bail;
|
next_plane = primary;
|
||||||
|
if (next_plane == NULL)
|
||||||
if (es->plane == WESTON_PLANE_PRIMARY)
|
next_plane = drm_output_set_cursor(output, es);
|
||||||
drm_output_set_cursor(output, es);
|
if (next_plane == NULL)
|
||||||
if (es->plane == WESTON_PLANE_PRIMARY)
|
next_plane = drm_output_prepare_scanout_surface(output, es);
|
||||||
drm_output_prepare_scanout_surface(output, es);
|
if (next_plane == NULL)
|
||||||
if (es->plane == WESTON_PLANE_PRIMARY)
|
next_plane = drm_output_prepare_overlay_surface(output, es);
|
||||||
drm_output_prepare_overlay_surface(output, es);
|
if (next_plane == NULL)
|
||||||
|
next_plane = primary;
|
||||||
bail:
|
weston_surface_move_to_plane(es, next_plane);
|
||||||
if (es->plane == WESTON_PLANE_PRIMARY)
|
if (next_plane == primary)
|
||||||
pixman_region32_union(&overlap, &overlap,
|
pixman_region32_union(&overlap, &overlap,
|
||||||
&es->transform.boundingbox);
|
&es->transform.boundingbox);
|
||||||
|
|
||||||
if (prev_plane != WESTON_PLANE_PRIMARY &&
|
|
||||||
es->plane == WESTON_PLANE_PRIMARY)
|
|
||||||
weston_surface_damage(es);
|
|
||||||
else if (prev_plane == WESTON_PLANE_PRIMARY &&
|
|
||||||
es->plane != WESTON_PLANE_PRIMARY)
|
|
||||||
weston_surface_damage_below(es);
|
|
||||||
|
|
||||||
pixman_region32_fini(&surface_overlap);
|
pixman_region32_fini(&surface_overlap);
|
||||||
}
|
}
|
||||||
pixman_region32_fini(&overlap);
|
pixman_region32_fini(&overlap);
|
||||||
@ -832,6 +818,9 @@ drm_output_destroy(struct weston_output *output_base)
|
|||||||
eglDestroySurface(c->base.egl_display, output->egl_surface);
|
eglDestroySurface(c->base.egl_display, output->egl_surface);
|
||||||
gbm_surface_destroy(output->surface);
|
gbm_surface_destroy(output->surface);
|
||||||
|
|
||||||
|
weston_plane_release(&output->fb_plane);
|
||||||
|
weston_plane_release(&output->cursor_plane);
|
||||||
|
|
||||||
weston_output_destroy(&output->base);
|
weston_output_destroy(&output->base);
|
||||||
wl_list_remove(&output->base.link);
|
wl_list_remove(&output->base.link);
|
||||||
|
|
||||||
@ -1491,6 +1480,9 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
output->base.set_dpms = drm_set_dpms;
|
output->base.set_dpms = drm_set_dpms;
|
||||||
output->base.switch_mode = drm_output_switch_mode;
|
output->base.switch_mode = drm_output_switch_mode;
|
||||||
|
|
||||||
|
weston_plane_init(&output->cursor_plane, 0, 0);
|
||||||
|
weston_plane_init(&output->fb_plane, 0, 0);
|
||||||
|
|
||||||
weston_log("Output %s, (connector %d, crtc %d)\n",
|
weston_log("Output %s, (connector %d, crtc %d)\n",
|
||||||
output->name, output->connector_id, output->crtc_id);
|
output->name, output->connector_id, output->crtc_id);
|
||||||
wl_list_for_each(m, &output->base.mode_list, link)
|
wl_list_for_each(m, &output->base.mode_list, link)
|
||||||
@ -1568,6 +1560,7 @@ create_sprites(struct drm_compositor *ec)
|
|||||||
memcpy(sprite->formats, plane->formats,
|
memcpy(sprite->formats, plane->formats,
|
||||||
plane->count_formats * sizeof(plane->formats[0]));
|
plane->count_formats * sizeof(plane->formats[0]));
|
||||||
drmModeFreePlane(plane);
|
drmModeFreePlane(plane);
|
||||||
|
weston_plane_init(&sprite->plane, 0, 0);
|
||||||
|
|
||||||
wl_list_insert(&ec->sprite_list, &sprite->link);
|
wl_list_insert(&ec->sprite_list, &sprite->link);
|
||||||
}
|
}
|
||||||
@ -1591,6 +1584,7 @@ destroy_sprites(struct drm_compositor *compositor)
|
|||||||
output->crtc_id, 0, 0,
|
output->crtc_id, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0);
|
0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
drmModeRmFB(compositor->drm.fd, sprite->fb_id);
|
drmModeRmFB(compositor->drm.fd, sprite->fb_id);
|
||||||
|
weston_plane_release(&sprite->plane);
|
||||||
free(sprite);
|
free(sprite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,6 +250,7 @@ weston_surface_create(struct weston_compositor *compositor)
|
|||||||
|
|
||||||
surface->buffer = NULL;
|
surface->buffer = NULL;
|
||||||
surface->output = NULL;
|
surface->output = NULL;
|
||||||
|
surface->plane = &compositor->primary_plane;
|
||||||
|
|
||||||
pixman_region32_init(&surface->damage);
|
pixman_region32_init(&surface->damage);
|
||||||
pixman_region32_init(&surface->opaque);
|
pixman_region32_init(&surface->opaque);
|
||||||
@ -308,20 +309,28 @@ weston_surface_to_global_float(struct weston_surface *surface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
weston_surface_move_to_plane(struct weston_surface *surface,
|
||||||
|
struct weston_plane *plane)
|
||||||
|
{
|
||||||
|
if (surface->plane == plane)
|
||||||
|
return;
|
||||||
|
|
||||||
|
weston_surface_damage_below(surface);
|
||||||
|
surface->plane = plane;
|
||||||
|
weston_surface_damage(surface);
|
||||||
|
}
|
||||||
|
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
weston_surface_damage_below(struct weston_surface *surface)
|
weston_surface_damage_below(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
struct weston_compositor *compositor = surface->compositor;
|
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
|
|
||||||
if (surface->plane != WESTON_PLANE_PRIMARY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
pixman_region32_subtract(&damage, &surface->transform.boundingbox,
|
pixman_region32_subtract(&damage, &surface->transform.boundingbox,
|
||||||
&surface->clip);
|
&surface->clip);
|
||||||
pixman_region32_union(&compositor->damage,
|
pixman_region32_union(&surface->plane->damage,
|
||||||
&compositor->damage, &damage);
|
&surface->plane->damage, &damage);
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,8 +1004,9 @@ weston_output_damage(struct weston_output *output)
|
|||||||
{
|
{
|
||||||
struct weston_compositor *compositor = output->compositor;
|
struct weston_compositor *compositor = output->compositor;
|
||||||
|
|
||||||
pixman_region32_union(&compositor->damage,
|
pixman_region32_union(&compositor->primary_plane.damage,
|
||||||
&compositor->damage, &output->region);
|
&compositor->primary_plane.damage,
|
||||||
|
&output->region);
|
||||||
weston_output_schedule_repaint(output);
|
weston_output_schedule_repaint(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,7 +1083,6 @@ update_shm_texture(struct weston_surface *surface)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
surface_accumulate_damage(struct weston_surface *surface,
|
surface_accumulate_damage(struct weston_surface *surface,
|
||||||
pixman_region32_t *new_damage,
|
|
||||||
pixman_region32_t *opaque)
|
pixman_region32_t *opaque)
|
||||||
{
|
{
|
||||||
if (surface->buffer && wl_buffer_is_shm(surface->buffer))
|
if (surface->buffer && wl_buffer_is_shm(surface->buffer))
|
||||||
@ -1087,14 +1096,18 @@ surface_accumulate_damage(struct weston_surface *surface,
|
|||||||
extents->x2 - extents->x1,
|
extents->x2 - extents->x1,
|
||||||
extents->y2 - extents->y1,
|
extents->y2 - extents->y1,
|
||||||
&surface->damage);
|
&surface->damage);
|
||||||
|
pixman_region32_translate(&surface->damage,
|
||||||
|
-surface->plane->x,
|
||||||
|
-surface->plane->y);
|
||||||
} else {
|
} else {
|
||||||
pixman_region32_translate(&surface->damage,
|
pixman_region32_translate(&surface->damage,
|
||||||
surface->geometry.x,
|
surface->geometry.x - surface->plane->x,
|
||||||
surface->geometry.y);
|
surface->geometry.y - surface->plane->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_subtract(&surface->damage, &surface->damage, opaque);
|
pixman_region32_subtract(&surface->damage, &surface->damage, opaque);
|
||||||
pixman_region32_union(new_damage, new_damage, &surface->damage);
|
pixman_region32_union(&surface->plane->damage,
|
||||||
|
&surface->plane->damage, &surface->damage);
|
||||||
empty_region(&surface->damage);
|
empty_region(&surface->damage);
|
||||||
pixman_region32_copy(&surface->clip, opaque);
|
pixman_region32_copy(&surface->clip, opaque);
|
||||||
pixman_region32_union(opaque, opaque, &surface->transform.opaque);
|
pixman_region32_union(opaque, opaque, &surface->transform.opaque);
|
||||||
@ -1109,7 +1122,7 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
|
|||||||
struct weston_animation *animation, *next;
|
struct weston_animation *animation, *next;
|
||||||
struct weston_frame_callback *cb, *cnext;
|
struct weston_frame_callback *cb, *cnext;
|
||||||
struct wl_list frame_callback_list;
|
struct wl_list frame_callback_list;
|
||||||
pixman_region32_t opaque, new_damage, output_damage;
|
pixman_region32_t opaque, output_damage;
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
|
|
||||||
weston_compositor_update_drag_surfaces(ec);
|
weston_compositor_update_drag_surfaces(ec);
|
||||||
@ -1144,24 +1157,22 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
|
|||||||
*/
|
*/
|
||||||
output->assign_planes(output);
|
output->assign_planes(output);
|
||||||
|
|
||||||
pixman_region32_init(&new_damage);
|
|
||||||
pixman_region32_init(&opaque);
|
pixman_region32_init(&opaque);
|
||||||
|
|
||||||
wl_list_for_each(es, &ec->surface_list, link)
|
wl_list_for_each(es, &ec->surface_list, link)
|
||||||
surface_accumulate_damage(es, &new_damage, &opaque);
|
surface_accumulate_damage(es, &opaque);
|
||||||
|
|
||||||
pixman_region32_union(&ec->damage, &ec->damage, &new_damage);
|
|
||||||
|
|
||||||
pixman_region32_init(&output_damage);
|
pixman_region32_init(&output_damage);
|
||||||
pixman_region32_union(&output_damage,
|
pixman_region32_union(&output_damage, &ec->primary_plane.damage,
|
||||||
&ec->damage, &output->previous_damage);
|
&output->previous_damage);
|
||||||
pixman_region32_copy(&output->previous_damage, &ec->damage);
|
pixman_region32_copy(&output->previous_damage,
|
||||||
|
&ec->primary_plane.damage);
|
||||||
pixman_region32_intersect(&output_damage,
|
pixman_region32_intersect(&output_damage,
|
||||||
&output_damage, &output->region);
|
&output_damage, &output->region);
|
||||||
pixman_region32_subtract(&ec->damage, &ec->damage, &output->region);
|
pixman_region32_subtract(&ec->primary_plane.damage,
|
||||||
|
&ec->primary_plane.damage, &output->region);
|
||||||
|
|
||||||
pixman_region32_fini(&opaque);
|
pixman_region32_fini(&opaque);
|
||||||
pixman_region32_fini(&new_damage);
|
|
||||||
|
|
||||||
if (output->dirty)
|
if (output->dirty)
|
||||||
weston_output_update_matrix(output);
|
weston_output_update_matrix(output);
|
||||||
@ -1659,6 +1670,20 @@ idle_handler(void *data)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
pixman_region32_init(&plane->damage);
|
||||||
|
plane->x = x;
|
||||||
|
plane->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
weston_plane_release(struct weston_plane *plane)
|
||||||
|
{
|
||||||
|
pixman_region32_fini(&plane->damage);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
weston_seat_update_drag_surface(struct wl_seat *seat, int dx, int dy);
|
weston_seat_update_drag_surface(struct wl_seat *seat, int dx, int dy);
|
||||||
|
|
||||||
@ -3138,6 +3163,8 @@ weston_compositor_init(struct weston_compositor *ec,
|
|||||||
wl_list_init(&ec->axis_binding_list);
|
wl_list_init(&ec->axis_binding_list);
|
||||||
wl_list_init(&ec->fade.animation.link);
|
wl_list_init(&ec->fade.animation.link);
|
||||||
|
|
||||||
|
weston_plane_init(&ec->primary_plane, 0, 0);
|
||||||
|
|
||||||
weston_compositor_xkb_init(ec, &xkb_names);
|
weston_compositor_xkb_init(ec, &xkb_names);
|
||||||
|
|
||||||
ec->ping_handler = NULL;
|
ec->ping_handler = NULL;
|
||||||
@ -3256,12 +3283,12 @@ weston_compositor_shutdown(struct weston_compositor *ec)
|
|||||||
weston_binding_list_destroy_all(&ec->button_binding_list);
|
weston_binding_list_destroy_all(&ec->button_binding_list);
|
||||||
weston_binding_list_destroy_all(&ec->axis_binding_list);
|
weston_binding_list_destroy_all(&ec->axis_binding_list);
|
||||||
|
|
||||||
|
weston_plane_release(&ec->primary_plane);
|
||||||
|
|
||||||
wl_array_release(&ec->vertices);
|
wl_array_release(&ec->vertices);
|
||||||
wl_array_release(&ec->indices);
|
wl_array_release(&ec->indices);
|
||||||
|
|
||||||
wl_event_loop_destroy(ec->input_loop);
|
wl_event_loop_destroy(ec->input_loop);
|
||||||
|
|
||||||
pixman_region32_fini(&ec->damage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_term_signal(int signal_number, void *data)
|
static int on_term_signal(int signal_number, void *data)
|
||||||
|
@ -258,6 +258,11 @@ struct weston_layer {
|
|||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct weston_plane {
|
||||||
|
pixman_region32_t damage;
|
||||||
|
int32_t x, y;
|
||||||
|
};
|
||||||
|
|
||||||
struct weston_compositor {
|
struct weston_compositor {
|
||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
struct wl_signal destroy_signal;
|
struct wl_signal destroy_signal;
|
||||||
@ -312,7 +317,7 @@ struct weston_compositor {
|
|||||||
|
|
||||||
/* Repaint state. */
|
/* Repaint state. */
|
||||||
struct wl_array vertices, indices;
|
struct wl_array vertices, indices;
|
||||||
pixman_region32_t damage;
|
struct weston_plane primary_plane;
|
||||||
|
|
||||||
uint32_t focus;
|
uint32_t focus;
|
||||||
|
|
||||||
@ -379,10 +384,6 @@ struct weston_region {
|
|||||||
* transformation in global coordinates, add it to the tail of the list.
|
* transformation in global coordinates, add it to the tail of the list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum {
|
|
||||||
WESTON_PLANE_PRIMARY
|
|
||||||
};
|
|
||||||
|
|
||||||
struct weston_surface {
|
struct weston_surface {
|
||||||
struct wl_surface surface;
|
struct wl_surface surface;
|
||||||
struct weston_compositor *compositor;
|
struct weston_compositor *compositor;
|
||||||
@ -400,7 +401,7 @@ struct weston_surface {
|
|||||||
GLfloat opaque_rect[4];
|
GLfloat opaque_rect[4];
|
||||||
GLfloat alpha;
|
GLfloat alpha;
|
||||||
int blend;
|
int blend;
|
||||||
int plane;
|
struct weston_plane *plane;
|
||||||
|
|
||||||
/* Surface geometry state, mutable.
|
/* Surface geometry state, mutable.
|
||||||
* If you change anything, set dirty = 1.
|
* If you change anything, set dirty = 1.
|
||||||
@ -535,6 +536,11 @@ notify_touch(struct wl_seat *seat, uint32_t time, int touch_id,
|
|||||||
void
|
void
|
||||||
weston_layer_init(struct weston_layer *layer, struct wl_list *below);
|
weston_layer_init(struct weston_layer *layer, struct wl_list *below);
|
||||||
|
|
||||||
|
void
|
||||||
|
weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y);
|
||||||
|
void
|
||||||
|
weston_plane_release(struct weston_plane *plane);
|
||||||
|
|
||||||
void
|
void
|
||||||
weston_output_finish_frame(struct weston_output *output, uint32_t msecs);
|
weston_output_finish_frame(struct weston_output *output, uint32_t msecs);
|
||||||
void
|
void
|
||||||
@ -640,6 +646,9 @@ weston_surface_damage(struct weston_surface *surface);
|
|||||||
void
|
void
|
||||||
weston_surface_damage_below(struct weston_surface *surface);
|
weston_surface_damage_below(struct weston_surface *surface);
|
||||||
|
|
||||||
|
void
|
||||||
|
weston_surface_move_to_plane(struct weston_surface *surface,
|
||||||
|
struct weston_plane *plane);
|
||||||
void
|
void
|
||||||
weston_surface_unmap(struct weston_surface *surface);
|
weston_surface_unmap(struct weston_surface *surface);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user