gallium: Refresh.

Catch up with changes in APIs, still no substance and the integration
with winsys handles needs review.
This commit is contained in:
Chris Wilson 2010-04-12 10:42:14 +01:00
parent bd672d080c
commit cf0933a05a
4 changed files with 322 additions and 219 deletions

View file

@ -209,14 +209,6 @@ enabled_cairo_boilerplate_private += $(cairo_boilerplate_png_private)
enabled_cairo_boilerplate_sources += $(cairo_boilerplate_png_sources)
endif
supported_cairo_boilerplate_headers += $(cairo_boilerplate_glew_headers)
all_cairo_boilerplate_headers += $(cairo_boilerplate_glew_headers)
all_cairo_boilerplate_private += $(cairo_boilerplate_glew_private)
all_cairo_boilerplate_sources += $(cairo_boilerplate_glew_sources)
enabled_cairo_boilerplate_headers += $(cairo_boilerplate_glew_headers)
enabled_cairo_boilerplate_private += $(cairo_boilerplate_glew_private)
enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glew_sources)
unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_gl_headers)
all_cairo_boilerplate_headers += $(cairo_boilerplate_gl_headers)
all_cairo_boilerplate_private += $(cairo_boilerplate_gl_private)

View file

@ -62,7 +62,6 @@ endif
ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1)
@echo "#define CAIRO_HAS_PNG_FUNCTIONS 1" >> src/cairo-features.h
endif
@echo "#define CAIRO_HAS_GLEW_FUNCTIONS 1" >> src/cairo-features.h
ifeq ($(CAIRO_HAS_GL_SURFACE),1)
@echo "#define CAIRO_HAS_GL_SURFACE 1" >> src/cairo-features.h
endif

View file

@ -287,14 +287,6 @@ ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1)
enabled_cairo_pkgconf += cairo-png.pc
endif
supported_cairo_headers += $(cairo_glew_headers)
all_cairo_headers += $(cairo_glew_headers)
all_cairo_private += $(cairo_glew_private)
all_cairo_sources += $(cairo_glew_sources)
enabled_cairo_headers += $(cairo_glew_headers)
enabled_cairo_private += $(cairo_glew_private)
enabled_cairo_sources += $(cairo_glew_sources)
unsupported_cairo_headers += $(cairo_gl_headers)
all_cairo_headers += $(cairo_gl_headers)
all_cairo_private += $(cairo_gl_private)

View file

