Ejemplo n.º 1
0
static pixman_bool_t
do_check (int i)
{
    pixman_image_t *source, *dest, *mask;
    pixman_op_t op;
    int x, y, width, height;
    pixman_image_t *dest_copy;
    pixman_bool_t result = TRUE;
    pixman_bool_t component_alpha;

    prng_srand (i);
    op = RANDOM_ELT (operators);
    x = prng_rand_n (MAX_WIDTH);
    y = prng_rand_n (MAX_HEIGHT);
    width = prng_rand_n (MAX_WIDTH) + 4;
    height = prng_rand_n (MAX_HEIGHT) + 4;

    source = create_image (NULL);
    mask = create_image (NULL);
    dest = create_image (&dest_copy);

    if (x >= dest->bits.width)
        x = dest->bits.width / 2;
    if (y >= dest->bits.height)
        y = dest->bits.height / 2;
    if (x + width > dest->bits.width)
        width = dest->bits.width - x;
    if (y + height > dest->bits.height)
        height = dest->bits.height - y;

    component_alpha = prng_rand_n (2);

    pixman_image_set_component_alpha (mask, component_alpha);
    
    pixman_image_composite32 (op, source, mask, dest,
                              0, 0, 0, 0,
                              x, y, width, height);

    if (!verify (i, op, source, mask, dest, dest_copy,
		 x, y, width, height, component_alpha))
    {
	result = FALSE;
    }
    
    pixman_image_unref (source);
    pixman_image_unref (mask);
    pixman_image_unref (dest);
    pixman_image_unref (dest_copy);

    return result;
}
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int testnum, int verbose)
{
    int i;
    pixman_image_t *src_img = NULL;
    pixman_image_t *dst_img = NULL;
    pixman_image_t *mask_img = NULL;
    int src_width, src_height;
    int dst_width, dst_height;
    int src_stride, dst_stride;
    int src_x, src_y;
    int dst_x, dst_y;
    int mask_x, mask_y;
    int w, h;
    pixman_op_t op;
    pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
    uint32_t *dstbuf, *srcbuf, *maskbuf;
    uint32_t crc32;
    int max_width, max_height, max_extra_stride;
    FLOAT_REGS_CORRUPTION_DETECTOR_START ();

    max_width = max_height = 24 + testnum / 10000;
    max_extra_stride = 4 + testnum / 1000000;

    if (max_width > 256)
	max_width = 256;

    if (max_height > 16)
	max_height = 16;

    if (max_extra_stride > 8)
	max_extra_stride = 8;

    lcg_srand (testnum);

    op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];

    if (lcg_rand_n (8))
    {
	/* normal image */
	src_img = create_random_image (img_fmt_list, max_width, max_height,
				       max_extra_stride, &src_fmt);
    }
    else
    {
	/* solid case */
	src_img = create_random_image (img_fmt_list, 1, 1,
				       max_extra_stride, &src_fmt);

	pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
    }

    dst_img = create_random_image (img_fmt_list, max_width, max_height,
				   max_extra_stride, &dst_fmt);

    src_width = pixman_image_get_width (src_img);
    src_height = pixman_image_get_height (src_img);
    src_stride = pixman_image_get_stride (src_img);

    dst_width = pixman_image_get_width (dst_img);
    dst_height = pixman_image_get_height (dst_img);
    dst_stride = pixman_image_get_stride (dst_img);

    dstbuf = pixman_image_get_data (dst_img);
    srcbuf = pixman_image_get_data (src_img);

    src_x = lcg_rand_n (src_width);
    src_y = lcg_rand_n (src_height);
    dst_x = lcg_rand_n (dst_width);
    dst_y = lcg_rand_n (dst_height);

    mask_img = NULL;
    mask_fmt = PIXMAN_null;
    mask_x = 0;
    mask_y = 0;
    maskbuf = NULL;

    if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
	(lcg_rand_n (4) == 0))
    {
	/* PIXBUF */
	mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
	mask_img = pixman_image_create_bits (mask_fmt,
	                                     src_width,
	                                     src_height,
	                                     srcbuf,
	                                     src_stride);
	mask_x = src_x;
	mask_y = src_y;
	maskbuf = srcbuf;
    }
    else if (lcg_rand_n (2))
    {
	if (lcg_rand_n (2))
	{
	    mask_img = create_random_image (mask_fmt_list, max_width, max_height,
					   max_extra_stride, &mask_fmt);
	}
	else
	{
	    /* solid case */
	    mask_img = create_random_image (mask_fmt_list, 1, 1,
					   max_extra_stride, &mask_fmt);
	    pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
	}

	if (lcg_rand_n (2))
	    pixman_image_set_component_alpha (mask_img, 1);

	mask_x = lcg_rand_n (pixman_image_get_width (mask_img));
	mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
    }


    w = lcg_rand_n (dst_width - dst_x + 1);
    h = lcg_rand_n (dst_height - dst_y + 1);

    if (verbose)
    {
	printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
	    op, src_fmt, dst_fmt, mask_fmt);
	printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
	    src_width, src_height, dst_width, dst_height);
	printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
	    src_x, src_y, dst_x, dst_y);
	printf ("src_stride=%d, dst_stride=%d\n",
	    src_stride, dst_stride);
	printf ("w=%d, h=%d\n", w, h);
    }

    pixman_image_composite (op, src_img, mask_img, dst_img,
			    src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);

    if (verbose)
    {
	int j;

	printf ("---\n");
	for (i = 0; i < dst_height; i++)
	{
	    for (j = 0; j < dst_stride; j++)
	    {
		if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
		    printf ("| ");

		printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
	    }
	    printf ("\n");
	}
	printf ("---\n");
    }

    free_random_image (0, src_img, PIXMAN_null);
    crc32 = free_random_image (0, dst_img, dst_fmt);

    if (mask_img)
    {
	if (srcbuf == maskbuf)
	    pixman_image_unref(mask_img);
	else
	    free_random_image (0, mask_img, PIXMAN_null);
    }

    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    return crc32;
}
Ejemplo n.º 3
0
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int testnum, int verbose)
{
    pixman_image_t *src_img = NULL;
    pixman_image_t *dst_img = NULL;
    pixman_image_t *mask_img = NULL;
    int src_width, src_height;
    int dst_width, dst_height;
    int src_stride, dst_stride;
    int src_x, src_y;
    int dst_x, dst_y;
    int mask_x, mask_y;
    int w, h;
    pixman_op_t op;
    pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
    uint32_t *srcbuf, *maskbuf;
    uint32_t crc32;
    int max_width, max_height, max_extra_stride;
    FLOAT_REGS_CORRUPTION_DETECTOR_START ();

    max_width = max_height = 24 + testnum / 10000;
    max_extra_stride = 4 + testnum / 1000000;

    if (max_width > 256)
	max_width = 256;

    if (max_height > 16)
	max_height = 16;

    if (max_extra_stride > 8)
	max_extra_stride = 8;

    prng_srand (testnum);

    op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))];

    if (prng_rand_n (8))
    {
	/* normal image */
	src_img = create_random_image (img_fmt_list, max_width, max_height,
				       max_extra_stride, &src_fmt);
    }
    else
    {
	/* solid case */
	src_img = create_random_image (img_fmt_list, 1, 1,
				       max_extra_stride, &src_fmt);

	pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
    }

    dst_img = create_random_image (img_fmt_list, max_width, max_height,
				   max_extra_stride, &dst_fmt);

    src_width = pixman_image_get_width (src_img);
    src_height = pixman_image_get_height (src_img);
    src_stride = pixman_image_get_stride (src_img);

    dst_width = pixman_image_get_width (dst_img);
    dst_height = pixman_image_get_height (dst_img);
    dst_stride = pixman_image_get_stride (dst_img);

    srcbuf = pixman_image_get_data (src_img);

    src_x = prng_rand_n (src_width);
    src_y = prng_rand_n (src_height);
    dst_x = prng_rand_n (dst_width);
    dst_y = prng_rand_n (dst_height);

    mask_img = NULL;
    mask_fmt = PIXMAN_null;
    mask_x = 0;
    mask_y = 0;
    maskbuf = NULL;

    if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
	(prng_rand_n (4) == 0))
    {
	/* PIXBUF */
	mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
	mask_img = pixman_image_create_bits (mask_fmt,
	                                     src_width,
	                                     src_height,
	                                     srcbuf,
	                                     src_stride);
	mask_x = src_x;
	mask_y = src_y;
	maskbuf = srcbuf;
    }
    else if (prng_rand_n (2))
    {
	if (prng_rand_n (2))
	{
	    mask_img = create_random_image (mask_fmt_list, max_width, max_height,
					   max_extra_stride, &mask_fmt);
	}
	else
	{
	    /* solid case */
	    mask_img = create_random_image (mask_fmt_list, 1, 1,
					   max_extra_stride, &mask_fmt);
	    pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
	}

	if (prng_rand_n (2))
	    pixman_image_set_component_alpha (mask_img, 1);

	mask_x = prng_rand_n (pixman_image_get_width (mask_img));
	mask_y = prng_rand_n (pixman_image_get_height (mask_img));
    }


    w = prng_rand_n (dst_width - dst_x + 1);
    h = prng_rand_n (dst_height - dst_y + 1);

    if (verbose)
    {
        printf ("op=%s\n", operator_name (op));
	printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n",
	    format_name (src_fmt), format_name (dst_fmt),
	    format_name (mask_fmt));
	printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
	    src_width, src_height, dst_width, dst_height);
	printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
	    src_x, src_y, dst_x, dst_y);
	printf ("src_stride=%d, dst_stride=%d\n",
	    src_stride, dst_stride);
	printf ("w=%d, h=%d\n", w, h);
    }

    pixman_image_composite (op, src_img, mask_img, dst_img,
			    src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);

    if (verbose)
	print_image (dst_img);

    free_random_image (0, src_img, PIXMAN_null);
    crc32 = free_random_image (0, dst_img, dst_fmt);

    if (mask_img)
    {
	if (srcbuf == maskbuf)
	    pixman_image_unref(mask_img);
	else
	    free_random_image (0, mask_img, PIXMAN_null);
    }

    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    return crc32;
}
Ejemplo n.º 4
0
cairo_warn cairo_int_status_t
_cairo_dwrite_scaled_show_glyphs(void			*scaled_font,
				 cairo_operator_t	 op,
				 const cairo_pattern_t	*pattern,
				 cairo_surface_t	*generic_surface,
				 int			 source_x,
				 int			 source_y,
				 int			 dest_x,
				 int			 dest_y,
				 unsigned int		 width,
				 unsigned int		 height,
				 cairo_glyph_t		*glyphs,
				 int			 num_glyphs,
				 cairo_region_t		*clip_region,
				 int			*remaining_glyphs)
{
    cairo_win32_surface_t *surface = (cairo_win32_surface_t *)generic_surface;
    cairo_int_status_t status;

    if (width == 0 || height == 0)
	return (cairo_int_status_t)CAIRO_STATUS_SUCCESS;

    if (_cairo_surface_is_win32 (generic_surface) &&
	surface->format == CAIRO_FORMAT_RGB24 &&
	op == CAIRO_OPERATOR_OVER) {

	    //XXX: we need to set the clip region here

	status = (cairo_int_status_t)_cairo_dwrite_show_glyphs_on_surface (surface, op, pattern,
									  glyphs, num_glyphs, 
									  (cairo_scaled_font_t*)scaled_font, NULL);

	return status;
    } else {
	cairo_dwrite_scaled_font_t *dwritesf =
	    static_cast<cairo_dwrite_scaled_font_t*>(scaled_font);
	UINT16 *indices = new UINT16[num_glyphs];
	DWRITE_GLYPH_OFFSET *offsets = new DWRITE_GLYPH_OFFSET[num_glyphs];
	FLOAT *advances = new FLOAT[num_glyphs];
	BOOL transform = FALSE;

	DWRITE_GLYPH_RUN run;
	run.bidiLevel = 0;
	run.fontFace = ((cairo_dwrite_font_face_t*)dwritesf->base.font_face)->dwriteface;
	run.glyphIndices = indices;
	run.glyphCount = num_glyphs;
	run.isSideways = FALSE;
	run.glyphOffsets = offsets;
	run.glyphAdvances = advances;
    	IDWriteGlyphRunAnalysis *analysis;

	if (dwritesf->mat.xy == 0 && dwritesf->mat.yx == 0 &&
	    dwritesf->mat.xx == dwritesf->base.font_matrix.xx && 
	    dwritesf->mat.yy == dwritesf->base.font_matrix.yy) {

	    for (int i = 0; i < num_glyphs; i++) {
		indices[i] = (WORD) glyphs[i].index;
		// Since we will multiply by our ctm matrix later for rotation effects
		// and such, adjust positions by the inverse matrix now.
		offsets[i].ascenderOffset = (FLOAT)dest_y - (FLOAT)glyphs[i].y;
		offsets[i].advanceOffset = (FLOAT)glyphs[i].x - dest_x;
		advances[i] = 0.0;
	    }
	    run.fontEmSize = (FLOAT)dwritesf->base.font_matrix.yy;
	} else {
	    transform = TRUE;

	    for (int i = 0; i < num_glyphs; i++) {
		indices[i] = (WORD) glyphs[i].index;
		double x = glyphs[i].x - dest_x;
		double y = glyphs[i].y - dest_y;
		cairo_matrix_transform_point(&dwritesf->mat_inverse, &x, &y);
		// Since we will multiply by our ctm matrix later for rotation effects
		// and such, adjust positions by the inverse matrix now.
		offsets[i].ascenderOffset = -(FLOAT)y;
		offsets[i].advanceOffset = (FLOAT)x;
		advances[i] = 0.0;
	    }
	    run.fontEmSize = 1.0f;
	}

	if (!transform) {
	    DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
							      1.0f,
							      NULL,
							      DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
							      DWRITE_MEASURING_MODE_NATURAL,
							      0,
							      0,
							      &analysis);
	} else {
	    DWRITE_MATRIX dwmatrix = _cairo_dwrite_matrix_from_matrix(&dwritesf->mat);
	    DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
							      1.0f,
							      &dwmatrix,
							      DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
							      DWRITE_MEASURING_MODE_NATURAL,
							      0,
							      0,
							      &analysis);
	}

	RECT r;
	r.left = 0;
	r.top = 0;
	r.right = width;
	r.bottom = height;

	BYTE *surface = new BYTE[width * height * 3];

	analysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1, &r, surface, width * height * 3);

	cairo_image_surface_t *mask_surface = 
	    (cairo_image_surface_t*)cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);

	cairo_surface_flush(&mask_surface->base);

	for (unsigned int y = 0; y < height; y++) {
	    for (unsigned int x = 0; x < width; x++) {
		mask_surface->data[y * mask_surface->stride + x * 4] = surface[y * width * 3 + x * 3 + 1];
		mask_surface->data[y * mask_surface->stride + x * 4 + 1] = surface[y * width * 3 + x * 3 + 1];
		mask_surface->data[y * mask_surface->stride + x * 4 + 2] = surface[y * width * 3 + x * 3 + 1];
		mask_surface->data[y * mask_surface->stride + x * 4 + 3] = surface[y * width * 3 + x * 3 + 1];
	    }
	}
	cairo_surface_mark_dirty(&mask_surface->base);

	pixman_image_set_component_alpha(mask_surface->pixman_image, 1);

	cairo_surface_pattern_t mask;
	_cairo_pattern_init_for_surface (&mask, &mask_surface->base);

	status = (cairo_int_status_t)_cairo_surface_composite (op, pattern,
							       &mask.base,
							       generic_surface,
							       source_x, source_y,
							       0, 0,
							       dest_x, dest_y,
							       width, height,
							       clip_region);

	_cairo_pattern_fini (&mask.base);

	analysis->Release();
	delete [] surface;
	delete [] indices;
	delete [] offsets;
	delete [] advances;

	cairo_surface_destroy (&mask_surface->base);
	*remaining_glyphs = 0;

	return (cairo_int_status_t)CAIRO_STATUS_SUCCESS;
    }
}
Ejemplo n.º 5
0
cairo_status_t
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t    *scaled_font,
				cairo_operator_t        op,
				cairo_pattern_t        *pattern,
				cairo_surface_t        *surface,
				int                     source_x,
				int                     source_y,
				int			dest_x,
				int			dest_y,
				unsigned int		width,
				unsigned int		height,
				const cairo_glyph_t    *glyphs,
				int                     num_glyphs)
{
    cairo_status_t status;
    cairo_surface_t *mask = NULL;
    int i;

    /* These operators aren't interpreted the same way by the backends;
     * they are implemented in terms of other operators in cairo-gstate.c
     */
    assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
    
    if (scaled_font->status)
	return scaled_font->status;

    if (scaled_font->backend->show_glyphs != NULL) {
	status = scaled_font->backend->show_glyphs (scaled_font,
						    op, pattern, 
						    surface,
						    source_x, source_y,
						    dest_x, dest_y,
						    width, height,
						    glyphs, num_glyphs);
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	    return status;
    }

    /* Font display routine either does not exist or failed. */
    
    status = CAIRO_STATUS_SUCCESS;

    _cairo_cache_freeze (scaled_font->glyphs);

    for (i = 0; i < num_glyphs; i++) {
	int x, y;
	cairo_surface_pattern_t glyph_pattern;
	cairo_image_surface_t *glyph_surface;
	cairo_scaled_glyph_t *scaled_glyph;
	
	status = _cairo_scaled_glyph_lookup (scaled_font,
					     glyphs[i].index,
					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
					     &scaled_glyph);

	if (status)
	    goto CLEANUP_MASK;
	
	glyph_surface = scaled_glyph->surface;

	/* Create the mask using the format from the first glyph */
	if (mask == NULL) {
	    mask = cairo_image_surface_create (glyph_surface->format,
					       width, height);
	    if (mask->status) {
		status = mask->status;
		goto CLEANUP_MASK;
	    }

	    status = _cairo_surface_fill_rectangle (mask,
						    CAIRO_OPERATOR_CLEAR,
						    CAIRO_COLOR_TRANSPARENT,
						    0, 0,
						    width, height);
	    if (status)
		goto CLEANUP_MASK;
	    if (glyph_surface->format == CAIRO_FORMAT_ARGB32)
		pixman_image_set_component_alpha (((cairo_image_surface_t*) mask)->
						  pixman_image, TRUE);

	}
	
	/* round glyph locations to the nearest pixel */
	x = (int) floor (glyphs[i].x + 
			 glyph_surface->base.device_x_offset +
			 0.5);
	y = (int) floor (glyphs[i].y +
			 glyph_surface->base.device_y_offset +
			 0.5);
	
	_cairo_pattern_init_for_surface (&glyph_pattern, &glyph_surface->base);

	status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, 
					   &glyph_pattern.base, 
					   NULL,
					   mask,
					   0, 0,
					   0, 0, 
					   x - dest_x, 
					   y - dest_y, 
					   glyph_surface->width,
					   glyph_surface->height);

	_cairo_pattern_fini (&glyph_pattern.base);
	if (status)
	    break;
    }
    
    if (mask != NULL) {
	cairo_surface_pattern_t mask_pattern;

	_cairo_pattern_init_for_surface (&mask_pattern, mask);
    
	status = _cairo_surface_composite (op, pattern, &mask_pattern.base,
					   surface,
					   source_x, source_y, 
					   0,        0,
					   dest_x,   dest_y,
					   width,    height);
    
	_cairo_pattern_fini (&mask_pattern.base);
    }
	
