diff options
Diffstat (limited to 'libs/cairo-1.16.0/src/drm/cairo-drm-gallium-surface.c')
-rw-r--r-- | libs/cairo-1.16.0/src/drm/cairo-drm-gallium-surface.c | 826 |
1 files changed, 0 insertions, 826 deletions
diff --git a/libs/cairo-1.16.0/src/drm/cairo-drm-gallium-surface.c b/libs/cairo-1.16.0/src/drm/cairo-drm-gallium-surface.c deleted file mode 100644 index ca18f73..0000000 --- a/libs/cairo-1.16.0/src/drm/cairo-drm-gallium-surface.c +++ /dev/null @@ -1,826 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * Copyright © 2009 Eric Anholt - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Chris Wilson. - */ - -#include "cairoint.h" - -#include "cairo-drm-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" - -#include <dlfcn.h> - -#include <state_tracker/drm_api.h> -#include <pipe/p_format.h> -#include <pipe/p_screen.h> -#include <pipe/p_context.h> -#include <pipe/p_state.h> - -#include <util/u_inlines.h> - -typedef struct _gallium_surface gallium_surface_t; -typedef struct _gallium_device gallium_device_t; - -struct _gallium_device { - cairo_drm_device_t drm; - - void *dlhandle; - struct drm_api *api; - - struct pipe_screen *screen; - struct pipe_context *pipe; - - int max_size; -}; - -struct _gallium_surface { - cairo_drm_surface_t drm; - - enum pipe_format pipe_format; - - struct pipe_resource *texture; - struct pipe_transfer *map_transfer; - - cairo_surface_t *fallback; -}; - -static cairo_surface_t * -gallium_surface_create_internal (gallium_device_t *device, - enum pipe_format format, - int width, int height); - -static inline gallium_device_t * -gallium_device (gallium_surface_t *surface) -{ - return (gallium_device_t *) surface->drm.base.device; -} - -static cairo_format_t -_cairo_format_from_pipe_format (enum pipe_format format) -{ - switch ((int) format) { - case PIPE_FORMAT_A8_UNORM: - return CAIRO_FORMAT_A8; - case PIPE_FORMAT_A8R8G8B8_UNORM: - return CAIRO_FORMAT_ARGB32; - default: - return CAIRO_FORMAT_INVALID; - } -} - -static enum pipe_format -pipe_format_from_format (cairo_format_t format) -{ - switch ((int) format) { - case CAIRO_FORMAT_A8: - return PIPE_FORMAT_A8_UNORM; - case CAIRO_FORMAT_ARGB32: - return PIPE_FORMAT_A8R8G8B8_UNORM; - default: - return (enum pipe_format) -1; - } -} - -static enum pipe_format -pipe_format_from_content (cairo_content_t content) -{ - if (content == CAIRO_CONTENT_ALPHA) - return PIPE_FORMAT_A8_UNORM; - else - return PIPE_FORMAT_A8R8G8B8_UNORM; -} - -static cairo_bool_t -format_is_supported_destination (gallium_device_t *device, - enum pipe_format format) -{ - if (format == (enum pipe_format) -1) - return FALSE; - - return device->screen->is_format_supported (device->screen, - format, - 0, - PIPE_BIND_RENDER_TARGET, - 0); -} - -#if 0 -static cairo_bool_t -format_is_supported_source (gallium_device_t *device, - enum pipe_format format) -{ - return device->screen->is_format_supported (device->screen, - format, - 0, - PIPE_BIND_SAMPLER_VIEW, - 0); -} -#endif - -static cairo_surface_t * -gallium_surface_create_similar (void *abstract_src, - cairo_content_t content, - int width, - int height) -{ - gallium_surface_t *other = abstract_src; - gallium_device_t *device = gallium_device (other); - enum pipe_format pipe_format; - cairo_surface_t *surface = NULL; - cairo_status_t status; - - status = cairo_device_acquire (&device->drm.base); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (MAX (width, height) > device->max_size) - goto RELEASE; - - if (content == other->drm.base.content) - pipe_format = other->pipe_format; - else - pipe_format = pipe_format_from_content (content); - - if (! format_is_supported_destination (device, pipe_format)) - goto RELEASE; - - surface = gallium_surface_create_internal (device, - pipe_format, - width, height); - -RELEASE: - cairo_device_release (&device->drm.base); - - return surface; -} - -static cairo_status_t -gallium_surface_finish (void *abstract_surface) -{ - gallium_surface_t *surface = abstract_surface; - gallium_device_t *device = gallium_device (surface); - cairo_status_t status; - - status = cairo_device_acquire (&device->drm.base); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - pipe_resource_reference (&surface->texture, NULL); - cairo_device_release (&device->drm.base); - } - - return _cairo_drm_surface_finish (&surface->drm); -} - -static cairo_surface_t * -gallium_surface_map_to_image (gallium_surface_t *surface) -{ - gallium_device_t *device = gallium_device (surface); - cairo_status_t status; - void *ptr = NULL; - - status = cairo_device_acquire (&device->drm.base); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - surface->map_transfer = - pipe_get_transfer (device->pipe, - surface->texture, 0, 0, 0, - PIPE_TRANSFER_MAP_DIRECTLY | - PIPE_TRANSFER_READ_WRITE, - 0, 0, - surface->drm.width, - surface->drm.height); - if (likely (surface->map_transfer != NULL)) - ptr = device->pipe->transfer_map (device->pipe, surface->map_transfer); - - cairo_device_release (&device->drm.base); - - if (unlikely (ptr == NULL)) { - if (surface->map_transfer != NULL) { - device->pipe->transfer_destroy (device->pipe, - surface->map_transfer); - surface->map_transfer = NULL; - } - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - return cairo_image_surface_create_for_data (ptr, - surface->drm.format, - surface->drm.width, - surface->drm.height, - surface->map_transfer->stride); -} - -static cairo_status_t -gallium_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - gallium_surface_t *surface = abstract_surface; - gallium_device_t *device = gallium_device (surface); - cairo_format_t format; - cairo_surface_t *image; - cairo_status_t status; - struct pipe_transfer *transfer; - void *ptr; - - if (surface->fallback != NULL) { - *image_out = (cairo_image_surface_t *) - cairo_surface_reference (surface->fallback); - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; - } - - if (unlikely (surface->drm.width == 0 || surface->drm.height == 0)) { - image = cairo_image_surface_create (surface->drm.format, 0, 0); - if (unlikely (image->status)) - return image->status; - - *image_out = (cairo_image_surface_t *) image; - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; - } - - format = _cairo_format_from_pipe_format (surface->pipe_format); - if (format == CAIRO_FORMAT_INVALID) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = cairo_device_acquire (&device->drm.base); - if (unlikely (status)) - return status; - - transfer = pipe_get_transfer (device->pipe, - surface->texture, 0, 0, 0, - PIPE_TRANSFER_READ, - 0, 0, - surface->drm.width, - surface->drm.height); - ptr = device->pipe->transfer_map (device->pipe, transfer); - cairo_device_release (&device->drm.base); - - image = cairo_image_surface_create_for_data (ptr, format, - surface->drm.width, - surface->drm.height, - surface->drm.stride); - if (unlikely (image->status)) - return image->status; - - *image_out = (cairo_image_surface_t *) image; - *image_extra = transfer; - return CAIRO_STATUS_SUCCESS; -} - -static void -gallium_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); - - if (image_extra != NULL) { - gallium_device_t *device = gallium_device (abstract_surface); - - device->pipe->transfer_unmap (device->pipe, image_extra); - device->pipe->transfer_destroy (device->pipe, image_extra); - } -} - -static cairo_status_t -gallium_surface_flush (void *abstract_surface, - unsigned flags) -{ - gallium_surface_t *surface = abstract_surface; - gallium_device_t *device = gallium_device (surface); - cairo_status_t status; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - if (surface->fallback == NULL) { - device->pipe->flush (device->pipe, - PIPE_FLUSH_RENDER_CACHE, - NULL); - return CAIRO_STATUS_SUCCESS; - } - - /* kill any outstanding maps */ - cairo_surface_finish (surface->fallback); - - status = cairo_device_acquire (&device->drm.base); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - device->pipe->transfer_unmap (device->pipe, - surface->map_transfer); - device->pipe->transfer_destroy (device->pipe, - surface->map_transfer); - surface->map_transfer = NULL; - cairo_device_release (&device->drm.base); - } - - status = cairo_surface_status (surface->fallback); - cairo_surface_destroy (surface->fallback); - surface->fallback = NULL; - - return status; -} - -static cairo_int_status_t -gallium_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_clip_t *clip) -{ - gallium_surface_t *surface = abstract_surface; - - if (surface->fallback == NULL) { - /* XXX insert magic */ - surface->fallback = gallium_surface_map_to_image (surface); - } - - return _cairo_surface_paint (surface->fallback, op, source, clip); -} - -static cairo_int_status_t -gallium_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - cairo_clip_t *clip) -{ - gallium_surface_t *surface = abstract_surface; - - if (surface->fallback == NULL) { - /* XXX insert magic */ - surface->fallback = gallium_surface_map_to_image (surface); - } - - return _cairo_surface_mask (surface->fallback, - op, source, mask, - clip); -} - -static cairo_int_status_t -gallium_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - cairo_clip_t *clip) -{ - gallium_surface_t *surface = abstract_surface; - - if (surface->fallback == NULL) { - /* XXX insert magic */ - surface->fallback = gallium_surface_map_to_image (surface); - } - - return _cairo_surface_stroke (surface->fallback, - op, source, - path, style, - ctm, ctm_inverse, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -gallium_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - cairo_clip_t *clip) -{ - gallium_surface_t *surface = abstract_surface; - - if (surface->fallback == NULL) { - /* XXX insert magic */ - surface->fallback = gallium_surface_map_to_image (surface); - } - - return _cairo_surface_fill (surface->fallback, - op, source, - path, fill_rule, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -gallium_surface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - cairo_clip_t *clip, - int *num_remaining) -{ - gallium_surface_t *surface = abstract_surface; - - *num_remaining = 0; - - if (surface->fallback == NULL) { - /* XXX insert magic */ - surface->fallback = gallium_surface_map_to_image (surface); - } - - return _cairo_surface_show_text_glyphs (surface->fallback, - op, source, - NULL, 0, - glyphs, num_glyphs, - NULL, 0, 0, - scaled_font, - clip); -} - -static const cairo_surface_backend_t gallium_surface_backend = { - CAIRO_SURFACE_TYPE_DRM, - _cairo_default_context_create, - - gallium_surface_create_similar, - gallium_surface_finish, - - NULL, - gallium_surface_acquire_source_image, - gallium_surface_release_source_image, - - NULL, //gallium_surface_acquire_dest_image, - NULL, //gallium_surface_release_dest_image, - NULL, //gallium_surface_clone_similar, - NULL, //gallium_surface_composite, - NULL, //gallium_surface_fill_rectangles, - NULL, //gallium_surface_composite_trapezoids, - NULL, //gallium_surface_create_span_renderer, - NULL, //gallium_surface_check_span_renderer, - NULL, /* copy_page */ - NULL, /* show_page */ - _cairo_drm_surface_get_extents, - NULL, /* old_show_glyphs */ - _cairo_drm_surface_get_font_options, - gallium_surface_flush, - NULL, /* mark_dirty_rectangle */ - NULL, //gallium_surface_scaled_font_fini, - NULL, //gallium_surface_scaled_glyph_fini, - - gallium_surface_paint, - gallium_surface_mask, - gallium_surface_stroke, - gallium_surface_fill, - gallium_surface_glyphs, - - NULL, /* snapshot */ - - NULL, /* is_similar */ - - NULL, /* reset */ -}; - -static int -gallium_format_stride_for_width (enum pipe_format format, int width) -{ - int stride; - - stride = 1024; /* XXX fugly */ - while (stride < width) - stride *= 2; - - if (format == PIPE_FORMAT_A8R8G8B8_UNORM) - stride *= 4; - - return stride; -} - -static cairo_drm_bo_t * -_gallium_fake_bo_create (uint32_t size, uint32_t name) -{ - cairo_drm_bo_t *bo; - - /* XXX integrate with winsys handle */ - - bo = _cairo_malloc (sizeof (cairo_drm_bo_t)); - - CAIRO_REFERENCE_COUNT_INIT (&bo->ref_count, 1); - bo->name = name; - bo->handle = 0; - bo->size = size; - - return bo; -} - -static void -_gallium_fake_bo_release (void *dev, void *bo) -{ - free (bo); -} - -static cairo_surface_t * -gallium_surface_create_internal (gallium_device_t *device, - enum pipe_format pipe_format, - int width, int height) -{ - gallium_surface_t *surface; - struct pipe_resource template; - cairo_status_t status; - cairo_format_t format; - int stride, size; - - surface = _cairo_malloc (sizeof (gallium_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - format = _cairo_format_from_pipe_format (pipe_format); - _cairo_surface_init (&surface->drm.base, - &gallium_surface_backend, - &device->drm.base, - _cairo_content_from_format (format)); - _cairo_drm_surface_init (&surface->drm, format, width, height); - - stride = gallium_format_stride_for_width (pipe_format, width); - size = stride * height; - - surface->drm.stride = stride; - surface->drm.bo = _gallium_fake_bo_create (size, 0); - - memset(&template, 0, sizeof(template)); - template.target = PIPE_TEXTURE_2D; - template.format = pipe_format; - template.width0 = width; - template.height0 = height; - template.depth0 = 1; - template.last_level = 0; - template.bind = PIPE_BIND_RENDER_TARGET; - surface->texture = device->screen->resource_create (device->screen, - &template); - - if (unlikely (surface->texture == NULL)) { - status = _cairo_drm_surface_finish (&surface->drm); - free (surface); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - surface->pipe_format = pipe_format; - surface->texture = NULL; - - return &surface->drm.base; -} - -static cairo_surface_t * -gallium_surface_create (cairo_drm_device_t *base_dev, - cairo_format_t format, - int width, int height) -{ - gallium_device_t *device = (gallium_device_t *) base_dev; - cairo_surface_t *surface; - enum pipe_format pipe_format; - cairo_status_t status; - - status = cairo_device_acquire (&device->drm.base); - - if (MAX (width, height) > device->max_size) { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - goto RELEASE; - } - - pipe_format = pipe_format_from_format (format); - if (! format_is_supported_destination (device, pipe_format)) { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - goto RELEASE; - } - - surface = gallium_surface_create_internal (device, - pipe_format, - width, height); - -RELEASE: - cairo_device_release (&device->drm.base); - - return surface; -} - -#if 0 -static cairo_surface_t * -gallium_surface_create_for_name (cairo_drm_device_t *base_dev, - unsigned int name, - cairo_format_t format, - int width, int height, int stride) -{ - gallium_device_t *device; - gallium_surface_t *surface; - cairo_status_t status; - cairo_content_t content; - - surface = _cairo_malloc (sizeof (gallium_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - switch (format) { - default: - case CAIRO_FORMAT_INVALID: - case CAIRO_FORMAT_A1: - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - case CAIRO_FORMAT_A8: - surface->pipe_format = PIPE_FORMAT_A8_UNORM; - break; - case CAIRO_FORMAT_RGB24: - case CAIRO_FORMAT_ARGB32: - surface->pipe_format = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - } - - status = cairo_device_acquire (&device->drm.base); - - if (MAX (width, height) > device->max_size) { - cairo_device_release (&device->drm.base); - free (surface); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - } - - if (! format_is_supported_destination (device, surface->pipe_format)) { - cairo_device_release (&device->drm.base); - free (surface); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - } - - content = _cairo_content_from_format (format); - _cairo_surface_init (&surface->drm.base, - &gallium_surface_backend, - content); - _cairo_drm_surface_init (&surface->drm, base_dev); - - surface->drm.bo = _gallium_fake_bo_create (height * stride, name); - - surface->drm.width = width; - surface->drm.height = height; - surface->drm.stride = stride; - -#if 0 - /* XXX screen->create_from_handle */ - surface->buffer = device->api->buffer_from_handle (device->api, - device->screen, - "cairo-gallium alien", - name); - if (unlikely (surface->buffer == NULL)) { - status = _cairo_drm_surface_finish (&surface->drm); - cairo_device_release (&device->drm.base); - free (surface); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } -#endif - - surface->texture = NULL; - - surface->fallback = NULL; - - cairo_device_release (&device->drm.base); - - return &surface->drm.base; -} - -static cairo_int_status_t -gallium_surface_flink (void *abstract_surface) -{ - gallium_surface_t *surface = abstract_surface; - gallium_device_t *device; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - status = cairo_device_acquire (&device->drm.base); - if (! device->api->global_handle_from_buffer (device->api, - device->screen, - surface->buffer, - &surface->drm.bo->name)) - { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - cairo_device_release (&device->drm.base); - - return status; -} -#endif - -static void -gallium_device_destroy (void *abstract_device) -{ - gallium_device_t *device = abstract_device; - - device->pipe->destroy (device->pipe); - device->screen->destroy (device->screen); - device->api->destroy (device->api); - - dlclose (device->dlhandle); - free (device); -} - -cairo_drm_device_t * -_cairo_drm_gallium_device_create (int fd, dev_t dev, int vendor_id, int chip_id) -{ - gallium_device_t *device; - cairo_status_t status; - void *handle; - const char *libdir; - char buf[4096]; - struct drm_api *(*ctor) (void); - - /* XXX need search path + probe */ - libdir = getenv ("CAIRO_GALLIUM_LIBDIR"); - if (libdir == NULL) - libdir = "/usr/lib/dri"; - buf[snprintf (buf, sizeof (buf)-1, "%s/i915_dri.so", libdir)] = '\0'; - - handle = dlopen (buf, RTLD_LAZY); - if (handle == NULL) - return NULL; - - ctor = dlsym (handle, "drm_api_create"); - if (ctor == NULL) { - dlclose (handle); - return NULL; - } - - device = _cairo_malloc (sizeof (gallium_device_t)); - if (device == NULL) { - dlclose (handle); - return _cairo_drm_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - device->dlhandle = handle; - - device->drm.surface.create = gallium_surface_create; - device->drm.surface.create_for_name = NULL; - //device->drm.surface.create_for_name = gallium_surface_create_for_name; - device->drm.surface.enable_scan_out = NULL; - //device->drm.surface.flink = gallium_surface_flink; - device->drm.surface.flink = NULL; - - device->drm.device.flush = NULL; - device->drm.device.throttle = NULL; - device->drm.device.destroy = gallium_device_destroy; - - device->drm.bo.release = _gallium_fake_bo_release; - - device->api = ctor (); - if (device->api == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP; - } - - device->screen = device->api->create_screen (device->api, fd, NULL); - if (device->screen == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_API; - } - - device->max_size = 1 << device->screen->get_param (device->screen, - PIPE_CAP_MAX_TEXTURE_2D_LEVELS); - - device->pipe = device->screen->context_create (device->screen, device); - if (device->pipe == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_SCREEN; - } - - return _cairo_drm_device_init (&device->drm, - fd, dev, - 0, 0, - device->max_size); - -CLEANUP_SCREEN: - device->screen->destroy (device->screen); -CLEANUP_API: - device->api->destroy (device->api); -CLEANUP: - free (device); - dlclose (handle); - return _cairo_drm_device_create_in_error (status); -} |