summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-04-26 12:43:21 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-04-26 12:43:21 -0400
commitd9a932ac871372ffd7550290e0849a258cc98ce0 (patch)
treedb1e0dd923fe548d6c6acd24e7233a0baa6f10ab
parent643b741b945dfe2aae4feb6c4c1cae7ee0db48b7 (diff)
Polygon replayer, bug fixes in tracers
-rw-r--r--trace/Makefile.am11
-rw-r--r--trace/libpolygon-extractor.c2
-rw-r--r--trace/pixman-trace.c2
-rw-r--r--trace/polygon-replay.c202
4 files changed, 213 insertions, 4 deletions
diff --git a/trace/Makefile.am b/trace/Makefile.am
index 44f73009..2531be8d 100644
--- a/trace/Makefile.am
+++ b/trace/Makefile.am
@@ -4,11 +4,14 @@ libpixman_trace_la_SOURCES = pixman-trace.c
libpixman_trace_la_LIBADD = -ldl
libpixman_trace_la_LDFLAGS = -no-undefined
-libpolygon_extractor_trace_la_SOURCES = pixman-trace.c
-libpolygon_extractor_trace_la_LIBADD = -ldl
-libpolygon_extractor_trace_la_LDFLAGS = -no-undefined
+libpolygon_extractor_la_SOURCES = libpolygon-extractor.c
+libpolygon_extractor_la_LIBADD = -ldl
+libpolygon_extractor_la_LDFLAGS = -no-undefined
-bin_PROGRAMS = pixman-replay
+bin_PROGRAMS = pixman-replay polygon-replay
pixman_replay_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
pixman_replay_SOURCES = pixman-replay.c
+
+polygon_replay_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+polygon_replay_SOURCES = polygon-replay.c
diff --git a/trace/libpolygon-extractor.c b/trace/libpolygon-extractor.c
index 103d8fe0..74e85066 100644
--- a/trace/libpolygon-extractor.c
+++ b/trace/libpolygon-extractor.c
@@ -99,6 +99,7 @@ emit_region32 (pixman_region32_t *region)
int n_rects;
boxes = pixman_region32_rectangles (region, &n_rects);
+ emit_int (n_rects);
while (n_rects--)
emit_box32 (boxes++);
}
@@ -188,6 +189,7 @@ pixman_image_composite32 (pixman_op_t op,
pixman_region32_init_rect (&clip, dest_x, dest_y, width, height);
if (dest->common.have_clip_region)
pixman_region32_intersect (&clip, &clip, &dest->common.clip_region);
+
emit_region32 (&clip);
pixman_region32_fini (&clip);
diff --git a/trace/pixman-trace.c b/trace/pixman-trace.c
index 344f8201..745aff51 100644
--- a/trace/pixman-trace.c
+++ b/trace/pixman-trace.c
@@ -243,6 +243,7 @@ emit_region16 (pixman_region16_t *region)
int n_rects;
boxes = pixman_region_rectangles (region, &n_rects);
+ emit_int (n_rects);
while (n_rects--)
emit_box16 (boxes++);
}
@@ -254,6 +255,7 @@ emit_region32 (pixman_region32_t *region)
int n_rects;
boxes = pixman_region32_rectangles (region, &n_rects);
+ emit_int (n_rects);
while (n_rects--)
emit_box32 (boxes++);
}
diff --git a/trace/polygon-replay.c b/trace/polygon-replay.c
new file mode 100644
index 00000000..41b88a60
--- /dev/null
+++ b/trace/polygon-replay.c
@@ -0,0 +1,202 @@
+#include <config.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <stdint.h>
+#include <unistd.h>
+#include "pixman-private.h"
+#include "trace.h"
+
+#define debugf(...)
+//#define debugf printf
+
+
+static uint8_t *
+map_file (const char *filename, size_t *length, char **error)
+{
+ int fd = open (filename, O_RDONLY);
+ struct stat statbuf;
+ uint8_t *buffer = NULL;
+ *error = NULL;
+
+ if (fd < 0)
+ {
+ *error = "Could not open file\n";
+ goto out;
+ }
+
+ if (fstat (fd, &statbuf) < 0)
+ {
+ *error = "Could not stat file\n";
+ goto out;
+ }
+
+ buffer = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (buffer == MAP_FAILED)
+ {
+ *error = "Could not map file\n";
+ buffer = NULL;
+ goto out;
+ }
+
+ *length = statbuf.st_size;
+
+out:
+ close (fd);
+ return buffer;
+}
+
+static force_inline int32_t
+read_int (uint32_t **buffer)
+{
+ return *(*buffer)++;
+}
+
+static void
+get_int (uint32_t **buffer, int32_t *i)
+{
+ *i = read_int (buffer);
+}
+
+static void
+get_box32 (uint32_t **buffer, pixman_box32_t *box)
+{
+ box->x1 = read_int (buffer);
+ box->y1 = read_int (buffer);
+ box->x2 = read_int (buffer);
+ box->y2 = read_int (buffer);
+}
+
+static void
+get_region32 (uint32_t **buffer, pixman_region32_t *region)
+{
+ int n_boxes = read_int (buffer);
+ pixman_box32_t *boxes;
+ int i;
+
+ boxes = malloc (n_boxes * sizeof (pixman_box32_t));
+ for (i = 0; i < n_boxes; ++i)
+ get_box32 (buffer, &(boxes[i]));
+
+ pixman_region32_init_rects (region, boxes, n_boxes);
+}
+
+static void
+get_point_24_8 (uint32_t **buffer, pixman_point_24_8_t *point)
+{
+ point->x = read_int (buffer);
+ point->y = read_int (buffer);
+}
+
+static void
+get_line_24_8 (uint32_t **buffer, pixman_line_24_8_t *line)
+{
+ get_point_24_8 (buffer, &line->p1);
+ get_point_24_8 (buffer, &line->p2);
+}
+
+static void
+get_segment_24_8 (uint32_t **buffer, pixman_segment_24_8_t *segment)
+{
+ get_line_24_8 (buffer, &(segment->line));
+ get_int (buffer, &(segment->top));
+ get_int (buffer, &(segment->bottom));
+ get_int (buffer, &(segment->dir));
+}
+
+static void
+get_segments_24_8 (uint32_t **buffer, int *n_segments, pixman_segment_24_8_t **segments)
+{
+ int i;
+
+ *n_segments = read_int (buffer);
+ *segments = realloc (*segments, *n_segments * sizeof (pixman_segment_24_8_t));
+ for (i = 0; i < *n_segments; ++i)
+ get_segment_24_8 (buffer, &((*segments)[i]));
+}
+
+static void
+polygon_replay (const char *filename)
+{
+ char *error;
+ uint32_t *buffer, *end;
+ size_t length;
+
+ if (!(buffer = (uint32_t *)map_file (filename, &length, &error)))
+ {
+ printf ("%s\n", error);
+ return;
+ }
+
+ if (length % 4 != 0)
+ {
+ printf ("Length of file is not a multiple of 4\n\n");
+ return;
+ }
+
+ end = buffer + length / 4;
+ while (buffer < end)
+ {
+ int resample;
+ int fill_rule;
+ int n_segments;
+ pixman_segment_24_8_t *segments = NULL;
+ pixman_image_t *polygon;
+ pixman_image_t *destination;
+ int width, height;
+ pixman_region32_t clip;
+ int src_x, src_y;
+ int dest_x, dest_y;
+
+ /* Polygon */
+ get_int (&buffer, &resample);
+ get_int (&buffer, &fill_rule);
+ get_segments_24_8 (&buffer, &n_segments, &segments);
+ polygon = pixman_image_create_polygon_from_segments (segments, n_segments);
+ pixman_image_set_fill_rule (polygon, fill_rule);
+ pixman_image_set_resample (polygon, resample);
+ free (segments);
+
+ /* Destination */
+ get_int (&buffer, &width);
+ get_int (&buffer, &height);
+ get_region32 (&buffer, &clip);
+
+ destination = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, -1);
+ pixman_image_set_clip_region32 (destination, &clip);
+ pixman_region32_fini (&clip);
+
+ /* Composite */
+ get_int (&buffer, &src_x);
+ get_int (&buffer, &src_y);
+ get_int (&buffer, &dest_x);
+ get_int (&buffer, &dest_y);
+ get_int (&buffer, &width);
+ get_int (&buffer, &height);
+
+ pixman_image_composite32 (PIXMAN_OP_SRC,
+ polygon, NULL, destination,
+ src_x, src_y, 0, 0, dest_x, dest_y,
+ width, height);
+
+ pixman_image_unref (polygon);
+ pixman_image_unref (destination);
+ }
+
+ munmap (buffer, length);
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc != 2)
+ {
+ printf ("Usage: pixman-replay filename\n");
+ return -1;
+ }
+
+ polygon_replay (argv[1]);
+ return 0;
+}