CLEANUP_MASK:
    _cairo_cache_thaw (scaled_font->glyphs);
    
    if (mask != NULL)
	cairo_surface_destroy (mask);
    return status;
}
Ejemplo n.º 6
0
static void
set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip,
                     int *xoff, int *yoff, Bool is_alpha_map)
{
    pixman_repeat_t repeat;
    pixman_filter_t filter;

    if (pict->transform) {
        /* For source images, adjust the transform to account
         * for the drawable offset within the pixman image,
         * then set the offset to 0 as it will be used
         * to compute positions within the transformed image.
         */
        if (!has_clip) {
            struct pixman_transform adjusted;

            adjusted = *pict->transform;
            pixman_transform_translate(&adjusted,
                                       NULL,
                                       pixman_int_to_fixed(*xoff),
                                       pixman_int_to_fixed(*yoff));
            pixman_image_set_transform(image, &adjusted);
            *xoff = 0;
            *yoff = 0;
        }
        else
            pixman_image_set_transform(image, pict->transform);
    }

    switch (pict->repeatType) {
    default:
    case RepeatNone:
        repeat = PIXMAN_REPEAT_NONE;
        break;

    case RepeatPad:
        repeat = PIXMAN_REPEAT_PAD;
        break;

    case RepeatNormal:
        repeat = PIXMAN_REPEAT_NORMAL;
        break;

    case RepeatReflect:
        repeat = PIXMAN_REPEAT_REFLECT;
        break;
    }

    pixman_image_set_repeat(image, repeat);

    /* Fetch alpha map unless 'pict' is being used
     * as the alpha map for this operation
     */
    if (pict->alphaMap && !is_alpha_map) {
        int alpha_xoff, alpha_yoff;
        pixman_image_t *alpha_map =
            image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff,
                                     &alpha_yoff, TRUE);

        pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x,
                                   pict->alphaOrigin.y);

        free_pixman_pict(pict->alphaMap, alpha_map);
    }

    pixman_image_set_component_alpha(image, pict->componentAlpha);

    switch (pict->filter) {
    default:
    case PictFilterNearest:
    case PictFilterFast:
        filter = PIXMAN_FILTER_NEAREST;
        break;

    case PictFilterBilinear:
    case PictFilterGood:
        filter = PIXMAN_FILTER_BILINEAR;
        break;

    case PictFilterConvolution:
        filter = PIXMAN_FILTER_CONVOLUTION;
        break;
    }

    if (pict->pDrawable)
        pixman_image_set_destroy_function(image, &image_destroy,
                                          pict->pDrawable);

    pixman_image_set_filter(image, filter,
                            (pixman_fixed_t *) pict->filter_params,
                            pict->filter_nparams);
    pixman_image_set_source_clipping(image, TRUE);
}
Ejemplo n.º 7
0
int
main (int argc, char *argv[])
{
    bench_info_t         binfo;
    pixman_filter_t      filter      = PIXMAN_FILTER_NEAREST;
    pixman_format_code_t src_format  = PIXMAN_a8r8g8b8;
    pixman_format_code_t mask_format = 0;
    pixman_format_code_t dest_format = PIXMAN_a8r8g8b8;
    pixman_box32_t       dest_box    = { 0, 0, WIDTH, HEIGHT };
    box_48_16_t          transformed = { 0 };
    int32_t xmin, ymin, xmax, ymax;
    uint32_t *src, *mask, *dest;

    binfo.op         = PIXMAN_OP_SRC;
    binfo.mask_image = NULL;
    pixman_transform_init_identity (&binfo.transform);

    ++argv;
    if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'n')
    {
        filter = PIXMAN_FILTER_NEAREST;
        ++argv;
        --argc;
    }

    if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'b')
    {
        filter = PIXMAN_FILTER_BILINEAR;
        ++argv;
        --argc;
    }

    if (argc == 1 ||
        !parse_arguments (argc, argv, &binfo.transform, &binfo.op,
                          &src_format, &mask_format, &dest_format))
    {
        printf ("Usage: affine-bench [-n] [-b] axx [axy] [ayx] [ayy] [combine type]\n");
        printf ("                    [src format] [mask format] [dest format]\n");
        printf ("  -n : nearest scaling (default)\n");
        printf ("  -b : bilinear scaling\n");
        printf ("  axx : x_out:x_in factor\n");
        printf ("  axy : x_out:y_in factor (default 0)\n");
        printf ("  ayx : y_out:x_in factor (default 0)\n");
        printf ("  ayy : y_out:y_in factor (default 1)\n");
        printf ("  combine type : src, over, in etc (default src)\n");
        printf ("  src format : a8r8g8b8, r5g6b5 etc (default a8r8g8b8)\n");
        printf ("  mask format : as for src format, but no mask used if omitted\n");
        printf ("  dest format : as for src format (default a8r8g8b8)\n");
        printf ("The output is a single number in megapixels/second.\n");

        return EXIT_FAILURE;
    }

    /* Compute required extents for source and mask image so they qualify
     * for COVER fast paths and get the flags in pixman.c:analyze_extent().
     * These computations are for FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR,
     * but at the same time they also allow COVER_CLIP_NEAREST.
     */
    compute_transformed_extents (&binfo.transform, &dest_box, &transformed);
    xmin = pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2);
    ymin = pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2);
    xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2);
    ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2);
    /* Note:
     * The upper limits can be reduced to the following when fetchers
     * are guaranteed to not access pixels with zero weight. This concerns
     * particularly all bilinear samplers.
     *
     * xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2 - pixman_fixed_e);
     * ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2 - pixman_fixed_e);
     * This is equivalent to subtracting 0.5 and rounding up, rather than
     * subtracting 0.5, rounding down and adding 1.
     */
    binfo.src_x = -xmin;
    binfo.src_y = -ymin;

    /* Always over-allocate width by 64 pixels for all src, mask and dst,
     * so that we can iterate over an x-offset 0..63 in bench ().
     * This is similar to lowlevel-blt-bench, which uses the same method
     * to hit different cacheline misalignments.
     */
    create_image (xmax - xmin + 64, ymax - ymin + 1, src_format, filter,
                  &src, &binfo.src_image);

    if (mask_format)
    {
        create_image (xmax - xmin + 64, ymax - ymin + 1, mask_format, filter,
                      &mask, &binfo.mask_image);

        if ((PIXMAN_FORMAT_R(mask_format) ||
             PIXMAN_FORMAT_G(mask_format) ||
             PIXMAN_FORMAT_B(mask_format)))
        {
            pixman_image_set_component_alpha (binfo.mask_image, 1);
        }
    }

    create_image (WIDTH + 64, HEIGHT, dest_format, filter,
                  &dest, &binfo.dest_image);

    run_benchmark (&binfo);

    return EXIT_SUCCESS;
}