mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-01 12:37:58 +02:00
gl: Port to cairo_device_t
This commit is contained in:
parent
3acd520c9d
commit
ccea7fd7c1
7 changed files with 211 additions and 201 deletions
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue