gl: Port to cairo_device_t

This commit is contained in:
Chris Wilson 2010-01-18 23:37:11 +00:00
parent 3acd520c9d
commit ccea7fd7c1
7 changed files with 211 additions and 201 deletions

View file

@ -37,9 +37,10 @@
typedef struct _gl_target_closure {
Display *dpy;
int screen;
Window drawable;
GLXContext gl_ctx;
cairo_gl_context_t *ctx;
GLXContext ctx;
cairo_device_t *device;
cairo_surface_t *surface;
} gl_target_closure_t;
@ -48,9 +49,15 @@ _cairo_boilerplate_gl_cleanup (void *closure)
{
gl_target_closure_t *gltc = closure;
cairo_gl_context_destroy (gltc->ctx);
glXDestroyContext (gltc->dpy, gltc->gl_ctx);
cairo_device_finish (gltc->device);
cairo_device_destroy (gltc->device);
glXDestroyContext (gltc->dpy, gltc->ctx);
if (gltc->drawable)
XDestroyWindow (gltc->dpy, gltc->drawable);
XCloseDisplay (gltc->dpy);
free (gltc);
}
@ -79,12 +86,12 @@ _cairo_boilerplate_gl_create_surface (const char *name,
GLX_DOUBLEBUFFER,
None };
XVisualInfo *visinfo;
GLXContext gl_ctx;
GLXContext ctx;
gl_target_closure_t *gltc;
cairo_surface_t *surface;
Display *dpy;
gltc = malloc (sizeof (gl_target_closure_t));
gltc = calloc (1, sizeof (gl_target_closure_t));
*closure = gltc;
if (width == 0)
@ -115,13 +122,14 @@ _cairo_boilerplate_gl_create_surface (const char *name,
return NULL;
}
gl_ctx = glXCreateContext (dpy, visinfo, NULL, True);
ctx = glXCreateContext (dpy, visinfo, NULL, True);
XFree (visinfo);
gltc->gl_ctx = gl_ctx;
gltc->ctx = cairo_glx_context_create (dpy, gl_ctx);
gltc->ctx = ctx;
gltc->device = cairo_glx_device_create (dpy, ctx);
gltc->surface = surface = cairo_gl_surface_create (gltc->ctx, content,
gltc->surface = surface = cairo_gl_surface_create (gltc->device,
content,
ceil (width),
ceil (height));
if (cairo_surface_status (surface))

View file

@ -41,6 +41,7 @@
#include "cairo-gl-private.h"
#include "cairo-error-private.h"
#include <i915_drm.h> /* XXX dummy surface for glewInit() */
#include <sys/ioctl.h>
@ -129,19 +130,18 @@ _eagle_init (EGLDisplay display, EGLContext context)
eagleMakeCurrent (display, dummy, dummy, context);
}
cairo_gl_context_t *
cairo_device_t *
cairo_eagle_context_create (EGLDisplay display, EGLContext context)
{
cairo_eagle_context_t *ctx;
cairo_status_t status;
if (! _eagle_init (display, context)) {
return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
}
if (! _eagle_init (display, context))
return _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
ctx = calloc (1, sizeof (cairo_eagle_context_t));
if (ctx == NULL)
return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
ctx->display = display;
ctx->context = context;
@ -153,28 +153,31 @@ cairo_eagle_context_create (EGLDisplay display, EGLContext context)
status = _cairo_gl_context_init (&ctx->base);
if (status) {
free (ctx);
return _cairo_gl_context_create_in_error (status);
return _cairo_device_create_in_error (status);
}
return &ctx->base;
return &ctx->base.base;
}
cairo_surface_t *
cairo_gl_surface_create_for_eagle (cairo_gl_context_t *ctx,
cairo_gl_surface_create_for_eagle (cairo_device_t *device,
EGLSurface eagle,
int width,
int height)
{
cairo_eagle_surface_t *surface;
if (ctx->status)
return _cairo_surface_create_in_error (ctx->status);
if (unlikely (device->status))
return _cairo_surface_create_in_error (device->status);
if (unlikely (device->backend->type != CAIRO_DEVICE_TYPE_GL))
return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
surface = calloc (1, sizeof (cairo_eagle_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_gl_surface_init (ctx, &surface->base,
_cairo_gl_surface_init (device, &surface->base,
CAIRO_CONTENT_COLOR_ALPHA, width, height);
surface->eagle = eagle;

View file

@ -208,12 +208,12 @@ static cairo_bool_t
_cairo_gl_surface_owns_font (cairo_gl_surface_t *surface,
cairo_scaled_font_t *scaled_font)
{
cairo_gl_context_t *font_private;
cairo_device_t *font_private;
font_private = scaled_font->surface_private;
if ((scaled_font->surface_backend != NULL &&
scaled_font->surface_backend != &_cairo_gl_surface_backend) ||
(font_private != NULL && font_private != surface->ctx))
(font_private != NULL && font_private != surface->base.device))
{
return FALSE;
}
@ -448,7 +448,9 @@ _render_glyphs (cairo_gl_surface_t *dst,
if (unlikely (status))
return status;
ctx = _cairo_gl_context_acquire (dst->ctx);
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (unlikely (status))
return status;
_cairo_gl_set_destination (dst);
@ -619,31 +621,43 @@ _cairo_gl_surface_show_glyphs_via_mask (cairo_gl_surface_t *dst,
cairo_clip_t *clip,
int *remaining_glyphs)
{
cairo_gl_context_t *ctx;
cairo_surface_t *mask;
cairo_status_t status;
cairo_solid_pattern_t solid;
cairo_bool_t has_component_alpha;
int i;
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (unlikely (status))
return status;
/* XXX: For non-CA, this should be CAIRO_CONTENT_ALPHA to save memory */
if (dst->ctx->glyphs_temporary_mask) {
if (glyph_extents->width <= dst->ctx->glyphs_temporary_mask->width &&
glyph_extents->height <= dst->ctx->glyphs_temporary_mask->height)
if (ctx->glyphs_temporary_mask) {
if (glyph_extents->width <= ctx->glyphs_temporary_mask->width &&
glyph_extents->height <= ctx->glyphs_temporary_mask->height)
{
_cairo_gl_surface_clear (dst->ctx->glyphs_temporary_mask);
mask = &dst->ctx->glyphs_temporary_mask->base;
status = _cairo_gl_surface_clear (ctx->glyphs_temporary_mask);
if (unlikely (status)) {
_cairo_gl_context_release (ctx);
return status;
}
mask = &ctx->glyphs_temporary_mask->base;
} else {
cairo_surface_destroy (&dst->ctx->glyphs_temporary_mask->base);
dst->ctx->glyphs_temporary_mask = NULL;
cairo_surface_destroy (&ctx->glyphs_temporary_mask->base);
ctx->glyphs_temporary_mask = NULL;
}
}
if (!mask) {
mask = cairo_gl_surface_create (dst->ctx,
if (mask == NULL) {
mask = cairo_gl_surface_create (dst->base.device,
CAIRO_CONTENT_COLOR_ALPHA,
glyph_extents->width,
glyph_extents->height);
if (unlikely (mask->status))
if (unlikely (mask->status)) {
_cairo_gl_context_release (ctx);
return mask->status;
}
}
for (i = 0; i < num_glyphs; i++) {
@ -676,8 +690,10 @@ _cairo_gl_surface_show_glyphs_via_mask (cairo_gl_surface_t *dst,
*remaining_glyphs = num_glyphs;
}
if (!dst->ctx->glyphs_temporary_mask)
dst->ctx->glyphs_temporary_mask = (cairo_gl_surface_t *)mask;
if (ctx->glyphs_temporary_mask == NULL)
ctx->glyphs_temporary_mask = (cairo_gl_surface_t *) mask;
_cairo_gl_context_release (ctx);
return status;
}

View file

@ -40,6 +40,7 @@
#define CAIRO_GL_PRIVATE_H
#include "cairoint.h"
#include "cairo-device-private.h"
#include "cairo-rtree-private.h"
#include <GL/glew.h>
@ -66,7 +67,6 @@
typedef struct _cairo_gl_surface {
cairo_surface_t base;
cairo_gl_context_t *ctx;
int width, height;
GLuint tex; /* GL texture object containing our data. */
@ -79,11 +79,9 @@ typedef struct cairo_gl_glyph_cache {
unsigned int width, height;
} cairo_gl_glyph_cache_t;
struct _cairo_gl_context {
cairo_reference_count_t ref_count;
cairo_status_t status;
typedef struct _cairo_gl_context {
cairo_device_t base;
cairo_mutex_t mutex; /* needed? */
GLuint dummy_tex;
GLint fill_rectangles_shader;
GLint fill_rectangles_color_uniform;
@ -97,7 +95,7 @@ struct _cairo_gl_context {
void (*make_current)(void *ctx, cairo_gl_surface_t *surface);
void (*swap_buffers)(void *ctx, cairo_gl_surface_t *surface);
void (*destroy) (void *ctx);
};
} cairo_gl_context_t;
enum cairo_gl_composite_operand_type {
OPERAND_CONSTANT,
@ -130,14 +128,17 @@ typedef struct _cairo_gl_composite_setup {
cairo_private extern const cairo_surface_backend_t _cairo_gl_surface_backend;
cairo_private cairo_gl_context_t *
_cairo_gl_context_create_in_error (cairo_status_t status);
static inline cairo_device_t *
_cairo_gl_context_create_in_error (cairo_status_t status)
{
return (cairo_device_t *) _cairo_device_create_in_error (status);
}
cairo_private cairo_status_t
_cairo_gl_context_init (cairo_gl_context_t *ctx);
cairo_private void
_cairo_gl_surface_init (cairo_gl_context_t *ctx,
_cairo_gl_surface_init (cairo_device_t *device,
cairo_gl_surface_t *surface,
cairo_content_t content,
int width, int height);
@ -157,11 +158,26 @@ _cairo_gl_operand_init (cairo_gl_composite_operand_t *operand,
int dst_x, int dst_y,
int width, int height);
cairo_private cairo_gl_context_t *
_cairo_gl_context_acquire (cairo_gl_context_t *ctx);
static inline cairo_status_t cairo_warn
_cairo_gl_context_acquire (cairo_device_t *device,
cairo_gl_context_t **ctx)
{
cairo_status_t status;
status = cairo_device_acquire (device);
if (unlikely (status))
return status;
*ctx = (cairo_gl_context_t *) device;
return CAIRO_STATUS_SUCCESS;
}
static inline void
_cairo_gl_context_release (cairo_gl_context_t *ctx)
{
cairo_device_release (&ctx->base);
}
cairo_private void
_cairo_gl_context_release (cairo_gl_context_t *ctx);
cairo_private void
_cairo_gl_set_destination (cairo_gl_surface_t *surface);
@ -169,7 +185,7 @@ _cairo_gl_set_destination (cairo_gl_surface_t *surface);
cairo_private cairo_bool_t
_cairo_gl_operator_is_supported (cairo_operator_t op);
cairo_private void
cairo_private cairo_status_t
_cairo_gl_surface_clear (cairo_gl_surface_t *surface);
cairo_private void

View file

@ -40,9 +40,6 @@
#include "cairo-error-private.h"
#include "cairo-gl-private.h"
slim_hidden_proto (cairo_gl_context_reference);
slim_hidden_proto (cairo_gl_context_destroy);
static cairo_int_status_t
_cairo_gl_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
@ -64,42 +61,36 @@ int_as_float (uint32_t val)
return fi.f;
}
static const cairo_gl_context_t _nil_context = {
CAIRO_REFERENCE_COUNT_INVALID,
CAIRO_STATUS_NO_MEMORY
};
static const cairo_gl_context_t _nil_context__invalid_format = {
CAIRO_REFERENCE_COUNT_INVALID,
CAIRO_STATUS_INVALID_FORMAT
};
static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface)
{
return surface->backend == &_cairo_gl_surface_backend;
}
cairo_gl_context_t *
_cairo_gl_context_create_in_error (cairo_status_t status)
static void
_gl_destroy (void *device)
{
if (status == CAIRO_STATUS_NO_MEMORY)
return (cairo_gl_context_t *) &_nil_context;
cairo_gl_context_t *ctx = device;
if (status == CAIRO_STATUS_INVALID_FORMAT)
return (cairo_gl_context_t *) &_nil_context__invalid_format;
ASSERT_NOT_REACHED;
return NULL;
ctx->destroy (ctx);
free (ctx);
}
static const cairo_device_backend_t _cairo_gl_device_backend = {
CAIRO_DEVICE_TYPE_GL,
NULL, NULL, /* lock, unlock */
NULL, /* flush */
NULL, /* finish */
_gl_destroy,
};
cairo_status_t
_cairo_gl_context_init (cairo_gl_context_t *ctx)
{
int n;
ctx->status = CAIRO_STATUS_SUCCESS;
CAIRO_REFERENCE_COUNT_INIT (&ctx->ref_count, 1);
CAIRO_MUTEX_INIT (ctx->mutex);
_cairo_device_init (&ctx->base, &_cairo_gl_device_backend);
memset (ctx->glyph_cache, 0, sizeof (ctx->glyph_cache));
@ -139,57 +130,6 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
return CAIRO_STATUS_SUCCESS;
}
cairo_gl_context_t *
cairo_gl_context_reference (cairo_gl_context_t *context)
{
if (context == NULL ||
CAIRO_REFERENCE_COUNT_IS_INVALID (&context->ref_count))
{
return context;
}
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&context->ref_count));
_cairo_reference_count_inc (&context->ref_count);
return context;
}
slim_hidden_def (cairo_gl_context_reference);
void
cairo_gl_context_destroy (cairo_gl_context_t *context)
{
int n;
if (context == NULL ||
CAIRO_REFERENCE_COUNT_IS_INVALID (&context->ref_count))
{
return;
}
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&context->ref_count));
if (! _cairo_reference_count_dec_and_test (&context->ref_count))
return;
glDeleteTextures (1, &context->dummy_tex);
for (n = 0; n < ARRAY_LENGTH (context->glyph_cache); n++)
_cairo_gl_glyph_cache_fini (&context->glyph_cache[n]);
context->destroy (context);
cairo_surface_destroy (&context->glyphs_temporary_mask->base);
free (context);
}
slim_hidden_def (cairo_gl_context_destroy);
cairo_gl_context_t *
_cairo_gl_context_acquire (cairo_gl_context_t *ctx)
{
CAIRO_MUTEX_LOCK (ctx->mutex);
return ctx;
}
cairo_bool_t
_cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
GLenum *internal_format, GLenum *format,
@ -313,16 +253,10 @@ _cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
}
}
void
_cairo_gl_context_release (cairo_gl_context_t *ctx)
{
CAIRO_MUTEX_UNLOCK (ctx->mutex);
}
void
_cairo_gl_set_destination (cairo_gl_surface_t *surface)
{
cairo_gl_context_t *ctx = surface->ctx;
cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->base.device;
if (ctx->current_target != surface) {
ctx->current_target = surface;
@ -455,17 +389,16 @@ _cairo_gl_set_texture_surface (int tex_unit, GLuint tex,
}
void
_cairo_gl_surface_init (cairo_gl_context_t *ctx,
_cairo_gl_surface_init (cairo_device_t *device,
cairo_gl_surface_t *surface,
cairo_content_t content,
int width, int height)
{
_cairo_surface_init (&surface->base,
&_cairo_gl_surface_backend,
NULL, /* device */
device,
content);
surface->ctx = cairo_gl_context_reference (ctx);
surface->width = width;
surface->height = height;
}
@ -480,8 +413,8 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
GLenum err, format;
cairo_status_t status;
if (ctx->status)
return _cairo_surface_create_in_error (ctx->status);
if (ctx->base.status)
return _cairo_surface_create_in_error (ctx->base.status);
assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
@ -489,7 +422,7 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_gl_surface_init (ctx, surface, content, width, height);
_cairo_gl_surface_init (&ctx->base, surface, content, width, height);
switch (content) {
default:
@ -545,12 +478,16 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
return &surface->base;
}
void
cairo_status_t
_cairo_gl_surface_clear (cairo_gl_surface_t *surface)
{
cairo_gl_context_t *ctx;
cairo_status_t status;
status = _cairo_gl_context_acquire (surface->base.device, &ctx);
if (unlikely (status))
return status;
ctx = _cairo_gl_context_acquire (surface->ctx);
_cairo_gl_set_destination (surface);
if (surface->base.content == CAIRO_CONTENT_COLOR)
glClearColor (0.0, 0.0, 0.0, 1.0);
@ -561,17 +498,20 @@ _cairo_gl_surface_clear (cairo_gl_surface_t *surface)
surface->base.is_clear = TRUE;
return CAIRO_STATUS_SUCCESS;
}
cairo_surface_t *
cairo_gl_surface_create (cairo_gl_context_t *ctx,
cairo_content_t content,
int width,
int height)
cairo_gl_surface_create (cairo_device_t *abstract_device,
cairo_content_t content,
int width,
int height)
{
cairo_gl_context_t *ctx = (cairo_gl_context_t *) abstract_device;
cairo_gl_surface_t *surface;
cairo_status_t status;
if (!CAIRO_CONTENT_VALID (content))
if (! CAIRO_CONTENT_VALID (content))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
if (ctx == NULL) {
@ -579,13 +519,20 @@ cairo_gl_surface_create (cairo_gl_context_t *ctx,
width, height);
}
if (ctx->base.backend->type != CAIRO_DEVICE_TYPE_GL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
surface = (cairo_gl_surface_t *)
_cairo_gl_surface_create_scratch (ctx, content, width, height);
if (unlikely (surface->base.status))
return &surface->base;
/* Cairo surfaces start out initialized to transparent (black) */
_cairo_gl_surface_clear (surface);
status = _cairo_gl_surface_clear (surface);
if (unlikely (status)) {
cairo_surface_destroy (&surface->base);
return _cairo_surface_create_in_error (status);
}
return &surface->base;
}
@ -631,7 +578,6 @@ cairo_gl_surface_get_height (cairo_surface_t *abstract_surface)
return surface->height;
}
void
cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
{
@ -644,8 +590,10 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
return;
}
if (! surface->fb)
surface->ctx->swap_buffers (surface->ctx, surface);
if (! surface->fb) {
cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->base.device;
ctx->swap_buffers (ctx, surface);
}
}
static cairo_surface_t *
@ -655,11 +603,12 @@ _cairo_gl_surface_create_similar (void *abstract_surface,
int height)
{
cairo_gl_surface_t *surface = abstract_surface;
cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->base.device;
assert (CAIRO_CONTENT_VALID (content));
if (width > surface->ctx->max_framebuffer_size ||
height > surface->ctx->max_framebuffer_size)
if (width > ctx->max_framebuffer_size ||
height > ctx->max_framebuffer_size)
{
return NULL;
}
@ -669,7 +618,7 @@ _cairo_gl_surface_create_similar (void *abstract_surface,
if (height < 1)
height = 1;
return _cairo_gl_surface_create_scratch (surface->ctx, content, width, height);
return _cairo_gl_surface_create_scratch (ctx, content, width, height);
}
cairo_status_t
@ -685,10 +634,10 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
int cpp;
if (! _cairo_gl_get_image_format_and_type (src->pixman_format,
&internal_format,
&format,
&type,
&has_alpha))
&internal_format,
&format,
&type,
&has_alpha))
{
cairo_bool_t is_supported;
@ -815,14 +764,13 @@ static cairo_status_t
_cairo_gl_surface_finish (void *abstract_surface)
{
cairo_gl_surface_t *surface = abstract_surface;
cairo_gl_context_t *ctx = (cairo_gl_context_t *) surface->base.device;
glDeleteFramebuffersEXT (1, &surface->fb);
glDeleteTextures (1, &surface->tex);
if (surface->ctx->current_target == surface)
surface->ctx->current_target = NULL;
cairo_gl_context_destroy (surface->ctx);
if (ctx->current_target == surface)
ctx->current_target = NULL;
return CAIRO_STATUS_SUCCESS;
}
@ -1418,7 +1366,13 @@ _cairo_gl_surface_composite_component_alpha (cairo_operator_t op,
}
mask_attributes = &setup.mask.operand.texture.attributes;
ctx = _cairo_gl_context_acquire (dst->ctx);
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (unlikely (status)) {
_cairo_gl_operand_destroy (&setup.src);
_cairo_gl_operand_destroy (&setup.mask);
return status;
}
_cairo_gl_set_destination (dst);
if (clip_region != NULL) {
@ -1610,7 +1564,10 @@ _cairo_gl_surface_composite (cairo_operator_t op,
mask_attributes = &setup.mask.operand.texture.attributes;
}
ctx = _cairo_gl_context_acquire (dst->ctx);
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (unlikely (status))
goto CLEANUP_SHADER;
_cairo_gl_set_destination (dst);
_cairo_gl_set_operator (dst, op, FALSE);
@ -1748,6 +1705,7 @@ _cairo_gl_surface_composite (cairo_operator_t op,
CONTEXT_RELEASE:
_cairo_gl_context_release (ctx);
CLEANUP_SHADER:
_cairo_gl_operand_destroy (&setup.src);
if (mask != NULL)
_cairo_gl_operand_destroy (&setup.mask);
@ -1827,11 +1785,14 @@ _cairo_gl_surface_fill_rectangles_fixed (void *abstract_surface,
int i;
GLfloat *vertices;
GLfloat *colors;
cairo_status_t status;
if (! _cairo_gl_operator_is_supported (op))
return UNSUPPORTED ("unsupported operator");
ctx = _cairo_gl_context_acquire (surface->ctx);
status = _cairo_gl_context_acquire (surface->base.device, &ctx);
if (unlikely (status))
return status;
_cairo_gl_set_destination (surface);
_cairo_gl_set_operator (surface, op, FALSE);
@ -1926,13 +1887,17 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
if (! _cairo_gl_operator_is_supported (op))
return UNSUPPORTED ("unsupported operator");
ctx = _cairo_gl_context_acquire (surface->ctx);
status = _cairo_gl_context_acquire (surface->base.device, &ctx);
if (unlikely (status))
return status;
if (ctx->fill_rectangles_shader == 0) {
status = _cairo_gl_load_glsl (&ctx->fill_rectangles_shader,
fill_vs_source, fill_fs_source);
if (_cairo_status_is_error (status))
if (_cairo_status_is_error (status)) {
_cairo_gl_context_release (ctx);
return status;
}
ctx->fill_rectangles_color_uniform =
glGetUniformLocationARB (ctx->fill_rectangles_shader, "color");
@ -2020,6 +1985,7 @@ typedef struct _cairo_gl_surface_span_renderer {
cairo_antialias_t antialias;
cairo_gl_surface_t *dst;
cairo_gl_context_t *ctx;
cairo_region_t *clip;
cairo_composite_rectangles_t composite_rectangles;
@ -2218,7 +2184,7 @@ _cairo_gl_surface_span_renderer_destroy (void *abstract_renderer)
return;
_cairo_gl_operand_destroy (&renderer->setup.src);
_cairo_gl_context_release (renderer->dst->ctx);
_cairo_gl_context_release (renderer->ctx);
free (renderer);
}
@ -2303,23 +2269,30 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
rects->dst.x, rects->dst.y,
width, height);
if (unlikely (status)) {
_cairo_gl_context_acquire (dst->ctx);
cairo_status_t status_ignored;
status_ignored = _cairo_gl_context_acquire (dst->base.device, &renderer->ctx);
_cairo_gl_surface_span_renderer_destroy (renderer);
return _cairo_span_renderer_create_in_error (status);
}
_cairo_gl_context_acquire (dst->ctx);
status = _cairo_gl_context_acquire (dst->base.device, &renderer->ctx);
if (unlikely (status)) {
_cairo_gl_surface_span_renderer_destroy (renderer);
return _cairo_span_renderer_create_in_error (status);
}
_cairo_gl_set_destination (dst);
src_attributes = &renderer->setup.src.operand.texture.attributes;
_cairo_gl_set_operator (dst, op, FALSE);
_cairo_gl_set_src_operand (dst->ctx, &renderer->setup);
_cairo_gl_set_src_operand (renderer->ctx, &renderer->setup);
/* Set up the mask to source from the incoming vertex color. */
glActiveTexture (GL_TEXTURE1);
/* Have to have a dummy texture bound in order to use the combiner unit. */
glBindTexture (GL_TEXTURE_2D, dst->ctx->dummy_tex);
glBindTexture (GL_TEXTURE_2D, renderer->ctx->dummy_tex);
glEnable (GL_TEXTURE_2D);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
@ -2372,11 +2345,8 @@ _cairo_gl_surface_paint (void *abstract_surface,
cairo_clip_t *clip)
{
/* simplify the common case of clearing the surface */
if (op == CAIRO_OPERATOR_CLEAR && clip == NULL) {
_cairo_gl_surface_clear (abstract_surface);
return CAIRO_STATUS_SUCCESS;
}
if (op == CAIRO_OPERATOR_CLEAR && clip == NULL)
return _cairo_gl_surface_clear (abstract_surface);
return CAIRO_INT_STATUS_UNSUPPORTED;
}

View file

@ -40,16 +40,8 @@
CAIRO_BEGIN_DECLS
typedef struct _cairo_gl_context cairo_gl_context_t;
cairo_public cairo_gl_context_t *
cairo_gl_context_reference (cairo_gl_context_t *context);
cairo_public void
cairo_gl_context_destroy (cairo_gl_context_t *context);
cairo_public cairo_surface_t *
cairo_gl_surface_create (cairo_gl_context_t *ctx,
cairo_gl_surface_create (cairo_device_t *device,
cairo_content_t content,
int width, int height);
@ -71,11 +63,11 @@ cairo_gl_surface_glfinish (cairo_surface_t *surface);
#if CAIRO_HAS_GLX_FUNCTIONS
#include <GL/glx.h>
cairo_public cairo_gl_context_t *
cairo_glx_context_create (Display *dpy, GLXContext gl_ctx);
cairo_public cairo_device_t *
cairo_glx_device_create (Display *dpy, GLXContext gl_ctx);
cairo_public cairo_surface_t *
cairo_gl_surface_create_for_window (cairo_gl_context_t *ctx,
cairo_gl_surface_create_for_window (cairo_device_t *device,
Window win,
int width, int height);
#endif
@ -83,11 +75,11 @@ cairo_gl_surface_create_for_window (cairo_gl_context_t *ctx,
#if CAIRO_HAS_EAGLE_FUNCTIONS
#include <eagle.h>
cairo_public cairo_gl_context_t *
cairo_eagle_context_create (EGLDisplay display, EGLContext context);
cairo_public cairo_device_t *
cairo_eagle_device_create (EGLDisplay display, EGLContext context);
cairo_public cairo_surface_t *
cairo_gl_surface_create_for_eagle (cairo_gl_context_t *ctx,
cairo_gl_surface_create_for_eagle (cairo_device_t *device,
EGLSurface surface,
int width, int height);
#endif

View file

@ -88,6 +88,8 @@ _glx_destroy (void *abstract_ctx)
if (ctx->dummy_window != None)
XDestroyWindow (ctx->display, ctx->dummy_window);
glXMakeCurrent (ctx->display, 0, 0);
}
static cairo_status_t
@ -142,8 +144,8 @@ _glx_dummy_ctx (Display *dpy, GLXContext gl_ctx, Window *dummy)
return CAIRO_STATUS_SUCCESS;
}
cairo_gl_context_t *
cairo_glx_context_create (Display *dpy, GLXContext gl_ctx)
cairo_device_t *
cairo_glx_device_create (Display *dpy, GLXContext gl_ctx)
{
cairo_glx_context_t *ctx;
cairo_status_t status;
@ -171,25 +173,28 @@ cairo_glx_context_create (Display *dpy, GLXContext gl_ctx)
return _cairo_gl_context_create_in_error (status);
}
return &ctx->base;
return &ctx->base.base;
}
cairo_surface_t *
cairo_gl_surface_create_for_window (cairo_gl_context_t *ctx,
Window win,
int width,
int height)
cairo_gl_surface_create_for_window (cairo_device_t *device,
Window win,
int width,
int height)
{
cairo_glx_surface_t *surface;
if (unlikely (ctx->status))
return _cairo_surface_create_in_error (ctx->status);
if (unlikely (device->status))
return _cairo_surface_create_in_error (device->status);
if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
surface = calloc (1, sizeof (cairo_glx_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
_cairo_gl_surface_init (ctx, &surface->base,
_cairo_gl_surface_init (device, &surface->base,
CAIRO_CONTENT_COLOR_ALPHA, width, height);
surface->win = win;