diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2013-10-11 16:50:56 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2013-10-11 16:50:56 -0400 |
commit | 7b467305a8912dc8d4a6a4c6f54405a8539b447e (patch) | |
tree | 5ce4bd5419015f0f98284f9217f8cd4083c979e7 | |
parent | 02d912ca8e7d7802a8ad009e8c0d32306b55c543 (diff) |
Check in libpolygon-extractor.c
-rw-r--r-- | demos/Makefile.am | 2 | ||||
-rw-r--r-- | pixman/todo | 10 | ||||
-rw-r--r-- | test/libpolygon-extractor.c | 189 |
3 files changed, 199 insertions, 2 deletions
diff --git a/demos/Makefile.am b/demos/Makefile.am index 9e849fb3..58b9fd50 100644 --- a/demos/Makefile.am +++ b/demos/Makefile.am @@ -44,10 +44,8 @@ clip_in_SOURCES = clip-in.c $(GTK_UTILS) trap_test_SOURCES = trap-test.c $(GTK_UTILS) screen_test_SOURCES = screen-test.c $(GTK_UTILS) convolution_test_SOURCES = convolution-test.c $(GTK_UTILS) -radial_test_SOURCES = radial-test.c $(GTK_UTILS) linear_gradient_SOURCES = linear-gradient.c $(GTK_UTILS) conical_test_SOURCES = conical-test.c $(GTK_UTILS) -tri_test_SOURCES = tri-test.c $(GTK_UTILS) checkerboard_SOURCES = checkerboard.c $(GTK_UTILS) srgb_test_SOURCES = srgb-test.c $(GTK_UTILS) srgb_trap_test_SOURCES = srgb-trap-test.c $(GTK_UTILS) diff --git a/pixman/todo b/pixman/todo index 79915144..f141a320 100644 --- a/pixman/todo +++ b/pixman/todo @@ -20,6 +20,16 @@ * - Sorting at the death event is necessary to cause the new edge to * be positioned correctly in the sort */ +/* Polygon benchmarking + * - Add polygon-extractor + * - Initial version: + * - for compositing operations ( + * if solid, record color (especially whether it has alpha or not) + * if bits, record image format, size + * if polygon, record the full polygon + * if gradient, skip) + * - emit C array of compositing operations + * - ignore endianness /* Optimizations: * - for a given y coordinate, store in the tables the number of small steps * remaining. That will get rid of a test in the inner emit loop. diff --git a/test/libpolygon-extractor.c b/test/libpolygon-extractor.c new file mode 100644 index 00000000..bb0b4333 --- /dev/null +++ b/test/libpolygon-extractor.c @@ -0,0 +1,189 @@ +/* polygon-extractor - a utility to extract polygons + * + * Copyright © 2012, 2013 Red Hat, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define _GNU_SOURCE 1 + +#include <stdlib.h> +#include <dlfcn.h> +#include <assert.h> +#include <stdio.h> +#include <config.h> +#include "pixman-private.h" +#include "trace.h" + +/* FIXME: endianness */ + +/* This macro is lifted from cairo-trace, written by Chris Wilson */ + +static void *_dlhandle = RTLD_NEXT; +#define DLCALL(name, args...) \ + ({ \ + static typeof (&name) name##_real; \ + if (name##_real == NULL) \ + { \ + name##_real = (typeof (&name))(dlsym (_dlhandle, #name)); \ + if (name##_real == NULL && _dlhandle == RTLD_NEXT) \ + { \ + _dlhandle = dlopen ("libpixman.so", RTLD_LAZY); \ + name##_real = (typeof (&name))(dlsym (_dlhandle, #name)); \ + assert (name##_real != NULL); \ + } \ + } \ + (*name##_real) (args); \ + }) + +static FILE *file; +static FILE *ops; +static pixman_bool_t no_output; + +static pixman_bool_t +ensure_files (void) +{ + char *filename; + + if (file) + return TRUE; + + if (no_output) + return FALSE; + + if (!(filename = getenv ("PIXMAN_TRACE_OUTPUT_FILE"))) + goto no; + + if (!(file = fopen (filename, "w"))) + goto no; + + return TRUE; + +no: + no_output = TRUE; + return FALSE; +} + +static int +emit_segments_24_8 (const pixman_segment_24_8_t *segments, + int n_segments) +{ + static int segno = 0; + + ++segno; + emit_string ("static const pixman_segment_24_8_t segments%d[] =\n", + segno); + emit_string ("{\n"); + + while (n_segments--) + { + pixman_segment_24_8_t segment = segments++; + + emit_string ( + " { { { 0x%x, 0x%x }, { 0x%x, 0x%x } }, 0x%x, 0x%x, %d },\n", + segment->line->p1.x, segment->line->p1.y, + segment->line->p2.x, segment->line->p2.y, + segemnt->top, segment->bottom, + segment->dir); + } + + emit_string ("};\n\n"); +} + +static void +emit_image (pixman_image_t *image) +{ + emit_string (" { "); + + if (image->common.extended_format_code == PIXMAN_solid) + { + emit_string (".solid = { IMAGE_SOLID, %08x }", + pixman_image_get_solid (image)); + } + else if (image->common.type == BITS) + { + emit_string (".bits = { IMAGE_BITS, PIXMAN_%s, %d %d }", + format_name (image->bits.format), + image->bits.width, + image->bits.height); + } + else if (image->common.type == POLYGON) + { + static const char *antialias[] = + { + "PIXMAN_ANTIALIAS_BOX_17_15", + "PIXMAN_ANTIALIAS_BOX_5_3", + "PIXMAN_ANTIALIAS_BOX_1_1", + }; + static const char *fill_rules[] = + { + "PIXMAN_FILL_RULE_WINDING", + "PIXMAN_FILL_RULE_EVEN_ODD", + "PIXMAN_FILL_RULE_INVERSE_WINDING", + "PIXMAN_FILL_RULE_INVERSE_EVEN_ODD", + }; + + polygon_t *polygon = &image->polygon; + int segno; + + segno = emit_segments_24_8 (polygon->segments, polygon->n_segments); + + emit_string (".polygon = {\n"); + emit_string (" IMAGE_POLYGON,\n"); + emit_string (" %s,\n", + antialias[image->common.antialias]); + emit_string (" %s,\n", + fill_rule[image->common.fill_rule]); + emit_string (" %d, segments%d }\n", + polygon->n_segments, segno); + } + emit_string (" }"); +} + +PIXMAN_EXPORT void +pixman_image_composite32 (pixman_op_t op, + pixman_image_t *src, + pixman_image_t *mask, + pixman_image_t *dest, + int32_t src_x, + int32_t src_y, + int32_t mask_x, + int32_t mask_y, + int32_t dest_x, + int32_t dest_y, + int32_t width, + int32_t height) +{ + DLCALL (pixman_image_composite32, + op, src, mask, dest, + src_x, src_y, mask_x, mask_y, dest_x, dest_y, + width, height); + + if (src->type == GRADIENT || (mask && mask->type == GRADIENT)) + return; + + ensure_file (); + + emit_string (" { %s,\n", operator_name (op)); + emit_image (src); + emit_string (",\n"); + emit_image (mask); + emit_string (",\n"); + emit_image (dest); + emit_string (",\n"); + emit_string (" %d, %d, %d, %d, %d, %d, %d, %d\n", + src_x, src_y, mask_x, mask_y, + dest_x, dest_y, width, height); + emit_string (" },\n\n"); +} |