compositor: Compute overlapped early and base hw cursor decision on that

dev
Kristian Høgsberg 13 years ago
parent 9f404b7ac8
commit a82c4860a1
  1. 69
      src/compositor.c
  2. 3
      src/compositor.h
  3. 8
      src/shell.c

@ -595,13 +595,30 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
pixman_region32_fini(&repaint); pixman_region32_fini(&repaint);
} }
WL_EXPORT struct wl_list *
weston_compositor_top(struct weston_compositor *compositor)
{
struct weston_input_device *input_device;
struct wl_list *list;
input_device = (struct weston_input_device *) compositor->input_device;
/* Insert below pointer */
list = &compositor->surface_list;
if (list->next == &input_device->sprite->link)
list = list->next;
return list;
}
static void static void
weston_surface_raise(struct weston_surface *surface) weston_surface_raise(struct weston_surface *surface)
{ {
struct weston_compositor *compositor = surface->compositor; struct weston_compositor *compositor = surface->compositor;
struct wl_list *list = weston_compositor_top(compositor);
wl_list_remove(&surface->link); wl_list_remove(&surface->link);
wl_list_insert(&compositor->surface_list, &surface->link); wl_list_insert(list, &surface->link);
weston_compositor_repick(compositor); weston_compositor_repick(compositor);
weston_surface_damage(surface); weston_surface_damage(surface);
} }
@ -707,13 +724,12 @@ solid_surface_release(struct weston_surface *surface)
static void static void
weston_output_set_cursor(struct weston_output *output, weston_output_set_cursor(struct weston_output *output,
struct wl_input_device *dev, int force_sw) struct wl_input_device *dev)
{ {
struct weston_compositor *ec = output->compositor;
struct weston_input_device *device = struct weston_input_device *device =
(struct weston_input_device *) dev; (struct weston_input_device *) dev;
pixman_region32_t cursor_region; pixman_region32_t cursor_region;
int use_hardware_cursor = 1, prior_was_hardware; int prior_was_hardware;
if (device->sprite == NULL) if (device->sprite == NULL)
return; return;
@ -730,25 +746,20 @@ weston_output_set_cursor(struct weston_output *output,
goto out; goto out;
} }
prior_was_hardware = wl_list_empty(&device->sprite->link); prior_was_hardware = device->hw_cursor;
if (force_sw || output->set_hardware_cursor(output, device) < 0) { if (device->sprite->overlapped ||
output->set_hardware_cursor(output, device) < 0) {
if (prior_was_hardware) { if (prior_was_hardware) {
weston_surface_damage(device->sprite); weston_surface_damage(device->sprite);
output->set_hardware_cursor(output, NULL); output->set_hardware_cursor(output, NULL);
} }
use_hardware_cursor = 0; device->hw_cursor = 0;
} else if (!prior_was_hardware) {
weston_surface_damage_below(device->sprite);
}
/* Remove always to be on top. */
wl_list_remove(&device->sprite->link);
if (!use_hardware_cursor && ec->focus) {
wl_list_insert(&ec->surface_list, &device->sprite->link);
device->sprite->output = output;
} else { } else {
wl_list_init(&device->sprite->link); if (!prior_was_hardware)
device->sprite->output = NULL; weston_surface_damage_below(device->sprite);
pixman_region32_fini(&device->sprite->damage);
pixman_region32_init(&device->sprite->damage);
device->hw_cursor = 1;
} }
out: out:
@ -765,21 +776,14 @@ weston_output_repaint(struct weston_output *output)
glViewport(0, 0, output->current->width, output->current->height); glViewport(0, 0, output->current->width, output->current->height);
weston_output_set_cursor(output, ec->input_device, if (ec->fade.spring.current >= 0.001)
ec->fade.spring.current >= 0.001); solid_surface_init(&solid, output, ec->fade.spring.current);
pixman_region32_init(&new_damage); pixman_region32_init(&new_damage);
pixman_region32_init(&opaque); pixman_region32_init(&opaque);
pixman_region32_init(&overlap); pixman_region32_init(&overlap);
if (ec->fade.spring.current >= 0.001)
solid_surface_init(&solid, output, ec->fade.spring.current);
wl_list_for_each(es, &ec->surface_list, link) { wl_list_for_each(es, &ec->surface_list, link) {
pixman_region32_subtract(&es->damage, &es->damage, &opaque);
pixman_region32_union(&new_damage, &new_damage, &es->damage);
pixman_region32_union(&opaque, &opaque, &es->opaque);
pixman_region32_init(&surface_overlap); pixman_region32_init(&surface_overlap);
pixman_region32_intersect_rect(&surface_overlap, pixman_region32_intersect_rect(&surface_overlap,
&overlap, es->x, es->y, &overlap, es->x, es->y,
@ -790,6 +794,14 @@ weston_output_repaint(struct weston_output *output)
es->width, es->height); es->width, es->height);
} }
weston_output_set_cursor(output, ec->input_device);
wl_list_for_each(es, &ec->surface_list, link) {
pixman_region32_subtract(&es->damage, &es->damage, &opaque);
pixman_region32_union(&new_damage, &new_damage, &es->damage);
pixman_region32_union(&opaque, &opaque, &es->opaque);
}
pixman_region32_init(&total_damage); pixman_region32_init(&total_damage);
pixman_region32_union(&total_damage, &new_damage, pixman_region32_union(&total_damage, &new_damage,
&output->previous_damage); &output->previous_damage);
@ -1517,7 +1529,8 @@ input_device_attach(struct wl_client *client,
weston_surface_create(compositor, weston_surface_create(compositor,
device->input_device.x, device->input_device.x,
device->input_device.y, 32, 32); device->input_device.y, 32, 32);
wl_list_init(&device->sprite->link); wl_list_insert(&compositor->surface_list,
&device->sprite->link);
} }
buffer = buffer_resource->data; buffer = buffer_resource->data;

