diff --git a/ChangeLog b/ChangeLog index c3aeb0ecd..8b6b5191b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-07-04 David Reveman + + * configure.in: Require glitz >= 0.4.4. + + * src/cairo-glitz-surface.c: Use frame buffer objects instead of + pbuffers for accelerated offscreen drawing. + (_cairo_glitz_pattern_acquire_surface): Minor improvement to gradient + pattern creation. + 2005-07-01 Kristian Høgsberg * src/cairo-ps-surface.c: Rewrite postscript backend to generate diff --git a/configure.in b/configure.in index 8fca1e403..af4e25db1 100644 --- a/configure.in +++ b/configure.in @@ -215,7 +215,7 @@ AC_ARG_ENABLE(glitz, [use_glitz=$enableval], [use_glitz=yes]) if test "x$use_glitz" = "xyes"; then - PKG_CHECK_MODULES(GLITZ, glitz >= 0.4.0, [ + PKG_CHECK_MODULES(GLITZ, glitz >= 0.4.4, [ GLITZ_REQUIRES=glitz use_glitz=yes], [use_glitz="no (requires glitz http://freedesktop.org/Software/glitz)"]) fi diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index ce9da259b..962d0c641 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -440,73 +440,18 @@ _glitz_operator (cairo_operator_t op) return CAIRO_OPERATOR_XOR; } +#define CAIRO_GLITZ_FEATURE_OK(surface, name) \ + (glitz_drawable_get_features (glitz_surface_get_drawable (surface)) & \ + (GLITZ_FEATURE_ ## name ## _MASK)) + static glitz_status_t _glitz_ensure_target (glitz_surface_t *surface) { - glitz_drawable_t *drawable; + if (glitz_surface_get_attached_drawable (surface) || + CAIRO_GLITZ_FEATURE_OK (surface, FRAMEBUFFER_OBJECT)) + return CAIRO_STATUS_SUCCESS; - drawable = glitz_surface_get_attached_drawable (surface); - if (!drawable) { - glitz_drawable_format_t *dformat; - glitz_drawable_format_t templ; - glitz_format_t *format; - glitz_drawable_t *pbuffer; - unsigned long mask; - int i; - - format = glitz_surface_get_format (surface); - if (format->type != GLITZ_FORMAT_TYPE_COLOR) - return CAIRO_INT_STATUS_UNSUPPORTED; - - drawable = glitz_surface_get_drawable (surface); - dformat = glitz_drawable_get_format (drawable); - - templ.types.pbuffer = 1; - mask = GLITZ_FORMAT_PBUFFER_MASK; - - templ.samples = dformat->samples; - mask |= GLITZ_FORMAT_SAMPLES_MASK; - - i = 0; - do { - dformat = glitz_find_similar_drawable_format (drawable, - mask, &templ, i++); - - if (dformat) { - int sufficient = 1; - - if (format->color.red_size) { - if (dformat->color.red_size < format->color.red_size) - sufficient = 0; - } - if (format->color.alpha_size) { - if (dformat->color.alpha_size < format->color.alpha_size) - sufficient = 0; - } - - if (sufficient) - break; - } - } while (dformat); - - if (!dformat) - return CAIRO_INT_STATUS_UNSUPPORTED; - - pbuffer = - glitz_create_pbuffer_drawable (drawable, dformat, - glitz_surface_get_width (surface), - glitz_surface_get_height (surface)); - if (!pbuffer) - return CAIRO_INT_STATUS_UNSUPPORTED; - - glitz_surface_attach (surface, pbuffer, - GLITZ_DRAWABLE_BUFFER_FRONT_COLOR, - 0, 0); - - glitz_drawable_destroy (pbuffer); - } - - return CAIRO_STATUS_SUCCESS; + return CAIRO_INT_STATUS_UNSUPPORTED; } typedef struct _cairo_glitz_surface_attributes { @@ -536,13 +481,26 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern, switch (pattern->type) { case CAIRO_PATTERN_LINEAR: case CAIRO_PATTERN_RADIAL: { - cairo_gradient_pattern_t *gradient = + cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern; - glitz_drawable_t *drawable; - glitz_fixed16_16_t *params; - int n_params; - int i; - unsigned short alpha; + char *data; + glitz_fixed16_16_t *params; + int n_params; + unsigned int *pixels; + int i; + unsigned char alpha; + glitz_buffer_t *buffer; + static glitz_pixel_format_t format = { + { + 32, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }; /* XXX: the current color gradient acceleration provided by glitz is * experimental, it's been proven inappropriate in a number of ways, @@ -565,22 +523,20 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern, break; } - drawable = glitz_surface_get_drawable (dst->surface); - if (!(glitz_drawable_get_features (drawable) & - GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK)) + if (!CAIRO_GLITZ_FEATURE_OK (dst->surface, FRAGMENT_PROGRAM)) break; - + if (pattern->filter != CAIRO_FILTER_BILINEAR && pattern->filter != CAIRO_FILTER_GOOD && pattern->filter != CAIRO_FILTER_BEST) break; - alpha = (gradient->stops[0].color.alpha) * 0xffff; + alpha = gradient->stops[0].color.alpha * 0xff; for (i = 1; i < gradient->n_stops; i++) { - unsigned short a; + unsigned char a; - a = (gradient->stops[i].color.alpha) * 0xffff; + a = gradient->stops[i].color.alpha * 0xff; if (a != alpha) break; } @@ -592,35 +548,51 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern, n_params = gradient->n_stops * 3 + 4; - params = malloc (sizeof (glitz_fixed16_16_t) * n_params); - if (!params) + data = malloc (sizeof (glitz_fixed16_16_t) * n_params + + sizeof (unsigned int) * gradient->n_stops); + if (!data) return CAIRO_STATUS_NO_MEMORY; + params = (glitz_fixed16_16_t *) data; + pixels = (unsigned int *) + (data + sizeof (glitz_fixed16_16_t) * n_params); + + buffer = glitz_buffer_create_for_data (pixels); + if (!buffer) + { + free (data); + return CAIRO_STATUS_NO_MEMORY; + } + src = (cairo_glitz_surface_t *) _cairo_surface_create_similar_scratch (&dst->base, CAIRO_FORMAT_ARGB32, gradient->n_stops, 1); if (!src) { - free (params); + glitz_buffer_destroy (buffer); + free (data); return CAIRO_STATUS_NO_MEMORY; } - for (i = 0; i < gradient->n_stops; i++) { - glitz_color_t color; - - color.red = gradient->stops[i].color.red * alpha; - color.green = gradient->stops[i].color.green * alpha; - color.blue = gradient->stops[i].color.blue * alpha; - color.alpha = alpha; - - glitz_set_rectangle (src->surface, &color, i, 0, 1, 1); - + for (i = 0; i < gradient->n_stops; i++) + { + pixels[i] = + (((int) alpha) << 24) | + (((int) gradient->stops[i].color.red * alpha) << 16) | + (((int) gradient->stops[i].color.green * alpha) << 8) | + (((int) gradient->stops[i].color.blue * alpha)); + params[4 + 3 * i] = gradient->stops[i].offset; params[5 + 3 * i] = i << 16; params[6 + 3 * i] = 0; } + glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1, + &format, buffer); + + glitz_buffer_destroy (buffer); + if (pattern->type == CAIRO_PATTERN_LINEAR) { cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern; @@ -910,10 +882,6 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, glitz_color.blue = color->blue_short; glitz_color.alpha = color->alpha_short; - if (glitz_surface_get_width (dst->surface) != 1 || - glitz_surface_get_height (dst->surface) != 1) - _glitz_ensure_target (dst->surface); - glitz_set_rectangles (dst->surface, &glitz_color, (glitz_rectangle_t *) rects, n_rects); } @@ -1452,7 +1420,7 @@ _cairo_glitz_area_find (cairo_glitz_area_t *area, width, height, kick_out, closure); if (status == CAIRO_STATUS_SUCCESS) - return CAIRO_STATUS_SUCCESS; + return CAIRO_STATUS_SUCCESS; } } break; case CAIRO_GLITZ_AREA_DIVIDED: {