@ -34,20 +34,23 @@
#include "cairoint.h"
#include "cairo-drm-private.h"
#include "cairo-error-private.h"
#include <dlfcn.h>
#include <state_tracker/drm_api.h>
#include <pipe/p_inlines.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 base;
cairo_mutex_t mutex;
cairo_drm_device_t drm;
void *dlhandle;
struct drm_api *api;
@ -59,34 +62,25 @@ struct _gallium_device {
};
struct _gallium_surface {
cairo_drm_surface_t base;
cairo_drm_surface_t drm;
struct pipe_buffer *buffer;
enum pipe_format pipe_format;
struct pipe_texture *texture;
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,
cairo_content_t content,
enum pipe_format format,
int width, int height);
static gallium_device_t *
gallium_device_acquire (cairo_drm_device_t *base_dev)
static inline gallium_device_t *
gallium_device (gallium_surface_t *surface)
{
gallium_device_t *device = (gallium_device_t *) base_dev;
CAIRO_MUTEX_LOCK (device->mutex);
return device;
}
static void
gallium_device_release (gallium_device_t *device)
{
CAIRO_MUTEX_UNLOCK (device->mutex);
return (gallium_device_t *) surface->drm.base.device;
}
static cairo_format_t
@ -102,6 +96,19 @@ _cairo_format_from_pipe_format (enum pipe_format format)
}
}
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)
{
@ -115,13 +122,17 @@ 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_TEXTURE_USAGE_RENDER_TARGET,
PIPE_BIND_RENDER_TARGET,
0);
}
#if 0
static cairo_bool_t
format_is_supported_source (gallium_device_t *device,
enum pipe_format format)
@ -129,9 +140,10 @@ format_is_supported_source (gallium_device_t *device,
return device->screen->is_format_supported (device->screen,
format,
0,
PIPE_TEXTURE_USAGE_SAMPLER,
PIPE_BIND_SAMPLER_VIEW,
0);
}
#endif
static cairo_surface_t *
gallium_surface_create_similar (void *abstract_src,
@ -140,26 +152,32 @@ gallium_surface_create_similar (void *abstract_src,
int height)
{
gallium_surface_t *other = abstract_src;
gallium_device_t *device;
gallium_device_t *device = gallium_device (other);
enum pipe_format pipe_format;
cairo_surface_t *surface = NULL;
cairo_status_t status;
device = gallium_device_acquire (other->base.device);
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;
pipe_format = pipe_format_from_content (content);
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,
content, pipe_format,
pipe_format,
width, height);
RELEASE:
gallium_device_release (device);
cairo_device_release (&device->drm.base);
return surface;
}
@ -168,24 +186,56 @@ static cairo_status_t
gallium_surface_finish (void *abstract_surface)
{
gallium_surface_t *surface = abstract_surface;
gallium_device_t *device;
gallium_device_t *device = gallium_device (surface);
cairo_status_t status;
device = gallium_device_acquire (surface->base.device);
device->screen->buffer_destroy (surface->buffer);
gallium_device_release (device);
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->base);
return _cairo_drm_surface_finish (&surface->drm);
}
static void
gallium_surface_unmap (void *closure)
static cairo_surface_t *
gallium_surface_map_to_image (gallium_surface_t *surface)
{
gallium_surface_t *surface = closure;
gallium_device_t *device;
gallium_device_t *device = gallium_device (surface);
cairo_status_t status;
void *ptr = NULL;
device = gallium_device_acquire (surface->base.device);
pipe_buffer_unmap (device->screen, surface->buffer);
gallium_device_release (device);
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
@ -194,10 +244,11 @@ gallium_surface_acquire_source_image (void *abstract_surface,
void **image_extra)
{
gallium_surface_t *surface = abstract_surface;
gallium_device_t *device;
gallium_device_t *device = gallium_device (surface);
cairo_format_t format;
cairo_image_surface_t *image;
cairo_surface_t *image;
cairo_status_t status;
struct pipe_transfer *transfer;
void *ptr;
if (surface->fallback != NULL) {
@ -207,14 +258,12 @@ gallium_surface_acquire_source_image (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
if (unlikely (surface->base.width == 0 || surface->base.height == 0)) {
image = (cairo_image_surface_t *)
cairo_image_surface_create (surface->base.format, 0, 0);
status = image->base.status;
if (unlikely (status))
return status;
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 = image;
*image_out = (cairo_image_surface_t *) image;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -223,30 +272,28 @@ gallium_surface_acquire_source_image (void *abstract_surface,
if (format == CAIRO_FORMAT_INVALID)
return CAIRO_INT_STATUS_UNSUPPORTED;
device = gallium_device_acquire (surface->base.device);
ptr = pipe_buffer_map (device->screen, surface->buffer,
PIPE_BUFFER_USAGE_CPU_READ);
gallium_device_release (device);
image = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (ptr, format,
surface->base.width,
surface->base.height,
surface->base.stride);
if (unlikely (image->base.status))
return image->base.status;
status = _cairo_user_data_array_set_data (&image->base.user_data,
(cairo_user_data_key_t *) &surface->fallback,
surface,
gallium_surface_unmap);
if (unlikely (status)) {
cairo_surface_destroy (&image->base);
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 = NULL;
*image_extra = transfer;
return CAIRO_STATUS_SUCCESS;
}
@ -256,95 +303,41 @@ gallium_surface_release_source_image (void *abstract_surface,
void *image_extra)
{
cairo_surface_destroy (&image->base);
}
static cairo_status_t
gallium_surface_acquire_dest_image (void *abstract_surface,
cairo_rectangle_int_t *interest_rect,
cairo_image_surface_t **image_out,
cairo_rectangle_int_t *image_rect_out,
void **image_extra)
{
gallium_surface_t *surface = abstract_surface;
gallium_device_t *device;
cairo_surface_t *image;
cairo_format_t format;
cairo_status_t status;
void *ptr;
if (image_extra != NULL) {
gallium_device_t *device = gallium_device (abstract_surface);
assert (surface->fallback == NULL);
format = _cairo_format_from_pipe_format (surface->pipe_format);
if (format == CAIRO_FORMAT_INVALID)
return CAIRO_INT_STATUS_UNSUPPORTED;
device = gallium_device_acquire (surface->base.device);
ptr = pipe_buffer_map (device->screen, surface->buffer,
PIPE_BUFFER_USAGE_CPU_READ_WRITE);
gallium_device_release (device);
image = cairo_image_surface_create_for_data (ptr, format,
surface->base.width,
surface->base.height,
surface->base.stride);
if (unlikely (image->status))
return image->status;
status = _cairo_user_data_array_set_data (&image->user_data,
(cairo_user_data_key_t *) &surface->fallback,
surface,
gallium_surface_unmap);
if (unlikely (status)) {
cairo_surface_destroy (image);
return status;
device->pipe->transfer_unmap (device->pipe, image_extra);
device->pipe->transfer_destroy (device->pipe, image_extra);
}
surface->fallback = cairo_surface_reference (image);
*image_out = (cairo_image_surface_t *) image;
*image_extra = NULL;
image_rect_out->x = 0;
image_rect_out->y = 0;
image_rect_out->width = surface->base.width;
image_rect_out->height = surface->base.height;
return CAIRO_STATUS_SUCCESS;
}
static void
gallium_surface_release_dest_image (void *abstract_surface,
cairo_rectangle_int_t *interest_rect,
cairo_image_surface_t *image,
cairo_rectangle_int_t *image_rect,
void *image_extra)
{
/* Keep the fallback until we flush, either explicitly or at the
* end of this device. The idea is to avoid excess migration of
* the buffer between GPU and CPU domains.
*/
cairo_surface_destroy (&image->base);
}
static cairo_status_t
gallium_surface_flush (void *abstract_surface)
{
gallium_surface_t *surface = abstract_surface;
gallium_device_t *device;
gallium_device_t *device = gallium_device (surface);
cairo_status_t status;
if (surface->fallback == NULL)
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);
device = gallium_device_acquire (surface->base.device);
pipe_buffer_flush_mapped_range (device->screen,
surface->buffer,
0,
surface->base.stride * surface->base.height);
gallium_device_release (device);
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);
@ -353,6 +346,120 @@ gallium_surface_flush (void *abstract_surface)
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,
gallium_surface_create_similar,
@ -360,9 +467,9 @@ static const cairo_surface_backend_t gallium_surface_backend = {
gallium_surface_acquire_source_image,
gallium_surface_release_source_image,
gallium_surface_acquire_dest_image,
gallium_surface_release_dest_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,
@ -379,11 +486,11 @@ static const cairo_surface_backend_t gallium_surface_backend = {
NULL, //gallium_surface_scaled_font_fini,
NULL, //gallium_surface_scaled_glyph_fini,
_cairo_drm_surface_paint,
_cairo_drm_surface_mask,
_cairo_drm_surface_stroke,
_cairo_drm_surface_fill,
_cairo_drm_surface_show_glyphs,
gallium_surface_paint,
gallium_surface_mask,
gallium_surface_stroke,
gallium_surface_fill,
gallium_surface_glyphs,
NULL, /* snapshot */
@ -412,6 +519,8 @@ _gallium_fake_bo_create (uint32_t size, uint32_t name)
{
cairo_drm_bo_t *bo;
/* XXX integrate with winsys handle */
bo = malloc (sizeof (cairo_drm_bo_t));
CAIRO_REFERENCE_COUNT_INIT (&bo->ref_count, 1);
@ -430,38 +539,45 @@ _gallium_fake_bo_release (void *dev, void *bo)
static cairo_surface_t *
gallium_surface_create_internal (gallium_device_t *device,
cairo_content_t content,
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 = malloc (sizeof (gallium_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_surface_init (&surface->base.base,
format = _cairo_format_from_pipe_format (pipe_format);
_cairo_surface_init (&surface->drm.base,
&gallium_surface_backend,
content);
_cairo_drm_surface_init (&surface->base, &device->base);
&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->base.width = width;
surface->base.height = height;
surface->base.stride = stride;
surface->base.bo = _gallium_fake_bo_create (size, 0);
surface->drm.stride = stride;
surface->drm.bo = _gallium_fake_bo_create (size, 0);
surface->buffer = pipe_buffer_create (device->screen,
0,
PIPE_BUFFER_USAGE_GPU_READ_WRITE |
PIPE_BUFFER_USAGE_CPU_READ_WRITE,
size);
if (unlikely (surface->buffer == NULL)) {
status = _cairo_drm_surface_finish (&surface->base);
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));
}
@ -469,42 +585,43 @@ gallium_surface_create_internal (gallium_device_t *device,
surface->pipe_format = pipe_format;
surface->texture = NULL;
return &surface->base.base;
return &surface->drm.base;
}
static cairo_surface_t *
gallium_surface_create (cairo_drm_device_t *base_dev,
cairo_content_t content,
cairo_format_t format,
int width, int height)
{
gallium_device_t *device;
gallium_device_t *device = (gallium_device_t *) base_dev;
cairo_surface_t *surface;
enum pipe_format pipe_format;
cairo_status_t status;
device = gallium_device_acquire (base_dev);
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_content (content);
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,
content, pipe_format,
pipe_format,
width, height);
RELEASE:
gallium_device_release (device);
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,
@ -534,50 +651,53 @@ gallium_surface_create_for_name (cairo_drm_device_t *base_dev,
break;
}
device = gallium_device_acquire (base_dev);
status = cairo_device_acquire (&device->drm.base);
if (MAX (width, height) > device->max_size) {
gallium_device_release (device);
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)) {
gallium_device_release (device);
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->base.base,
_cairo_surface_init (&surface->drm.base,
&gallium_surface_backend,
content);
_cairo_drm_surface_init (&surface->base, base_dev);
_cairo_drm_surface_init (&surface->drm, base_dev);
surface->base.bo = _gallium_fake_bo_create (height * stride, name);
surface->drm.bo = _gallium_fake_bo_create (height * stride, name);
surface->base.width = width;
surface->base.height = height;
surface->base.stride = stride;
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->base);
gallium_device_release (device);
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;
gallium_device_release (device);
cairo_device_release (&device->drm.base);
return &surface->base.base;
return &surface->drm.base;
}
static cairo_int_status_t
@ -587,18 +707,19 @@ gallium_surface_flink (void *abstract_surface)
gallium_device_t *device;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
device = gallium_device_acquire (surface->base.device);
status = cairo_device_acquire (&device->drm.base);
if (! device->api->global_handle_from_buffer (device->api,
device->screen,
surface->buffer,
&surface->base.bo->name))
&surface->drm.bo->name))
{
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
gallium_device_release (device);
cairo_device_release (&device->drm.base);
return status;
}
#endif
static void
gallium_device_destroy (void *abstract_device)
@ -609,8 +730,6 @@ gallium_device_destroy (void *abstract_device)
device->screen->destroy (device->screen);
device->api->destroy (device->api);
CAIRO_MUTEX_FINI (device->mutex);
dlclose (device->dlhandle);
free (device);
}
@ -649,20 +768,18 @@ _cairo_drm_gallium_device_create (int fd, dev_t dev, int vendor_id, int chip_id)
device->dlhandle = handle;
CAIRO_MUTEX_INIT (device->mutex);
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->base.status = CAIRO_STATUS_SUCCESS;
device->drm.device.flush = NULL;
device->drm.device.throttle = NULL;
device->drm.device.destroy = gallium_device_destroy;
device->base.surface.create = gallium_surface_create;
device->base.surface.create_for_name = gallium_surface_create_for_name;
device->base.surface.enable_scan_out = NULL;
device->base.surface.flink = gallium_surface_flink;
device->base.device.flush = NULL;
device->base.device.throttle = NULL;
device->base.device.destroy = gallium_device_destroy;
device->base.bo.release = _gallium_fake_bo_release;
device->drm.bo.release = _gallium_fake_bo_release;
device->api = ctor ();
if (device->api == NULL) {
@ -679,13 +796,16 @@ _cairo_drm_gallium_device_create (int fd, dev_t dev, int vendor_id, int chip_id)
device->max_size = 1 << device->screen->get_param (device->screen,
PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
device->pipe = device->api->create_context (device->api, device->screen);
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->base, fd, dev, device->max_size);
return _cairo_drm_device_init (&device->drm,
fd, dev,
0, 0,
device->max_size);
CLEANUP_SCREEN:
device->screen->destroy (device->screen);