@ -96,6 +96,7 @@ struct weston_input_device {
int32_t hotspot_x, hotspot_y; int32_t hotspot_x, hotspot_y;
struct wl_list link; struct wl_list link;
uint32_t modifier_state; uint32_t modifier_state;
int hw_cursor;
uint32_t num_tp; uint32_t num_tp;
struct wl_surface *touch_focus; struct wl_surface *touch_focus;
@ -339,6 +340,8 @@ weston_compositor_run_binding(struct weston_compositor *compositor,
struct weston_input_device *device, struct weston_input_device *device,
uint32_t time, uint32_t time,
uint32_t key, uint32_t button, int32_t state); uint32_t key, uint32_t button, int32_t state);
struct wl_list *
weston_compositor_top(struct weston_compositor *compositor);
struct weston_surface * struct weston_surface *
weston_surface_create(struct weston_compositor *compositor, weston_surface_create(struct weston_compositor *compositor,

@ -952,6 +952,7 @@ activate(struct weston_shell *base, struct weston_surface *es,
{ {
struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct wl_shell *shell = container_of(base, struct wl_shell, shell);
struct weston_compositor *compositor = shell->compositor; struct weston_compositor *compositor = shell->compositor;
struct wl_list *list;
weston_surface_activate(es, device, time); weston_surface_activate(es, device, time);
@ -977,12 +978,13 @@ activate(struct weston_shell *base, struct weston_surface *es,
break; break;
default: default:
if (!shell->locked) { if (!shell->locked) {
list = weston_compositor_top(compositor);
/* bring panel back to top */ /* bring panel back to top */
struct shell_surface *panel; struct shell_surface *panel;
wl_list_for_each(panel, &shell->panels, link) { wl_list_for_each(panel, &shell->panels, link) {
wl_list_remove(&panel->surface->link); wl_list_remove(&panel->surface->link);
wl_list_insert(&compositor->surface_list, wl_list_insert(list, &panel->surface->link);
&panel->surface->link);
} }
} }
} }
@ -1119,7 +1121,7 @@ map(struct weston_shell *base,
list = &shell->hidden_surface_list; list = &shell->hidden_surface_list;
do_configure = 0; do_configure = 0;
} else { } else {
list = &compositor->surface_list; list = weston_compositor_top(compositor);
do_configure = 1; do_configure = 1;
} }

Loading…
Cancel
Save