summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2013-10-11 16:50:56 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2013-10-11 16:50:56 -0400
commit7b467305a8912dc8d4a6a4c6f54405a8539b447e (patch)
tree5ce4bd5419015f0f98284f9217f8cd4083c979e7
parent02d912ca8e7d7802a8ad009e8c0d32306b55c543 (diff)
Check in libpolygon-extractor.c
-rw-r--r--demos/Makefile.am2
-rw-r--r--pixman/todo10
-rw-r--r--test/libpolygon-extractor.c189
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");
+}