diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-04-26 12:43:21 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-04-26 12:43:21 -0400 |
commit | d9a932ac871372ffd7550290e0849a258cc98ce0 (patch) | |
tree | db1e0dd923fe548d6c6acd24e7233a0baa6f10ab | |
parent | 643b741b945dfe2aae4feb6c4c1cae7ee0db48b7 (diff) |
Polygon replayer, bug fixes in tracers
-rw-r--r-- | trace/Makefile.am | 11 | ||||
-rw-r--r-- | trace/libpolygon-extractor.c | 2 | ||||
-rw-r--r-- | trace/pixman-trace.c | 2 | ||||
-rw-r--r-- | trace/polygon-replay.c | 202 |
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; +} |