From ad398d9bda70a1e49edf126bd8576edf63b4b7a6 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Mon, 21 Jun 2004 15:13:52 +0000 Subject: [PATCH] Glitz updates and a minor clipping fix --- ChangeLog | 16 ++++ configure.in | 2 +- src/cairo-gstate.c | 26 ++++--- src/cairo_gl_surface.c | 161 ++++++++++++++++++++++++++--------------- src/cairo_gstate.c | 26 ++++--- 5 files changed, 155 insertions(+), 76 deletions(-) diff --git a/ChangeLog b/ChangeLog index c06ff8c77..111257e77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2004-06-21 David Reveman + + * configure.in: Require glitz >= 0.1.5. + + * src/cairo_gstate.c (_cairo_gstate_clip_and_composite_trapezoids): + Use correct source offset when creating clip surface. + + * src/cairo_gl_surface.c (_cairo_gl_surface_get_image): Use glitz's + new pixel interface. + (_cairo_gl_surface_set_image): Use glitz's new pixel interface. + (_cairo_gl_surface_create_similar): First try to create a drawable + surface and if that fails, create a read only surface. + (_cairo_gl_surface_create_similar): Glitz now handles inheritance of + anti-aliasing hints, so it can be removed from here. + (_cairo_gl_surface_create_pattern): Temporary fix for gradients. + 2004-06-16 Keith Packard * src/cairo_xcb_surface.c: (bytes_per_line), diff --git a/configure.in b/configure.in index 929eeafc9..5ab37391a 100644 --- a/configure.in +++ b/configure.in @@ -141,7 +141,7 @@ AC_ARG_ENABLE(gl, [use_gl=$enableval], [use_gl=yes]) if test "x$use_gl" = "xyes"; then - PKG_CHECK_MODULES(GL, glitz >= 0.1.4, [ + PKG_CHECK_MODULES(GL, glitz >= 0.1.5, [ GL_REQUIRES=glitz use_gl=yes], [use_gl="no (requires glitz http://freedesktop.org/software/glitz)"]) fi diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 98a6f161c..cad3b15e1 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1362,6 +1362,7 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, cairo_status_t status; cairo_pattern_t pattern; cairo_box_t extents; + int x_src, y_src; if (traps->num_traps == 0) return CAIRO_STATUS_SUCCESS; @@ -1404,6 +1405,14 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, t->right.p2.y -= yoff; } + if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) { + x_src = _cairo_fixed_to_double (traps->traps[0].left.p1.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p1.y); + } else { + x_src = _cairo_fixed_to_double (traps->traps[0].left.p2.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p2.y); + } + _cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0); _cairo_pattern_set_alpha (&pattern, 1.0); @@ -1414,7 +1423,8 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD, pattern.source, intermediate, - 0, 0, + x_src, + y_src, traps->traps, traps->num_traps); if (status) @@ -1465,14 +1475,12 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, return status; } else { - int xoff, yoff; - if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) { - xoff = _cairo_fixed_to_double (traps->traps[0].left.p1.x); - yoff = _cairo_fixed_to_double (traps->traps[0].left.p1.y); + x_src = _cairo_fixed_to_double (traps->traps[0].left.p1.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p1.y); } else { - xoff = _cairo_fixed_to_double (traps->traps[0].left.p2.x); - yoff = _cairo_fixed_to_double (traps->traps[0].left.p2.y); + x_src = _cairo_fixed_to_double (traps->traps[0].left.p2.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p2.y); } _cairo_pattern_init_copy (&pattern, src); @@ -1484,8 +1492,8 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, status = _cairo_surface_composite_trapezoids (gstate->operator, pattern.source, dst, - xoff - pattern.source_offset.x, - yoff - pattern.source_offset.y, + x_src - pattern.source_offset.x, + y_src - pattern.source_offset.y, traps->traps, traps->num_traps); diff --git a/src/cairo_gl_surface.c b/src/cairo_gl_surface.c index 55132b4e6..00e15d9c2 100644 --- a/src/cairo_gl_surface.c +++ b/src/cairo_gl_surface.c @@ -132,6 +132,7 @@ _cairo_gl_surface_get_image (void *abstract_surface) int width, height; int rowstride; cairo_format_masks_t format; + glitz_pixel_format_t pf; if (surface->hints & GLITZ_HINT_PROGRAMMATIC_MASK) return _cairo_pattern_get_image (&surface->pattern, @@ -140,23 +141,49 @@ _cairo_gl_surface_get_image (void *abstract_surface) width = glitz_surface_get_width (surface->surface); height = glitz_surface_get_height (surface->surface); - rowstride = (width * (surface->format->bpp / 8) + 3) & -4; + if (surface->format->red_size > 0) { + format.bpp = 32; + + if (surface->format->alpha_size > 0) + format.alpha_mask = 0xff000000; + else + format.alpha_mask = 0x0; + + format.red_mask = 0xff0000; + format.green_mask = 0xff00; + format.blue_mask = 0xff; + } else { + format.bpp = 8; + format.blue_mask = format.green_mask = format.red_mask = 0x0; + format.alpha_mask = 0xff; + } - pixels = (char *) malloc (sizeof (char) * height * rowstride); + rowstride = (((width * format.bpp) / 8) + 3) & -4; - glitz_surface_read_pixels (surface->surface, 0, 0, width, height, pixels); - - format.bpp = surface->format->bpp; - format.red_mask = surface->format->red_mask; - format.green_mask = surface->format->green_mask; - format.blue_mask = surface->format->blue_mask; - format.alpha_mask = surface->format->alpha_mask; + pf.masks.bpp = format.bpp; + pf.masks.alpha_mask = format.alpha_mask; + pf.masks.red_mask = format.red_mask; + pf.masks.green_mask = format.green_mask; + pf.masks.blue_mask = format.blue_mask; + pf.xoffset = 0; + pf.bytes_per_line = rowstride; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + pixels = (char *) malloc (height * rowstride); + if (!pixels) + return NULL; + + glitz_get_pixels (surface->surface, + 0, 0, + width, height, + &pf, + pixels); + image = (cairo_image_surface_t *) _cairo_image_surface_create_with_masks (pixels, &format, width, height, rowstride); - + _cairo_image_surface_assume_ownership_of_data (image); _cairo_image_surface_set_repeat (image, surface->base.repeat); @@ -170,10 +197,35 @@ _cairo_gl_surface_set_image (void *abstract_surface, cairo_image_surface_t *image) { cairo_gl_surface_t *surface = abstract_surface; + glitz_pixel_format_t pf; - glitz_surface_draw_pixels (surface->surface, 0, 0, - image->width, image->height, image->data); + if (image->depth > 8) { + pf.masks.bpp = 32; + + if (surface->format->alpha_size) + pf.masks.alpha_mask = 0xff000000; + else + pf.masks.alpha_mask = 0x0; + + pf.masks.red_mask = 0xff0000; + pf.masks.green_mask = 0xff00; + pf.masks.blue_mask = 0xff; + } else { + pf.masks.bpp = 8; + pf.masks.alpha_mask = 0xff; + pf.masks.red_mask = pf.masks.green_mask = pf.masks.blue_mask = 0x0; + } + pf.xoffset = 0; + pf.bytes_per_line = (((image->width * pf.masks.bpp) / 8) + 3) & -4; + pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + + glitz_put_pixels (surface->surface, + 0, 0, + image->width, image->height, + &pf, + image->data); + return CAIRO_STATUS_SUCCESS; } @@ -208,9 +260,9 @@ _cairo_gl_surface_set_filter (void *abstract_surface, cairo_filter_t filter) { static glitz_convolution_t gaussian = { { - {0, 1 << 16, 0}, - {1 << 16, 4 << 16, 1 << 16}, - {0, 1 << 16, 0} + { 0, 1 << 16, 0 }, + { 1 << 16, 4 << 16, 1 << 16 }, + { 0, 1 << 16, 0 } } }; cairo_gl_surface_t *surface = abstract_surface; @@ -332,9 +384,13 @@ _cairo_gl_surface_create_similar (void *abstract_src, cairo_surface_t *crsurface; glitz_format_t *glitz_format; unsigned long option_mask; + glitz_format_name_t format_name = _glitz_format (format); option_mask = GLITZ_FORMAT_OPTION_OFFSCREEN_MASK; - if (!drawable) + + if (drawable) + option_mask |= GLITZ_FORMAT_OPTION_READDRAW_MASK; + else option_mask |= GLITZ_FORMAT_OPTION_READONLY_MASK; if (src->format->multisample.samples < 2) @@ -342,7 +398,15 @@ _cairo_gl_surface_create_similar (void *abstract_src, glitz_format = glitz_surface_find_similar_standard_format (src->surface, option_mask, - _glitz_format (format)); + format_name); + if (glitz_format == NULL) { + option_mask &= ~GLITZ_FORMAT_OPTION_READDRAW_MASK; + glitz_format = + glitz_surface_find_similar_standard_format (src->surface, + option_mask, + format_name); + } + if (glitz_format == NULL) return NULL; @@ -351,12 +415,6 @@ _cairo_gl_surface_create_similar (void *abstract_src, if (surface == NULL) return NULL; - src->hints = glitz_surface_get_hints (src->surface); - if ((!CAIRO_GL_SURFACE_MULTISAMPLE (src)) && - (src->format->multisample.samples < 2)) { - glitz_surface_set_polyedge (surface, GLITZ_POLYEDGE_SHARP); - } - crsurface = _cairo_gl_surface_create (surface, 1); if (crsurface == NULL) glitz_surface_destroy (surface); @@ -637,17 +695,6 @@ _cairo_gl_surface_show_page (void *abstract_surface) return CAIRO_INT_STATUS_UNSUPPORTED; } -static void -_cario_gl_uint_to_power_of_two (unsigned int *value) -{ - unsigned int x = 1; - - while (x < *value) - x <<= 1; - - *value = x; -} - static void _cairo_gl_create_color_range (cairo_pattern_t *pattern, unsigned char *data, @@ -684,10 +731,17 @@ _cairo_gl_surface_create_pattern (void *abstract_surface, source = glitz_surface_create_solid (&color); } break; - case CAIRO_PATTERN_LINEAR: - case CAIRO_PATTERN_RADIAL: { - unsigned int color_range_size; + case CAIRO_PATTERN_RADIAL: + /* glitz doesn't support inner circle yet. */ + if (pattern->u.radial.center0.x != pattern->u.radial.center1.x || + pattern->u.radial.center0.y != pattern->u.radial.center1.y) + return CAIRO_INT_STATUS_UNSUPPORTED; + /* fall-through */ + case CAIRO_PATTERN_LINEAR: { + int color_range_size; glitz_color_range_t *color_range; + int width = ((box->p2.x + 65535) >> 16) - (box->p1.x >> 16); + int height = ((box->p2.y + 65535) >> 16) - (box->p1.y >> 16); if (!CAIRO_GL_FRAGMENT_PROGRAM_SUPPORT (surface)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -698,26 +752,17 @@ _cairo_gl_surface_create_pattern (void *abstract_surface, if (pattern->extend == CAIRO_EXTEND_REFLECT && (!CAIRO_GL_TEXTURE_MIRRORED_REPEAT_SUPPORT (surface))) return CAIRO_INT_STATUS_UNSUPPORTED; + + /* TODO: how do we figure out the color range resolution? transforming + the gradient vector with the inverse of the pattern matrix should + give us a good hint. */ + color_range_size = 512; - if (pattern->type == CAIRO_PATTERN_LINEAR) { - double dx, dy; - - dx = pattern->u.linear.point1.x - pattern->u.linear.point0.x; - dy = pattern->u.linear.point1.y - pattern->u.linear.point0.y; - - color_range_size = sqrt (dx * dx + dy * dy); - } else { - /* glitz doesn't support inner circle yet. */ - if (pattern->u.radial.center0.x != pattern->u.radial.center1.x || - pattern->u.radial.center0.y != pattern->u.radial.center1.y) - return CAIRO_INT_STATUS_UNSUPPORTED; - - color_range_size = pattern->u.radial.radius1; - } - - if ((!CAIRO_GL_TEXTURE_NPOT_SUPPORT (surface))) - _cario_gl_uint_to_power_of_two (&color_range_size); - + /* destination surface size less than color range size, an image + gradient is probably more efficient. */ + if ((width * height) <= color_range_size) + return CAIRO_INT_STATUS_UNSUPPORTED; + color_range = glitz_color_range_create (color_range_size); if (!color_range) return CAIRO_STATUS_NO_MEMORY; @@ -725,7 +770,9 @@ _cairo_gl_surface_create_pattern (void *abstract_surface, _cairo_gl_create_color_range (pattern, glitz_color_range_get_data (color_range), color_range_size); - + + glitz_color_range_put_back_data (color_range); + switch (pattern->extend) { case CAIRO_EXTEND_REPEAT: glitz_color_range_set_extend (color_range, GLITZ_EXTEND_REPEAT); diff --git a/src/cairo_gstate.c b/src/cairo_gstate.c index 98a6f161c..cad3b15e1 100644 --- a/src/cairo_gstate.c +++ b/src/cairo_gstate.c @@ -1362,6 +1362,7 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, cairo_status_t status; cairo_pattern_t pattern; cairo_box_t extents; + int x_src, y_src; if (traps->num_traps == 0) return CAIRO_STATUS_SUCCESS; @@ -1404,6 +1405,14 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, t->right.p2.y -= yoff; } + if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) { + x_src = _cairo_fixed_to_double (traps->traps[0].left.p1.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p1.y); + } else { + x_src = _cairo_fixed_to_double (traps->traps[0].left.p2.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p2.y); + } + _cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0); _cairo_pattern_set_alpha (&pattern, 1.0); @@ -1414,7 +1423,8 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD, pattern.source, intermediate, - 0, 0, + x_src, + y_src, traps->traps, traps->num_traps); if (status) @@ -1465,14 +1475,12 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, return status; } else { - int xoff, yoff; - if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) { - xoff = _cairo_fixed_to_double (traps->traps[0].left.p1.x); - yoff = _cairo_fixed_to_double (traps->traps[0].left.p1.y); + x_src = _cairo_fixed_to_double (traps->traps[0].left.p1.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p1.y); } else { - xoff = _cairo_fixed_to_double (traps->traps[0].left.p2.x); - yoff = _cairo_fixed_to_double (traps->traps[0].left.p2.y); + x_src = _cairo_fixed_to_double (traps->traps[0].left.p2.x); + y_src = _cairo_fixed_to_double (traps->traps[0].left.p2.y); } _cairo_pattern_init_copy (&pattern, src); @@ -1484,8 +1492,8 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, status = _cairo_surface_composite_trapezoids (gstate->operator, pattern.source, dst, - xoff - pattern.source_offset.x, - yoff - pattern.source_offset.y, + x_src - pattern.source_offset.x, + y_src - pattern.source_offset.y, traps->traps, traps->num_traps);