return surface;
}
+void
+wlsc_surface_damage_rectangle(struct wlsc_surface *surface,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ struct wlsc_compositor *compositor = surface->compositor;
+
+ pixman_region32_union_rect(&compositor->damage_region,
+ &compositor->damage_region,
+ surface->x + x, surface->y + y,
+ width, height);
+ wlsc_compositor_schedule_repaint(compositor);
+}
+
+void
+wlsc_surface_damage(struct wlsc_surface *surface)
+{
+ wlsc_surface_damage_rectangle(surface, 0, 0,
+ surface->width, surface->height);
+}
+
uint32_t
get_time(void)
{
{
struct wlsc_surface *surface =
container_of(resource, struct wlsc_surface, surface.resource);
- struct wlsc_compositor *compositor = surface->compositor;
struct wl_listener *l, *next;
uint32_t time;
+ wlsc_surface_damage(surface);
+
wl_list_remove(&surface->link);
glDeleteTextures(1, &surface->texture);
l->func(l, &surface->surface, time);
free(surface);
-
- wlsc_compositor_schedule_repaint(compositor);
}
uint32_t *
struct wlsc_compositor *ec = output->compositor;
struct wlsc_surface *es;
struct wlsc_input_device *eid;
+ pixman_region32_t new_damage, total_damage;
+ pixman_box32_t *extents;
glViewport(0, 0, output->width, output->height);
+ pixman_region32_init(&new_damage);
+ pixman_region32_init(&total_damage);
+ pixman_region32_intersect_rect(&new_damage,
+ &ec->damage_region,
+ output->x, output->y,
+ output->width, output->height);
+ pixman_region32_subtract(&ec->damage_region,
+ &ec->damage_region, &new_damage);
+ pixman_region32_union(&total_damage, &new_damage,
+ &output->previous_damage_region);
+ pixman_region32_copy(&output->previous_damage_region, &new_damage);
+
+ extents = pixman_region32_extents(&total_damage);
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(extents->x1, extents->y1,
+ extents->x2 - extents->x1, extents->y2 - extents->y1);
+
es = container_of(ec->surface_list.next, struct wlsc_surface, link);
if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN &&
es->fullscreen_output == output) {
{
struct wlsc_surface *es = (struct wlsc_surface *) surface;
+ /* FIXME: This damages the entire old surface, but we should
+ * really just damage the part that's no longer covered by the
+ * surface. Anything covered by the new surface will be
+ * damaged by the client. */
+ wlsc_surface_damage(es);
+
buffer->attach(buffer, surface);
es->buffer = buffer;
es->x += x;
break;
}
- wlsc_compositor_schedule_repaint(es->compositor);
+ wlsc_surface_damage(es);
es->map_type = WLSC_SURFACE_MAP_TOPLEVEL;
}
es->y = pes->y + y;
wlsc_surface_update_matrix(es);
- wlsc_compositor_schedule_repaint(es->compositor);
+ wlsc_surface_damage(es);
es->map_type = WLSC_SURFACE_MAP_TRANSIENT;
}
es->y = (output->height - es->height) / 2;
es->fullscreen_output = output;
wlsc_surface_update_matrix(es);
- wlsc_compositor_schedule_repaint(es->compositor);
+ wlsc_surface_damage(es);
es->map_type = WLSC_SURFACE_MAP_FULLSCREEN;
}
struct wlsc_surface *es = (struct wlsc_surface *) surface;
es->buffer->damage(es->buffer, surface, x, y, width, height);
- wlsc_compositor_schedule_repaint(es->compositor);
+
+ wlsc_surface_damage_rectangle(es, x, y, width, height);
}
const static struct wl_surface_interface surface_interface = {
wlsc_input_device_attach(struct wlsc_input_device *device,
struct wl_buffer *buffer, int x, int y)
{
- struct wlsc_compositor *ec =
- (struct wlsc_compositor *) device->input_device.compositor;
+ wlsc_surface_damage(device->sprite);
buffer->attach(buffer, &device->sprite->surface);
device->hotspot_x = x;
device->sprite->height = buffer->height;
wlsc_surface_update_matrix(device->sprite);
- wlsc_compositor_schedule_repaint(ec);
+ wlsc_surface_damage(device->sprite);
}
time, x, y, sx, sy);
}
+ wlsc_surface_damage(wd->sprite);
+
wd->sprite->x = device->x - wd->hotspot_x;
wd->sprite->y = device->y - wd->hotspot_y;
wlsc_surface_update_matrix(wd->sprite);
- wlsc_compositor_schedule_repaint(ec);
+ wlsc_surface_damage(wd->sprite);
}
static void
{
struct wl_list *l;
+ wlsc_surface_damage(switcher->current);
l = switcher->current->link.next;
if (l == &switcher->compositor->surface_list)
l = switcher->compositor->surface_list.next;
wl_list_remove(&switcher->listener.link);
wl_list_insert(switcher->current->surface.destroy_listener_list.prev,
&switcher->listener.link);
- wlsc_compositor_schedule_repaint(switcher->compositor);
+ wlsc_surface_damage(switcher->current);
}
static void
compositor->focus = 0;
}
- wlsc_compositor_schedule_repaint(compositor);
+ wlsc_surface_damage(wd->sprite);
}
void
output->width = width;
output->height = height;
+ pixman_region32_init(&output->previous_damage_region);
+
output->background =
background_create(output, option_background);
wl_display_add_object(c->wl_display, &output->object);
wl_display_add_global(c->wl_display, &output->object,
wlsc_output_post_geometry);
+
+ pixman_region32_union_rect(&c->damage_region,
+ &c->damage_region,
+ x, y, width, height);
}
int
loop = wl_display_get_event_loop(ec->wl_display);
ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec);
+ pixman_region32_init(&ec->damage_region);
wlsc_compositor_schedule_repaint(ec);
return 0;