static cairo_surface_t * _cairo_xcb_surface_fallback (cairo_xcb_surface_t *surface, cairo_composite_rectangles_t *composite) { cairo_image_surface_t *image; cairo_status_t status; status = _cairo_composite_rectangles_add_to_damage (composite, &surface->fallback_damage); if (unlikely (status)) return _cairo_surface_create_in_error (status); if (surface->fallback) return &surface->fallback->base; image = (cairo_image_surface_t *) _get_image (surface, TRUE, 0, 0, surface->width, surface->height); /* If there was a deferred clear, _get_image applied it */ if (image->base.status == CAIRO_STATUS_SUCCESS) { surface->deferred_clear = FALSE; surface->fallback = image; } return &surface->fallback->base; }
static cairo_surface_t * _cairo_xcb_surface_map_to_image (void *abstract_surface, const cairo_rectangle_int_t *extents) { cairo_xcb_surface_t *surface = abstract_surface; cairo_surface_t *image; if (surface->fallback) return surface->fallback->base.backend->map_to_image (&surface->fallback->base, extents); image = _get_image (surface, TRUE, extents->x, extents->y, extents->width, extents->height); if (unlikely (image->status)) return image; /* Do we have a deferred clear and this image surface does NOT cover the * whole xcb surface? Have to apply the clear in that case, else * uploading the image will handle the problem for us. */ if (surface->deferred_clear && ! (extents->width == surface->width && extents->height == surface->height)) { cairo_status_t status = _cairo_xcb_surface_clear (surface); if (unlikely (status)) { cairo_surface_destroy(image); return _cairo_surface_create_in_error (status); } } surface->deferred_clear = FALSE; cairo_surface_set_device_offset (image, -extents->x, -extents->y); return image; }
static cairo_status_t _cairo_xcb_surface_acquire_source_image (void *abstract_surface, cairo_image_surface_t **image_out, void **image_extra) { cairo_xcb_surface_t *surface = abstract_surface; cairo_surface_t *image; if (surface->fallback != NULL) { image = cairo_surface_reference (&surface->fallback->base); goto DONE; } image = _cairo_surface_has_snapshot (&surface->base, &_cairo_image_surface_backend); if (image != NULL) { image = cairo_surface_reference (image); goto DONE; } image = _get_image (surface, FALSE, 0, 0, surface->width, surface->height); if (unlikely (image->status)) return image->status; _cairo_surface_attach_snapshot (&surface->base, image, NULL); DONE: *image_out = (cairo_image_surface_t *) image; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; }
static cairo_surface_t * _cairo_xcb_surface_map_to_image (cairo_xcb_surface_t *surface) { cairo_status_t status; cairo_image_surface_t *image; status = _get_image (surface, TRUE, &image); if (unlikely (status)) return _cairo_surface_create_in_error (status); return &image->base; }
static cairo_status_t _cairo_xcb_surface_acquire_source_image (void *abstract_surface, cairo_image_surface_t **image_out, void **image_extra) { cairo_xcb_surface_t *surface = abstract_surface; cairo_image_surface_t *image; cairo_status_t status; if (surface->drm != NULL && ! surface->marked_dirty) { return _cairo_surface_acquire_source_image (surface->drm, image_out, image_extra); } if (surface->fallback != NULL) { image = (cairo_image_surface_t *) cairo_surface_reference (surface->fallback); goto DONE; } image = (cairo_image_surface_t *) _cairo_surface_has_snapshot (&surface->base, &_cairo_image_surface_backend); if (image != NULL) { image = (cairo_image_surface_t *) cairo_surface_reference (&image->base); goto DONE; } status = _get_image (surface, FALSE, &image); if (unlikely (status)) return status; _cairo_surface_attach_snapshot (&surface->base, &image->base, NULL); DONE: *image_out = image; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; }