From 979337dd4da40abb2ea49968a2c01709d9046aab Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 28 Mar 2009 21:53:04 -0700 Subject: [PATCH] [gl] Wire blend factors using dst alpha to constants for CAIRO_CONTENT_COLOR. This fixes the operator and operator-alpha tests to rgb24 destinations. While we request an RGB texture, the returned texture has alpha bits, so when we blend against it as a renderbuffer, we get the junk alpha values. Whether or not this is a driver bug, we'll have this problem when we get visuals with alpha bits for windows despite not requestiong alpha, so we have to handle it in cairo. --- src/cairo-gl-surface.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index a36f4bb8f..5590e1b43 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -246,7 +246,7 @@ _cairo_gl_set_destination (cairo_gl_surface_t *surface) } static int -_cairo_gl_set_operator (cairo_operator_t op) +_cairo_gl_set_operator (cairo_gl_surface_t *dst, cairo_operator_t op) { struct { GLenum src; @@ -268,11 +268,25 @@ _cairo_gl_set_operator (cairo_operator_t op) { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Xor */ { GL_ONE, GL_ONE }, /* Add */ }; + GLenum src_factor, dst_factor; if (op >= ARRAY_SIZE (blend_factors)) return CAIRO_INT_STATUS_UNSUPPORTED; - glBlendFunc (blend_factors[op].src, blend_factors[op].dst); + src_factor = blend_factors[op].src; + dst_factor = blend_factors[op].dst; + + /* We may have a visual with alpha bits despite the user requesting + * CAIRO_CONTENT_COLOR. So clear out those bits in that case. + */ + if (dst->content == CAIRO_CONTENT_COLOR) { + if (src_factor == GL_ONE_MINUS_DST_ALPHA) + src_factor = GL_ZERO; + if (src_factor == GL_DST_ALPHA) + src_factor = GL_ONE; + } + + glBlendFunc (src_factor, dst_factor); return CAIRO_STATUS_SUCCESS; } @@ -1214,7 +1228,7 @@ _cairo_gl_surface_composite (cairo_operator_t op, ctx = _cairo_gl_context_acquire (dst->ctx); _cairo_gl_set_destination (dst); - status = _cairo_gl_set_operator (op); + status = _cairo_gl_set_operator (dst, op); if (status != CAIRO_STATUS_SUCCESS) { _cairo_gl_operand_destroy (&setup.src); if (mask != NULL) @@ -1409,7 +1423,7 @@ _cairo_gl_surface_fill_rectangles (void *abstract_surface, ctx = _cairo_gl_context_acquire (surface->ctx); _cairo_gl_set_destination (surface); - status = _cairo_gl_set_operator (op); + status = _cairo_gl_set_operator (surface, op); if (status != CAIRO_STATUS_SUCCESS) { _cairo_gl_context_release (ctx); return status;