compositor: Fix cursor damaging on multi head
authorBenjamin Franzke <benjaminfranzke@googlemail.com>
Tue, 28 Jun 2011 20:56:43 +0000 (22:56 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 1 Jul 2011 19:51:41 +0000 (15:51 -0400)
Removing cursors from the surface list,
for usage as hardware cursor needs lower damaging.

Also damge when re-adding to the surface list.

compositor/compositor-drm.c
compositor/compositor.c

index cb38cd6..bf3dbc6 100644 (file)
@@ -210,10 +210,8 @@ drm_output_set_cursor(struct wlsc_output *output_base,
                                       output->base.current->width,
                                       output->base.current->height);
 
-       if (!pixman_region32_not_empty(&cursor_region)) {
-               ret = 0;
+       if (!pixman_region32_not_empty(&cursor_region))
                goto out;
-       }
 
        if (eid->sprite->image == EGL_NO_IMAGE_KHR)
                goto out;
index 3a8d41e..104da6e 100644 (file)
@@ -771,13 +771,53 @@ fade_output(struct wlsc_output *output,
        glUniform4fv(compositor->solid_shader.color_uniform, 1, color);
        wlsc_surface_draw(&surface, output, region);
 }
+
+static void
+wlsc_output_set_cursor(struct wlsc_output *output,
+                      struct wl_input_device *dev, int force_sw)
+{
+       struct wlsc_compositor *ec = output->compositor;
+       struct wlsc_input_device *device = (struct wlsc_input_device *) dev;
+       pixman_region32_t cursor_region;
+       int use_hardware_cursor = 1, prior_was_hardware;
+
+       pixman_region32_init_rect(&cursor_region,
+                                 device->sprite->x, device->sprite->y,
+                                 device->sprite->width,
+                                 device->sprite->height);
+
+       pixman_region32_intersect(&cursor_region, &cursor_region, &output->region);
+
+       if (!pixman_region32_not_empty(&cursor_region)) {
+               output->set_hardware_cursor(output, NULL);
+               goto out;
+       }
+
+       prior_was_hardware = wl_list_empty(&device->sprite->link);
+       if (force_sw || output->set_hardware_cursor(output, device) < 0) {
+               if (prior_was_hardware)
+                       wlsc_surface_damage(device->sprite);
+               use_hardware_cursor = 0;
+       } else if (!prior_was_hardware) {
+               wlsc_surface_damage_below(device->sprite);
+       }
+
+       /* Remove always to be on top. */
+       wl_list_remove(&device->sprite->link);
+       if (!use_hardware_cursor)
+               wl_list_insert(&ec->surface_list, &device->sprite->link);
+       else
+               wl_list_init(&device->sprite->link);
+
+out:
+       pixman_region32_fini(&cursor_region);
+}
  
 static void
 wlsc_output_repaint(struct wlsc_output *output)
 {
        struct wlsc_compositor *ec = output->compositor;
        struct wlsc_surface *es;
-       struct wlsc_input_device *device;
        pixman_region32_t clip, new_damage, total_damage;
 
        output->prepare_render(output);
@@ -789,6 +829,9 @@ wlsc_output_repaint(struct wlsc_output *output)
                           1, GL_FALSE, output->matrix.d);
        glUniform1i(ec->texture_shader.tex_uniform, 0);
 
+       wlsc_output_set_cursor(output, ec->input_device,
+                              !(ec->focus && ec->fade.spring.current < 0.001));
+
        pixman_region32_init(&new_damage);
        pixman_region32_intersect(&new_damage, &ec->damage, &output->region);
        pixman_region32_init(&clip);
@@ -808,22 +851,6 @@ wlsc_output_repaint(struct wlsc_output *output)
        pixman_region32_fini(&clip);
        pixman_region32_fini(&new_damage);
 
-       device = (struct wlsc_input_device *) ec->input_device;
-       if (ec->focus && ec->fade.spring.current < 0.001) {
-               if (!wl_list_empty(&device->sprite->link)) {
-                       wl_list_remove(&device->sprite->link);
-                       wl_list_init(&device->sprite->link);
-               }
-               if (output->set_hardware_cursor(output, device) < 0)
-                       wl_list_insert(&ec->surface_list,
-                                      &device->sprite->link);
-       } else {
-               output->set_hardware_cursor(output, NULL);
-               if (wl_list_empty(&device->sprite->link))
-                       wl_list_insert(&ec->surface_list,
-                                      &device->sprite->link);
-       }
-
        es = container_of(ec->surface_list.next, struct wlsc_surface, link);
 
        if (es->visual == &ec->compositor.rgb_visual &&