cairo_surface_t * _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, pixman_format_code_t pixman_format) { cairo_image_surface_t *surface; surface = malloc (sizeof (cairo_image_surface_t)); if (surface == NULL) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&surface->base, &_cairo_image_surface_backend, _cairo_content_from_pixman_format (pixman_format)); surface->pixman_image = pixman_image; surface->pixman_format = pixman_format; surface->format = _cairo_format_from_pixman_format (pixman_format); surface->data = (unsigned char *) pixman_image_get_data (pixman_image); surface->owns_data = FALSE; surface->has_clip = FALSE; surface->transparency = CAIRO_IMAGE_UNKNOWN; surface->width = pixman_image_get_width (pixman_image); surface->height = pixman_image_get_height (pixman_image); surface->stride = pixman_image_get_stride (pixman_image); surface->depth = pixman_image_get_depth (pixman_image); return &surface->base; }
static cairo_surface_t * _xcb_drm_create_surface_for_drawable (cairo_xcb_connection_t *connection, cairo_xcb_screen_t *screen, xcb_drawable_t drawable, pixman_format_code_t pixman_format, int width, int height) { uint32_t attachments[] = { XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT }; xcb_dri2_get_buffers_reply_t *buffers; xcb_dri2_dri2_buffer_t *buffer; cairo_surface_t *surface; if (! _cairo_drm_size_is_valid (screen->device, width, height)) return NULL; xcb_dri2_create_drawable (connection->xcb_connection, drawable); buffers = xcb_dri2_get_buffers_reply (connection->xcb_connection, xcb_dri2_get_buffers (connection->xcb_connection, drawable, 1, ARRAY_LENGTH (attachments), attachments), 0); if (buffers == NULL) { xcb_dri2_destroy_drawable (connection->xcb_connection, drawable); return NULL; } /* If the drawable is a window, we expect to receive an extra fake front, * which would involve copying on each flush - contrary to the user * expectations. But that is likely to be preferable to mixing drm/xcb * operations. */ buffer = xcb_dri2_get_buffers_buffers (buffers); if (buffers->count == 1 && buffer[0].attachment == XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT) { assert (buffer[0].cpp == PIXMAN_FORMAT_BPP (pixman_format) / 8); surface = cairo_drm_surface_create_for_name (screen->device, buffer[0].name, _cairo_format_from_pixman_format (pixman_format), width, height, buffer[0].pitch); } else { xcb_dri2_destroy_drawable (connection->xcb_connection, drawable); surface = NULL; } free (buffers); return surface; }
cairo_surface_t * _cairo_image_surface_create_with_masks (unsigned char *data, cairo_format_masks_t *format, int width, int height, int stride) { cairo_surface_t *surface; pixman_format_t *pixman_format; pixman_image_t *pixman_image; cairo_format_t cairo_format; pixman_format = pixman_format_create_masks (format->bpp, format->alpha_mask, format->red_mask, format->green_mask, format->blue_mask); if (pixman_format == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } cairo_format = _cairo_format_from_pixman_format (pixman_format); pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format, width, height, format->bpp, stride); pixman_format_destroy (pixman_format); if (pixman_image == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } surface = _cairo_image_surface_create_for_pixman_image (pixman_image, cairo_format); return surface; }
void _cairo_image_surface_init (cairo_image_surface_t *surface, pixman_image_t *pixman_image, pixman_format_code_t pixman_format) { surface->parent = NULL; surface->pixman_image = pixman_image; surface->pixman_format = pixman_format; surface->format = _cairo_format_from_pixman_format (pixman_format); surface->data = (uint8_t *) pixman_image_get_data (pixman_image); surface->owns_data = FALSE; surface->transparency = CAIRO_IMAGE_UNKNOWN; surface->color = CAIRO_IMAGE_UNKNOWN_COLOR; surface->width = pixman_image_get_width (pixman_image); surface->height = pixman_image_get_height (pixman_image); surface->stride = pixman_image_get_stride (pixman_image); surface->depth = pixman_image_get_depth (pixman_image); surface->base.is_clear = surface->width == 0 || surface->height == 0; surface->compositor = _cairo_image_spans_compositor_get (); }