diff options
Diffstat (limited to 'pixman/test')
-rw-r--r-- | pixman/test/Makefile.sources | 3 | ||||
-rw-r--r-- | pixman/test/affine-test.c | 111 | ||||
-rw-r--r-- | pixman/test/alpha-loop.c | 11 | ||||
-rw-r--r-- | pixman/test/alphamap.c | 2 | ||||
-rw-r--r-- | pixman/test/blitters-test.c | 60 | ||||
-rw-r--r-- | pixman/test/combiner-test.c | 4 | ||||
-rw-r--r-- | pixman/test/composite-traps-test.c | 58 | ||||
-rw-r--r-- | pixman/test/composite.c | 12 | ||||
-rw-r--r-- | pixman/test/glyph-test.c | 94 | ||||
-rw-r--r-- | pixman/test/prng-test.c | 172 | ||||
-rw-r--r-- | pixman/test/region-contains-test.c | 28 | ||||
-rw-r--r-- | pixman/test/region-test.c | 10 | ||||
-rw-r--r-- | pixman/test/rotate-test.c | 14 | ||||
-rw-r--r-- | pixman/test/scaling-helpers-test.c | 9 | ||||
-rw-r--r-- | pixman/test/scaling-test.c | 129 | ||||
-rw-r--r-- | pixman/test/stress-test.c | 112 | ||||
-rw-r--r-- | pixman/test/utils-prng.c | 238 | ||||
-rw-r--r-- | pixman/test/utils-prng.h | 168 | ||||
-rw-r--r-- | pixman/test/utils.c | 25 | ||||
-rw-r--r-- | pixman/test/utils.h | 58 |
20 files changed, 939 insertions, 379 deletions
diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources index 077897161..8c0b505df 100644 --- a/pixman/test/Makefile.sources +++ b/pixman/test/Makefile.sources @@ -1,5 +1,6 @@ # Tests (sorted by expected completion time) TESTPROGRAMS = \ + prng-test \ a1-trap-test \ pdf-op-test \ region-test \ @@ -33,8 +34,10 @@ BENCHMARKS = \ # Utility functions libutils_sources = \ utils.c \ + utils-prng.c \ $(NULL) libutils_headers = \ utils.h \ + utils-prng.h \ $(NULL) diff --git a/pixman/test/affine-test.c b/pixman/test/affine-test.c index daa86c81d..f60ec14eb 100644 --- a/pixman/test/affine-test.c +++ b/pixman/test/affine-test.c @@ -48,18 +48,18 @@ test_composite (int testnum, uint32_t crc32; FLOAT_REGS_CORRUPTION_DETECTOR_START (); - lcg_srand (testnum); + prng_srand (testnum); - src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; - dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; - op = (lcg_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER; + src_bpp = (prng_rand_n (2) == 0) ? 2 : 4; + dst_bpp = (prng_rand_n (2) == 0) ? 2 : 4; + op = (prng_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER; - src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1; - src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1; - dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1; - dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1; - src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp; - dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp; + src_width = prng_rand_n (MAX_SRC_WIDTH) + 1; + src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1; + dst_width = prng_rand_n (MAX_DST_WIDTH) + 1; + dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1; + src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp; + dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp; if (src_stride & 3) src_stride += 2; @@ -67,26 +67,23 @@ test_composite (int testnum, if (dst_stride & 3) dst_stride += 2; - src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2); - src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2); - dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2); - dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2); - w = lcg_rand_n (dst_width * 3 / 2 - dst_x); - h = lcg_rand_n (dst_height * 3 / 2 - dst_y); + src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2); + src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2); + dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2); + dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2); + w = prng_rand_n (dst_width * 3 / 2 - dst_x); + h = prng_rand_n (dst_height * 3 / 2 - dst_y); srcbuf = (uint32_t *)malloc (src_stride * src_height); dstbuf = (uint32_t *)malloc (dst_stride * dst_height); - for (i = 0; i < src_stride * src_height; i++) - *((uint8_t *)srcbuf + i) = lcg_rand_n (256); + prng_randmemset (srcbuf, src_stride * src_height, 0); + prng_randmemset (dstbuf, dst_stride * dst_height, 0); - for (i = 0; i < dst_stride * dst_height; i++) - *((uint8_t *)dstbuf + i) = lcg_rand_n (256); - - src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ? + src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; - dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ? + dst_fmt = dst_bpp == 4 ? (prng_rand_n (2) == 0 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; src_img = pixman_image_create_bits ( @@ -100,29 +97,29 @@ test_composite (int testnum, pixman_transform_init_identity (&transform); - if (lcg_rand_n (3) > 0) + if (prng_rand_n (3) > 0) { - scale_x = -65536 * 3 + lcg_rand_N (65536 * 6); - if (lcg_rand_n (2)) - scale_y = -65536 * 3 + lcg_rand_N (65536 * 6); + scale_x = -65536 * 3 + prng_rand_n (65536 * 6); + if (prng_rand_n (2)) + scale_y = -65536 * 3 + prng_rand_n (65536 * 6); else scale_y = scale_x; pixman_transform_init_scale (&transform, scale_x, scale_y); } - if (lcg_rand_n (3) > 0) + if (prng_rand_n (3) > 0) { - translate_x = -65536 * 3 + lcg_rand_N (6 * 65536); - if (lcg_rand_n (2)) - translate_y = -65536 * 3 + lcg_rand_N (6 * 65536); + translate_x = -65536 * 3 + prng_rand_n (6 * 65536); + if (prng_rand_n (2)) + translate_y = -65536 * 3 + prng_rand_n (6 * 65536); else translate_y = translate_x; pixman_transform_translate (&transform, NULL, translate_x, translate_y); } - if (lcg_rand_n (4) > 0) + if (prng_rand_n (4) > 0) { int c, s, tx = 0, ty = 0; - switch (lcg_rand_n (4)) + switch (prng_rand_n (4)) { case 0: /* 90 degrees */ @@ -145,32 +142,32 @@ test_composite (int testnum, break; default: /* arbitrary rotation */ - c = lcg_rand_N (2 * 65536) - 65536; - s = lcg_rand_N (2 * 65536) - 65536; + c = prng_rand_n (2 * 65536) - 65536; + s = prng_rand_n (2 * 65536) - 65536; break; } pixman_transform_rotate (&transform, NULL, c, s); pixman_transform_translate (&transform, NULL, tx, ty); } - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { /* Flip random bits */ int maxflipcount = 8; while (maxflipcount--) { - int i = lcg_rand_n (2); - int j = lcg_rand_n (3); - int bitnum = lcg_rand_n (32); + int i = prng_rand_n (2); + int j = prng_rand_n (3); + int bitnum = prng_rand_n (32); transform.matrix[i][j] ^= 1 << bitnum; - if (lcg_rand_n (2)) + if (prng_rand_n (2)) break; } } pixman_image_set_transform (src_img, &transform); - switch (lcg_rand_n (4)) + switch (prng_rand_n (4)) { case 0: repeat = PIXMAN_REPEAT_NONE; @@ -193,7 +190,7 @@ test_composite (int testnum, } pixman_image_set_repeat (src_img, repeat); - if (lcg_rand_n (2)) + if (prng_rand_n (2)) pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0); else pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0); @@ -220,19 +217,19 @@ test_composite (int testnum, printf ("w=%d, h=%d\n", w, h); } - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; - int n = lcg_rand_n (2) + 1; + int n = prng_rand_n (2) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (src_width); - clip_boxes[i].y1 = lcg_rand_n (src_height); + clip_boxes[i].x1 = prng_rand_n (src_width); + clip_boxes[i].y1 = prng_rand_n (src_height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1); if (verbose) { @@ -248,18 +245,18 @@ test_composite (int testnum, pixman_region_fini (&clip); } - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; - int n = lcg_rand_n (2) + 1; + int n = prng_rand_n (2) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (dst_width); - clip_boxes[i].y1 = lcg_rand_n (dst_height); + clip_boxes[i].x1 = prng_rand_n (dst_width); + clip_boxes[i].y1 = prng_rand_n (dst_height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1); if (verbose) { @@ -310,11 +307,11 @@ test_composite (int testnum, } #if BILINEAR_INTERPOLATION_BITS == 8 -#define CHECKSUM 0x344413F0 +#define CHECKSUM 0x97097336 #elif BILINEAR_INTERPOLATION_BITS == 7 -#define CHECKSUM 0xC8181A76 +#define CHECKSUM 0x31D2DC21 #elif BILINEAR_INTERPOLATION_BITS == 4 -#define CHECKSUM 0xD672A457 +#define CHECKSUM 0x8B925154 #else #define CHECKSUM 0x00000000 #endif diff --git a/pixman/test/alpha-loop.c b/pixman/test/alpha-loop.c index e4d90a988..eca761537 100644 --- a/pixman/test/alpha-loop.c +++ b/pixman/test/alpha-loop.c @@ -8,9 +8,14 @@ int main (int argc, char **argv) { - uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT); - uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); - uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); + uint8_t *alpha; + uint32_t *src, *dest; + + prng_srand (0); + + alpha = make_random_bytes (WIDTH * HEIGHT); + src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); + dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH); pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); diff --git a/pixman/test/alphamap.c b/pixman/test/alphamap.c index 0c5757ea3..1a6fca55a 100644 --- a/pixman/test/alphamap.c +++ b/pixman/test/alphamap.c @@ -307,6 +307,8 @@ main (int argc, char **argv) { int i, j, a, b, x, y; + prng_srand (0); + for (i = 0; i < ARRAY_LENGTH (formats); ++i) { for (j = 0; j < ARRAY_LENGTH (formats); ++j) diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index 30d69124c..9bde99c62 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -25,7 +25,7 @@ create_random_image (pixman_format_code_t *allowed_formats, int max_extra_stride, pixman_format_code_t *used_fmt) { - int n = 0, i, width, height, stride; + int n = 0, width, height, stride; pixman_format_code_t fmt; uint32_t *buf; pixman_image_t *img; @@ -33,28 +33,20 @@ create_random_image (pixman_format_code_t *allowed_formats, while (allowed_formats[n] != PIXMAN_null) n++; - if (n > N_MOST_LIKELY_FORMATS && lcg_rand_n (4) != 0) + if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0) n = N_MOST_LIKELY_FORMATS; - fmt = allowed_formats[lcg_rand_n (n)]; + fmt = allowed_formats[prng_rand_n (n)]; - width = lcg_rand_n (max_width) + 1; - height = lcg_rand_n (max_height) + 1; + width = prng_rand_n (max_width) + 1; + height = prng_rand_n (max_height) + 1; stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 + - lcg_rand_n (max_extra_stride + 1); + prng_rand_n (max_extra_stride + 1); stride = (stride + 3) & ~3; /* do the allocation */ buf = aligned_malloc (64, stride * height); - /* initialize image with random data */ - for (i = 0; i < stride * height; i++) - { - /* generation is biased to having more 0 or 255 bytes as - * they are more likely to be special-cased in code - */ - *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) : - (lcg_rand_n (2) ? 0 : 255); - } + prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF); img = pixman_image_create_bits (fmt, width, height, buf, stride); @@ -67,7 +59,7 @@ create_random_image (pixman_format_code_t *allowed_formats, pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)])); } - if (lcg_rand_n (16) == 0) + if (prng_rand_n (16) == 0) pixman_image_set_filter (img, PIXMAN_FILTER_BILINEAR, NULL, 0); image_endian_swap (img); @@ -251,11 +243,11 @@ test_composite (int testnum, int verbose) if (max_extra_stride > 8) max_extra_stride = 8; - lcg_srand (testnum); + prng_srand (testnum); - op = op_list[lcg_rand_n (ARRAY_LENGTH (op_list))]; + op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))]; - if (lcg_rand_n (8)) + if (prng_rand_n (8)) { /* normal image */ src_img = create_random_image (img_fmt_list, max_width, max_height, @@ -284,10 +276,10 @@ test_composite (int testnum, int verbose) 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); + 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; @@ -296,10 +288,10 @@ test_composite (int testnum, int verbose) maskbuf = NULL; if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) && - (lcg_rand_n (4) == 0)) + (prng_rand_n (4) == 0)) { /* PIXBUF */ - mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8; + mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8; mask_img = pixman_image_create_bits (mask_fmt, src_width, src_height, @@ -309,9 +301,9 @@ test_composite (int testnum, int verbose) mask_y = src_y; maskbuf = srcbuf; } - else if (lcg_rand_n (2)) + else if (prng_rand_n (2)) { - if (lcg_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); @@ -324,16 +316,16 @@ test_composite (int testnum, int verbose) pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL); } - if (lcg_rand_n (2)) + if (prng_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)); + mask_x = prng_rand_n (pixman_image_get_width (mask_img)); + mask_y = prng_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); + w = prng_rand_n (dst_width - dst_x + 1); + h = prng_rand_n (dst_height - dst_y + 1); if (verbose) { @@ -390,6 +382,8 @@ main (int argc, const char *argv[]) { int i; + prng_srand (0); + for (i = 1; i <= 8; i++) { initialize_palette (&(rgb_palette[i]), i, TRUE); @@ -397,6 +391,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main("blitters", 2000000, - 0x46136E0A, + 0xD8265D5E, test_composite, argc, argv); } diff --git a/pixman/test/combiner-test.c b/pixman/test/combiner-test.c index c438ae62e..01f63a56e 100644 --- a/pixman/test/combiner-test.c +++ b/pixman/test/combiner-test.c @@ -67,7 +67,7 @@ static const pixman_op_t op_list[] = static float rand_float (void) { - uint32_t u = lcg_rand_u32(); + uint32_t u = prng_rand(); return *(float *)&u; } @@ -123,7 +123,7 @@ main () impl = _pixman_internal_only_get_implementation(); - lcg_srand (0); + prng_srand (0); for (i = 0; i < ARRAY_LENGTH (op_list); ++i) { diff --git a/pixman/test/composite-traps-test.c b/pixman/test/composite-traps-test.c index 9fc94a4d6..2983eae83 100644 --- a/pixman/test/composite-traps-test.c +++ b/pixman/test/composite-traps-test.c @@ -26,7 +26,7 @@ static pixman_op_t operators[] = }; #define RANDOM_ELT(array) \ - ((array)[lcg_rand_n(ARRAY_LENGTH((array)))]) + ((array)[prng_rand_n(ARRAY_LENGTH((array)))]) static void destroy_bits (pixman_image_t *image, void *data) @@ -37,7 +37,7 @@ destroy_bits (pixman_image_t *image, void *data) static pixman_fixed_t random_fixed (int n) { - return lcg_rand_N (n << 16); + return prng_rand_n (n << 16); } /* @@ -75,17 +75,17 @@ test_composite (int testnum, FLOAT_REGS_CORRUPTION_DETECTOR_START (); - lcg_srand (testnum); + prng_srand (testnum); op = RANDOM_ELT (operators); mask_format = RANDOM_ELT (mask_formats); /* Create source image */ - if (lcg_rand_n (4) == 0) + if (prng_rand_n (4) == 0) { src_img = pixman_image_create_solid_fill ( - &(colors[lcg_rand_n (ARRAY_LENGTH (colors))])); + &(colors[prng_rand_n (ARRAY_LENGTH (colors))])); src_x = 10; src_y = 234; @@ -94,13 +94,13 @@ test_composite (int testnum, { pixman_format_code_t src_format = RANDOM_ELT(formats); int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8; - int src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1; - int src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1; - int src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp; + int src_width = prng_rand_n (MAX_SRC_WIDTH) + 1; + int src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1; + int src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp; uint32_t *bits; - src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2); - src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2); + src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2); + src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2); src_stride = (src_stride + 3) & ~3; @@ -111,19 +111,19 @@ test_composite (int testnum, pixman_image_set_destroy_function (src_img, destroy_bits, bits); - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; - int n = lcg_rand_n (2) + 1; + int n = prng_rand_n (2) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (src_width); - clip_boxes[i].y1 = lcg_rand_n (src_height); + clip_boxes[i].x1 = prng_rand_n (src_width); + clip_boxes[i].y1 = prng_rand_n (src_height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1); if (verbose) { @@ -146,15 +146,15 @@ test_composite (int testnum, { dst_format = RANDOM_ELT(formats); dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8; - dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1; - dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1; - dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp; + dst_width = prng_rand_n (MAX_DST_WIDTH) + 1; + dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1; + dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp; dst_stride = (dst_stride + 3) & ~3; dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height); - dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2); - dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2); + dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2); + dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2); dst_img = pixman_image_create_bits ( dst_format, dst_width, dst_height, dst_bits, dst_stride); @@ -166,7 +166,7 @@ test_composite (int testnum, { int i; - n_traps = lcg_rand_n (25); + n_traps = prng_rand_n (25); traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t)); for (i = 0; i < n_traps; ++i) @@ -186,18 +186,18 @@ test_composite (int testnum, } } - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; - int n = lcg_rand_n (2) + 1; + int n = prng_rand_n (2) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (dst_width); - clip_boxes[i].y1 = lcg_rand_n (dst_height); + clip_boxes[i].x1 = prng_rand_n (dst_width); + clip_boxes[i].y1 = prng_rand_n (dst_height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1); if (verbose) { @@ -251,6 +251,6 @@ test_composite (int testnum, int main (int argc, const char *argv[]) { - return fuzzer_test_main("composite traps", 40000, 0x33BFAA55, + return fuzzer_test_main("composite traps", 40000, 0x749BCC57, test_composite, argc, argv); } diff --git a/pixman/test/composite.c b/pixman/test/composite.c index 2930fb75b..09752c5c7 100644 --- a/pixman/test/composite.c +++ b/pixman/test/composite.c @@ -725,19 +725,19 @@ image_fini (image_t *info) static int random_size (void) { - return lcg_rand_n (ARRAY_LENGTH (sizes)); + return prng_rand_n (ARRAY_LENGTH (sizes)); } static int random_color (void) { - return lcg_rand_n (ARRAY_LENGTH (colors)); + return prng_rand_n (ARRAY_LENGTH (colors)); } static int random_format (void) { - return lcg_rand_n (ARRAY_LENGTH (formats)); + return prng_rand_n (ARRAY_LENGTH (formats)); } static pixman_bool_t @@ -748,15 +748,15 @@ run_test (uint32_t seed) int ca; int ok; - lcg_srand (seed); + prng_srand (seed); image_init (&dst, random_color(), random_format(), 1); image_init (&src, random_color(), random_format(), random_size()); image_init (&mask, random_color(), random_format(), random_size()); - op = &(operators [lcg_rand_n (ARRAY_LENGTH (operators))]); + op = &(operators [prng_rand_n (ARRAY_LENGTH (operators))]); - ca = lcg_rand_n (3); + ca = prng_rand_n (3); switch (ca) { diff --git a/pixman/test/glyph-test.c b/pixman/test/glyph-test.c index 501cc2e6f..1811add73 100644 --- a/pixman/test/glyph-test.c +++ b/pixman/test/glyph-test.c @@ -107,7 +107,7 @@ random_format (const pixman_format_code_t *formats) i = 0; while (formats[i] != PIXMAN_null) ++i; - return formats[lcg_rand_n (i)]; + return formats[prng_rand_n (i)]; } static pixman_image_t * @@ -122,27 +122,27 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags) int i; pixman_image_destroy_func_t destroy; - if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0) + if ((flags & ALLOW_SOLID) && prng_rand_n (4) == 0) { pixman_color_t color; - color.alpha = lcg_rand_u32(); - color.red = lcg_rand_u32(); - color.green = lcg_rand_u32(); - color.blue = lcg_rand_u32(); + color.alpha = prng_rand(); + color.red = prng_rand(); + color.green = prng_rand(); + color.blue = prng_rand(); return pixman_image_create_solid_fill (&color); } - width = lcg_rand_n (max_size) + 1; - height = lcg_rand_n (max_size) + 1; + width = prng_rand_n (max_size) + 1; + height = prng_rand_n (max_size) + 1; format = random_format (formats); bpp = PIXMAN_FORMAT_BPP (format); - stride = (width * bpp + 7) / 8 + lcg_rand_n (17); + stride = (width * bpp + 7) / 8 + prng_rand_n (17); stride = (stride + 3) & ~3; - if (lcg_rand_n (64) == 0) + if (prng_rand_n (64) == 0) { if (!(data = (uint32_t *)make_random_bytes (stride * height))) { @@ -153,34 +153,28 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags) } else { - uint8_t *d8; - data = malloc (stride * height); - - d8 = (uint8_t *)data; - for (i = 0; i < height * stride; ++i) - d8[i] = lcg_rand_n (256); - + prng_randmemset (data, height * stride, 0); destroy = destroy_malloced; } image = pixman_image_create_bits (format, width, height, data, stride); pixman_image_set_destroy_function (image, destroy, data); - if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0) + if ((flags & ALLOW_CLIPPED) && prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[8]; pixman_region16_t clip; - int n = lcg_rand_n (8) + 1; + int n = prng_rand_n (8) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (width); - clip_boxes[i].y1 = lcg_rand_n (height); + clip_boxes[i].x1 = prng_rand_n (width); + clip_boxes[i].y1 = prng_rand_n (height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (height - clip_boxes[i].y1); } pixman_region_init_rects (&clip, clip_boxes, n); @@ -188,27 +182,27 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags) pixman_region_fini (&clip); } - if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0) + if ((flags & ALLOW_SOURCE_CLIPPING) && prng_rand_n (4) == 0) { pixman_image_set_source_clipping (image, TRUE); pixman_image_set_has_client_clip (image, TRUE); } - if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0) + if ((flags & ALLOW_ALPHA_MAP) && prng_rand_n (16) == 0) { pixman_image_t *alpha_map; int alpha_x, alpha_y; - alpha_x = lcg_rand_n (width); - alpha_y = lcg_rand_n (height); + alpha_x = prng_rand_n (width); + alpha_y = prng_rand_n (height); alpha_map = create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID))); pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y); pixman_image_unref (alpha_map); } - if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0) - pixman_image_set_repeat (image, lcg_rand_n (4)); + if ((flags & ALLOW_REPEAT) && prng_rand_n (2) == 0) + pixman_image_set_repeat (image, prng_rand_n (4)); image_endian_swap (image); @@ -230,7 +224,7 @@ test_glyphs (int testnum, int verbose) int n_glyphs, i; pixman_glyph_cache_t *cache; - lcg_srand (testnum); + prng_srand (testnum); cache = pixman_glyph_cache_create (); @@ -245,13 +239,13 @@ test_glyphs (int testnum, int verbose) pixman_glyph_cache_freeze (cache); - n_glyphs = lcg_rand_n (MAX_GLYPHS); + n_glyphs = prng_rand_n (MAX_GLYPHS); for (i = 0; i < n_glyphs; ++i) glyph_images[i] = create_image (32, glyph_formats, 0); for (i = 0; i < 4 * n_glyphs; ++i) { - int g = lcg_rand_n (n_glyphs); + int g = prng_rand_n (n_glyphs); pixman_image_t *glyph_img = glyph_images[g]; void *key1 = KEY1 (glyph_img); void *key2 = KEY2 (glyph_img); @@ -264,21 +258,21 @@ test_glyphs (int testnum, int verbose) } glyphs[i].glyph = glyph; - glyphs[i].x = lcg_rand_n (128); - glyphs[i].y = lcg_rand_n (128); + glyphs[i].x = prng_rand_n (128); + glyphs[i].y = prng_rand_n (128); } - if (lcg_rand_n (2) == 0) + if (prng_rand_n (2) == 0) { - int src_x = lcg_rand_n (300) - 150; - int src_y = lcg_rand_n (300) - 150; - int mask_x = lcg_rand_n (64) - 32; - int mask_y = lcg_rand_n (64) - 32; - int dest_x = lcg_rand_n (64) - 32; - int dest_y = lcg_rand_n (64) - 32; - int width = lcg_rand_n (64); - int height = lcg_rand_n (64); - pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))]; + int src_x = prng_rand_n (300) - 150; + int src_y = prng_rand_n (300) - 150; + int mask_x = prng_rand_n (64) - 32; + int mask_y = prng_rand_n (64) - 32; + int dest_x = prng_rand_n (64) - 32; + int dest_y = prng_rand_n (64) - 32; + int width = prng_rand_n (64); + int height = prng_rand_n (64); + pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))]; pixman_format_code_t format = random_format (glyph_formats); pixman_composite_glyphs ( @@ -292,11 +286,11 @@ test_glyphs (int testnum, int verbose) } else { - pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))]; - int src_x = lcg_rand_n (300) - 150; - int src_y = lcg_rand_n (300) - 150; - int dest_x = lcg_rand_n (64) - 32; - int dest_y = lcg_rand_n (64) - 32; + pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))]; + int src_x = prng_rand_n (300) - 150; + int src_y = prng_rand_n (300) - 150; + int dest_x = prng_rand_n (64) - 32; + int dest_y = prng_rand_n (64) - 32; pixman_composite_glyphs_no_mask ( op, source, dest, @@ -333,6 +327,6 @@ int main (int argc, const char *argv[]) { return fuzzer_test_main ("glyph", 30000, - 0x79E74996, + 0xFA478A79, test_glyphs, argc, argv); } diff --git a/pixman/test/prng-test.c b/pixman/test/prng-test.c new file mode 100644 index 000000000..0a3ad5e8f --- /dev/null +++ b/pixman/test/prng-test.c @@ -0,0 +1,172 @@ +/* + * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * Based on the public domain implementation of small noncryptographic PRNG + * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <assert.h> +#include <stdlib.h> +#include "utils-prng.h" +#include "utils.h" + +/* The original code from http://www.burtleburtle.net/bob/rand/smallprng.html */ + +typedef uint32_t u4; +typedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx; + +#define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))) +u4 ranval( ranctx *x ) { + u4 e = x->a - rot(x->b, 27); + x->a = x->b ^ rot(x->c, 17); + x->b = x->c + x->d; + x->c = x->d + e; + x->d = e + x->a; + return x->d; +} + +void raninit( ranctx *x, u4 seed ) { + u4 i; + x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; + for (i=0; i<20; ++i) { + (void)ranval(x); + } +} + +/*****************************************************************************/ + +#define BUFSIZE (8 * 1024 * 1024) +#define N 50 + +void bench (void) +{ + double t1, t2; + int i; + prng_t prng; + uint8_t *buf = aligned_malloc (16, BUFSIZE + 1); + + prng_srand_r (&prng, 1234); + t1 = gettime(); + for (i = 0; i < N; i++) + prng_randmemset_r (&prng, buf, BUFSIZE, 0); + t2 = gettime(); + printf ("aligned randmemset : %.2f MB/s\n", + (double)BUFSIZE * N / 1000000. / (t2 - t1)); + + t1 = gettime(); + for (i = 0; i < N; i++) + prng_randmemset_r (&prng, buf + 1, BUFSIZE, 0); + t2 = gettime(); + printf ("unaligned randmemset : %.2f MB/s\n", + (double)BUFSIZE * N / 1000000. / (t2 - t1)); + + t1 = gettime(); + for (i = 0; i < N; i++) + { + prng_randmemset_r (&prng, buf, BUFSIZE, RANDMEMSET_MORE_00_AND_FF); + } + t2 = gettime (); + printf ("aligned randmemset (more 00 and FF) : %.2f MB/s\n", + (double)BUFSIZE * N / 1000000. / (t2 - t1)); + + t1 = gettime(); + for (i = 0; i < N; i++) + { + prng_randmemset_r (&prng, buf + 1, BUFSIZE, RANDMEMSET_MORE_00_AND_FF); + } + t2 = gettime (); + printf ("unaligned randmemset (more 00 and FF) : %.2f MB/s\n", + (double)BUFSIZE * N / 1000000. / (t2 - t1)); + + free (buf); +} + +#define SMALLBUFSIZE 100 + +int main (int argc, char *argv[]) +{ + const uint32_t ref_crc[RANDMEMSET_MORE_00_AND_FF + 1] = + { + 0xBA06763D, 0x103FC550, 0x8B59ABA5, 0xD82A0F39 + }; + uint32_t crc1, crc2; + uint32_t ref, seed, seed0, seed1, seed2, seed3; + prng_rand_128_data_t buf; + uint8_t *bytebuf = aligned_malloc(16, SMALLBUFSIZE + 1); + ranctx x; + prng_t prng; + prng_randmemset_flags_t flags; + + if (argc > 1 && strcmp(argv[1], "-bench") == 0) + { + bench (); + return 0; + } + + /* basic test */ + raninit (&x, 0); + prng_srand_r (&prng, 0); + assert (ranval (&x) == prng_rand_r (&prng)); + + /* test for simd code */ + seed = 0; + prng_srand_r (&prng, seed); + seed0 = (seed = seed * 1103515245 + 12345); + seed1 = (seed = seed * 1103515245 + 12345); + seed2 = (seed = seed * 1103515245 + 12345); + seed3 = (seed = seed * 1103515245 + 12345); + prng_rand_128_r (&prng, &buf); + + raninit (&x, seed0); + ref = ranval (&x); + assert (ref == buf.w[0]); + + raninit (&x, seed1); + ref = ranval (&x); + assert (ref == buf.w[1]); + + raninit (&x, seed2); + ref = ranval (&x); + assert (ref == buf.w[2]); + + raninit (&x, seed3); + ref = ranval (&x); + assert (ref == buf.w[3]); + + /* test for randmemset */ + for (flags = 0; flags <= RANDMEMSET_MORE_00_AND_FF; flags++) + { + prng_srand_r (&prng, 1234); + prng_randmemset_r (&prng, bytebuf, 16, flags); + prng_randmemset_r (&prng, bytebuf + 16, SMALLBUFSIZE - 17, flags); + crc1 = compute_crc32 (0, bytebuf, SMALLBUFSIZE - 1); + prng_srand_r (&prng, 1234); + prng_randmemset_r (&prng, bytebuf + 1, SMALLBUFSIZE - 1, flags); + crc2 = compute_crc32 (0, bytebuf + 1, SMALLBUFSIZE - 1); + assert (ref_crc[flags] == crc1); + assert (ref_crc[flags] == crc2); + } + + free (bytebuf); + + return 0; +} diff --git a/pixman/test/region-contains-test.c b/pixman/test/region-contains-test.c index 9524e2888..096e65179 100644 --- a/pixman/test/region-contains-test.c +++ b/pixman/test/region-contains-test.c @@ -9,16 +9,16 @@ make_random_region (pixman_region32_t *region) pixman_region32_init (region); - n_boxes = lcg_rand_n (64); + n_boxes = prng_rand_n (64); while (n_boxes--) { int32_t x, y; uint32_t w, h; - x = (int32_t)lcg_rand_u32() >> 2; - y = (int32_t)lcg_rand_u32() >> 2; - w = lcg_rand_u32() >> 2; - h = lcg_rand_u32() >> 2; + x = (int32_t)prng_rand() >> 2; + y = (int32_t)prng_rand() >> 2; + w = prng_rand() >> 2; + h = prng_rand() >> 2; pixman_region32_union_rect (region, region, x, y, w, h); } @@ -37,12 +37,12 @@ random_coord (pixman_region32_t *region, pixman_bool_t x) int n_boxes; int begin, end; - if (lcg_rand_n (14)) + if (prng_rand_n (14)) { bb = pixman_region32_rectangles (region, &n_boxes); if (n_boxes == 0) goto use_extent; - b = bb + lcg_rand_n (n_boxes); + b = bb + prng_rand_n (n_boxes); } else { @@ -62,12 +62,12 @@ random_coord (pixman_region32_t *region, pixman_bool_t x) end = b->y2; } - switch (lcg_rand_n (5)) + switch (prng_rand_n (5)) { case 0: - return begin - lcg_rand_u32(); + return begin - prng_rand(); case 1: - return end + lcg_rand_u32 (); + return end + prng_rand (); case 2: return end; case 3: @@ -111,14 +111,14 @@ test_region_contains_rectangle (int i, int verbose) pixman_region32_t region; uint32_t r, r1, r2, r3, r4, crc32; - lcg_srand (i); + prng_srand (i); make_random_region (®ion); box.x1 = random_coord (®ion, TRUE); - box.x2 = box.x1 + lcg_rand_u32 (); + box.x2 = box.x1 + prng_rand (); box.y1 = random_coord (®ion, FALSE); - box.y2 = box.y1 + lcg_rand_u32 (); + box.y2 = box.y1 + prng_rand (); if (verbose) { @@ -163,7 +163,7 @@ main (int argc, const char *argv[]) { return fuzzer_test_main ("region_contains", 1000000, - 0xD2BF8C73, + 0x548E0F3F, test_region_contains_rectangle, argc, argv); } diff --git a/pixman/test/region-test.c b/pixman/test/region-test.c index 9d5a41eb9..bfc219bc7 100644 --- a/pixman/test/region-test.c +++ b/pixman/test/region-test.c @@ -32,6 +32,8 @@ main () 0xffff }; + prng_srand (0); + /* This used to go into an infinite loop before pixman-region.c * was fixed to not use explict "short" variables */ @@ -91,10 +93,10 @@ main () /* Add some random rectangles */ for (j = 0; j < 64; j++) pixman_region32_union_rect (&r1, &r1, - lcg_rand_n (image_size), - lcg_rand_n (image_size), - lcg_rand_n (25), - lcg_rand_n (25)); + prng_rand_n (image_size), + prng_rand_n (image_size), + prng_rand_n (25), + prng_rand_n (25)); /* Clip to image size */ pixman_region32_init_rect (&r2, 0, 0, image_size, image_size); diff --git a/pixman/test/rotate-test.c b/pixman/test/rotate-test.c index a0488ef22..9d2a620cb 100644 --- a/pixman/test/rotate-test.c +++ b/pixman/test/rotate-test.c @@ -43,13 +43,13 @@ static const pixman_transform_t transforms[] = }; #define RANDOM_FORMAT() \ - (formats[lcg_rand_n (ARRAY_LENGTH (formats))]) + (formats[prng_rand_n (ARRAY_LENGTH (formats))]) #define RANDOM_OP() \ - (ops[lcg_rand_n (ARRAY_LENGTH (ops))]) + (ops[prng_rand_n (ARRAY_LENGTH (ops))]) #define RANDOM_TRANSFORM() \ - (&(transforms[lcg_rand_n (ARRAY_LENGTH (transforms))])) + (&(transforms[prng_rand_n (ARRAY_LENGTH (transforms))])) static void on_destroy (pixman_image_t *image, void *data) @@ -63,10 +63,8 @@ make_image (void) pixman_format_code_t format = RANDOM_FORMAT(); uint32_t *bytes = malloc (WIDTH * HEIGHT * 4); pixman_image_t *image; - int i; - for (i = 0; i < WIDTH * HEIGHT * 4; ++i) - ((uint8_t *)bytes)[i] = lcg_rand_n (256); + prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0); image = pixman_image_create_bits ( format, WIDTH, HEIGHT, bytes, WIDTH * 4); @@ -86,7 +84,7 @@ test_transform (int testnum, int verbose) pixman_image_t *src, *dest; uint32_t crc; - lcg_srand (testnum); + prng_srand (testnum); src = make_image (); dest = make_image (); @@ -108,6 +106,6 @@ int main (int argc, const char *argv[]) { return fuzzer_test_main ("rotate", 15000, - 0x5236FD9F, + 0xECF5E426, test_transform, argc, argv); } diff --git a/pixman/test/scaling-helpers-test.c b/pixman/test/scaling-helpers-test.c index 33ec47c85..cd5ace0b2 100644 --- a/pixman/test/scaling-helpers-test.c +++ b/pixman/test/scaling-helpers-test.c @@ -52,14 +52,15 @@ int main (void) { int i; + prng_srand (0); for (i = 0; i < 10000; i++) { int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1; int32_t left_pad2, left_tz2, width2, right_tz2, right_pad2; - pixman_fixed_t vx = lcg_rand_N(10000 << 16) - (3000 << 16); - int32_t width = lcg_rand_N(10000); - int32_t source_image_width = lcg_rand_N(10000) + 1; - pixman_fixed_t unit_x = lcg_rand_N(10 << 16) + 1; + pixman_fixed_t vx = prng_rand_n(10000 << 16) - (3000 << 16); + int32_t width = prng_rand_n(10000); + int32_t source_image_width = prng_rand_n(10000) + 1; + pixman_fixed_t unit_x = prng_rand_n(10 << 16) + 1; width1 = width2 = width; bilinear_pad_repeat_get_scanline_bounds_ref (source_image_width, diff --git a/pixman/test/scaling-test.c b/pixman/test/scaling-test.c index 035410333..64c12dd7c 100644 --- a/pixman/test/scaling-test.c +++ b/pixman/test/scaling-test.c @@ -26,7 +26,7 @@ get_format (int bpp) { if (bpp == 4) { - switch (lcg_rand_n (4)) + switch (prng_rand_n (4)) { default: case 0: @@ -80,11 +80,11 @@ test_composite (int testnum, uint32_t crc32; FLOAT_REGS_CORRUPTION_DETECTOR_START (); - lcg_srand (testnum); + prng_srand (testnum); - src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; - dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; - switch (lcg_rand_n (3)) + src_bpp = (prng_rand_n (2) == 0) ? 2 : 4; + dst_bpp = (prng_rand_n (2) == 0) ? 2 : 4; + switch (prng_rand_n (3)) { case 0: op = PIXMAN_OP_SRC; @@ -97,24 +97,24 @@ test_composite (int testnum, break; } - src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1; - src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1; + src_width = prng_rand_n (MAX_SRC_WIDTH) + 1; + src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1; - if (lcg_rand_n (2)) + if (prng_rand_n (2)) { - mask_width = lcg_rand_n (MAX_SRC_WIDTH) + 1; - mask_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1; + mask_width = prng_rand_n (MAX_SRC_WIDTH) + 1; + mask_height = prng_rand_n (MAX_SRC_HEIGHT) + 1; } else { mask_width = mask_height = 1; } - dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1; - dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1; - src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp; - mask_stride = mask_width * mask_bpp + lcg_rand_n (MAX_STRIDE) * mask_bpp; - dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp; + dst_width = prng_rand_n (MAX_DST_WIDTH) + 1; + dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1; + src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp; + mask_stride = mask_width * mask_bpp + prng_rand_n (MAX_STRIDE) * mask_bpp; + dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp; if (src_stride & 3) src_stride += 2; @@ -127,27 +127,22 @@ test_composite (int testnum, if (dst_stride & 3) dst_stride += 2; - src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2); - src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2); - mask_x = -(mask_width / 4) + lcg_rand_n (mask_width * 3 / 2); - mask_y = -(mask_height / 4) + lcg_rand_n (mask_height * 3 / 2); - dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2); - dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2); - w = lcg_rand_n (dst_width * 3 / 2 - dst_x); - h = lcg_rand_n (dst_height * 3 / 2 - dst_y); + src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2); + src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2); + mask_x = -(mask_width / 4) + prng_rand_n (mask_width * 3 / 2); + mask_y = -(mask_height / 4) + prng_rand_n (mask_height * 3 / 2); + dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2); + dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2); + w = prng_rand_n (dst_width * 3 / 2 - dst_x); + h = prng_rand_n (dst_height * 3 / 2 - dst_y); srcbuf = (uint32_t *)malloc (src_stride * src_height); maskbuf = (uint32_t *)malloc (mask_stride * mask_height); dstbuf = (uint32_t *)malloc (dst_stride * dst_height); - for (i = 0; i < src_stride * src_height; i++) - *((uint8_t *)srcbuf + i) = lcg_rand_n (256); - - for (i = 0; i < mask_stride * mask_height; i++) - *((uint8_t *)maskbuf + i) = lcg_rand_n (256); - - for (i = 0; i < dst_stride * dst_height; i++) - *((uint8_t *)dstbuf + i) = lcg_rand_n (256); + prng_randmemset (srcbuf, src_stride * src_height, 0); + prng_randmemset (maskbuf, mask_stride * mask_height, 0); + prng_randmemset (dstbuf, dst_stride * dst_height, 0); src_fmt = get_format (src_bpp); dst_fmt = get_format (dst_bpp); @@ -164,29 +159,29 @@ test_composite (int testnum, image_endian_swap (src_img); image_endian_swap (dst_img); - if (lcg_rand_n (4) > 0) + if (prng_rand_n (4) > 0) { - scale_x = -32768 * 3 + lcg_rand_N (65536 * 5); - scale_y = -32768 * 3 + lcg_rand_N (65536 * 5); - translate_x = lcg_rand_N (65536); - translate_y = lcg_rand_N (65536); + scale_x = -32768 * 3 + prng_rand_n (65536 * 5); + scale_y = -32768 * 3 + prng_rand_n (65536 * 5); + translate_x = prng_rand_n (65536); + translate_y = prng_rand_n (65536); pixman_transform_init_scale (&transform, scale_x, scale_y); pixman_transform_translate (&transform, NULL, translate_x, translate_y); pixman_image_set_transform (src_img, &transform); } - if (lcg_rand_n (2) > 0) + if (prng_rand_n (2) > 0) { - mask_scale_x = -32768 * 3 + lcg_rand_N (65536 * 5); - mask_scale_y = -32768 * 3 + lcg_rand_N (65536 * 5); - mask_translate_x = lcg_rand_N (65536); - mask_translate_y = lcg_rand_N (65536); + mask_scale_x = -32768 * 3 + prng_rand_n (65536 * 5); + mask_scale_y = -32768 * 3 + prng_rand_n (65536 * 5); + mask_translate_x = prng_rand_n (65536); + mask_translate_y = prng_rand_n (65536); pixman_transform_init_scale (&transform, mask_scale_x, mask_scale_y); pixman_transform_translate (&transform, NULL, mask_translate_x, mask_translate_y); pixman_image_set_transform (mask_img, &transform); } - switch (lcg_rand_n (4)) + switch (prng_rand_n (4)) { case 0: mask_repeat = PIXMAN_REPEAT_NONE; @@ -209,7 +204,7 @@ test_composite (int testnum, } pixman_image_set_repeat (mask_img, mask_repeat); - switch (lcg_rand_n (4)) + switch (prng_rand_n (4)) { case 0: repeat = PIXMAN_REPEAT_NONE; @@ -232,12 +227,12 @@ test_composite (int testnum, } pixman_image_set_repeat (src_img, repeat); - if (lcg_rand_n (2)) + if (prng_rand_n (2)) pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0); else pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0); - if (lcg_rand_n (2)) + if (prng_rand_n (2)) pixman_image_set_filter (mask_img, PIXMAN_FILTER_NEAREST, NULL, 0); else pixman_image_set_filter (mask_img, PIXMAN_FILTER_BILINEAR, NULL, 0); @@ -256,19 +251,19 @@ test_composite (int testnum, printf ("w=%d, h=%d\n", w, h); } - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; - int n = lcg_rand_n (2) + 1; + int n = prng_rand_n (2) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (src_width); - clip_boxes[i].y1 = lcg_rand_n (src_height); + clip_boxes[i].x1 = prng_rand_n (src_width); + clip_boxes[i].y1 = prng_rand_n (src_height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1); if (verbose) { @@ -284,19 +279,19 @@ test_composite (int testnum, pixman_region_fini (&clip); } - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; - int n = lcg_rand_n (2) + 1; + int n = prng_rand_n (2) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (mask_width); - clip_boxes[i].y1 = lcg_rand_n (mask_height); + clip_boxes[i].x1 = prng_rand_n (mask_width); + clip_boxes[i].y1 = prng_rand_n (mask_height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (mask_width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (mask_width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (mask_height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (mask_height - clip_boxes[i].y1); if (verbose) { @@ -312,18 +307,18 @@ test_composite (int testnum, pixman_region_fini (&clip); } - if (lcg_rand_n (8) == 0) + if (prng_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; - int n = lcg_rand_n (2) + 1; + int n = prng_rand_n (2) + 1; for (i = 0; i < n; i++) { - clip_boxes[i].x1 = lcg_rand_n (dst_width); - clip_boxes[i].y1 = lcg_rand_n (dst_height); + clip_boxes[i].x1 = prng_rand_n (dst_width); + clip_boxes[i].y1 = prng_rand_n (dst_height); clip_boxes[i].x2 = - clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1); + clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1); clip_boxes[i].y2 = - clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1); + clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1); if (verbose) { @@ -337,7 +332,7 @@ test_composite (int testnum, pixman_region_fini (&clip); } - if (lcg_rand_n (2) == 0) + if (prng_rand_n (2) == 0) pixman_image_composite (op, src_img, NULL, dst_img, src_x, src_y, 0, 0, dst_x, dst_y, w, h); else @@ -380,11 +375,11 @@ test_composite (int testnum, } #if BILINEAR_INTERPOLATION_BITS == 8 -#define CHECKSUM 0x107B67ED +#define CHECKSUM 0x9096E6B6 #elif BILINEAR_INTERPOLATION_BITS == 7 -#define CHECKSUM 0x30EC0CF0 +#define CHECKSUM 0xCE8EC6BA #elif BILINEAR_INTERPOLATION_BITS == 4 -#define CHECKSUM 0x87B496BC +#define CHECKSUM 0xAB1D39BE #else #define CHECKSUM 0x00000000 #endif diff --git a/pixman/test/stress-test.c b/pixman/test/stress-test.c index 059250dd4..ee55c21ea 100644 --- a/pixman/test/stress-test.c +++ b/pixman/test/stress-test.c @@ -74,7 +74,7 @@ static pixman_filter_t filters[] = static int get_size (void) { - switch (lcg_rand_n (28)) + switch (prng_rand_n (28)) { case 0: return 1; @@ -84,10 +84,10 @@ get_size (void) default: case 2: - return lcg_rand_n (100); + return prng_rand_n (100); case 4: - return lcg_rand_n (2000) + 1000; + return prng_rand_n (2000) + 1000; case 5: return 65535; @@ -96,7 +96,7 @@ get_size (void) return 65536; case 7: - return lcg_rand_N (64000) + 63000; + return prng_rand_n (64000) + 63000; } } @@ -164,7 +164,7 @@ real_writer (void *src, uint32_t value, int size) static uint32_t fake_reader (const void *src, int size) { - uint32_t r = lcg_rand_u32 (); + uint32_t r = prng_rand (); assert (size == 1 || size == 2 || size == 4); @@ -182,16 +182,16 @@ log_rand (void) { uint32_t mask; - mask = (1 << lcg_rand_n (10)) - 1; + mask = (1 << prng_rand_n (10)) - 1; - return (lcg_rand_u32 () & mask) - (mask >> 1); + return (prng_rand () & mask) - (mask >> 1); } static int32_t rand_x (pixman_image_t *image) { if (image->type == BITS) - return lcg_rand_n (image->bits.width); + return prng_rand_n (image->bits.width); else return log_rand (); } @@ -200,7 +200,7 @@ static int32_t rand_y (pixman_image_t *image) { if (image->type == BITS) - return lcg_rand_n (image->bits.height); + return prng_rand_n (image->bits.height); else return log_rand (); } @@ -220,7 +220,7 @@ create_random_bits_image (void) int n_coefficients = 0; /* format */ - format = image_formats[lcg_rand_n (ARRAY_LENGTH (image_formats))]; + format = image_formats[prng_rand_n (ARRAY_LENGTH (image_formats))]; indexed = NULL; if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) @@ -246,7 +246,7 @@ create_random_bits_image (void) while ((uint64_t)width * height > 200000) { - if (lcg_rand_n(2) == 0) + if (prng_rand_n(2) == 0) height = 200000 / width; else width = 200000 / height; @@ -258,11 +258,11 @@ create_random_bits_image (void) width = 1; /* bits */ - switch (lcg_rand_n (7)) + switch (prng_rand_n (7)) { default: case 0: - stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); + stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); stride = (stride + 3) & (~3); bits = (uint32_t *)make_random_bytes (height * stride); break; @@ -273,7 +273,7 @@ create_random_bits_image (void) break; case 2: /* Zero-filled */ - stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); + stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); stride = (stride + 3) & (~3); bits = fence_malloc (height * stride); if (!bits) @@ -282,7 +282,7 @@ create_random_bits_image (void) break; case 3: /* Filled with 0xFF */ - stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); + stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); stride = (stride + 3) & (~3); bits = fence_malloc (height * stride); if (!bits) @@ -298,7 +298,7 @@ create_random_bits_image (void) break; case 5: /* bits is a real pointer, has read/write functions */ - stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); + stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17); stride = (stride + 3) & (~3); bits = fence_malloc (height * stride); if (!bits) @@ -309,7 +309,7 @@ create_random_bits_image (void) break; case 6: /* bits is a real pointer, stride is negative */ - stride = (width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17)); + stride = (width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17)); stride = (stride + 3) & (~3); bits = (uint32_t *)make_random_bytes (height * stride); if (!bits) @@ -320,11 +320,11 @@ create_random_bits_image (void) } /* Filter */ - filter = filters[lcg_rand_n (ARRAY_LENGTH (filters))]; + filter = filters[prng_rand_n (ARRAY_LENGTH (filters))]; if (filter == PIXMAN_FILTER_CONVOLUTION) { - int width = lcg_rand_n (3); - int height = lcg_rand_n (4); + int width = prng_rand_n (3); + int height = prng_rand_n (4); n_coefficients = width * height + 2; coefficients = malloc (n_coefficients * sizeof (pixman_fixed_t)); @@ -334,7 +334,7 @@ create_random_bits_image (void) int i; for (i = 0; i < width * height; ++i) - coefficients[i + 2] = lcg_rand_u32(); + coefficients[i + 2] = prng_rand(); coefficients[0] = width << 16; coefficients[1] = height << 16; @@ -380,11 +380,11 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) /* Set properties that are generic to all images */ /* Repeat */ - repeat = repeats[lcg_rand_n (ARRAY_LENGTH (repeats))]; + repeat = repeats[prng_rand_n (ARRAY_LENGTH (repeats))]; pixman_image_set_repeat (image, repeat); /* Alpha map */ - if (allow_alpha_map && lcg_rand_n (4) == 0) + if (allow_alpha_map && prng_rand_n (4) == 0) { pixman_image_t *alpha_map; int16_t x, y; @@ -405,17 +405,17 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) } /* Component alpha */ - pixman_image_set_component_alpha (image, lcg_rand_n (3) == 0); + pixman_image_set_component_alpha (image, prng_rand_n (3) == 0); /* Clip region */ - if (lcg_rand_n (8) < 2) + if (prng_rand_n (8) < 2) { pixman_region32_t region; int i, n_rects; pixman_region32_init (®ion); - switch (lcg_rand_n (12)) + switch (prng_rand_n (12)) { case 0: n_rects = 0; @@ -434,7 +434,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) break; default: - n_rects = lcg_rand_n (100); + n_rects = prng_rand_n (100); break; } @@ -452,7 +452,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) ®ion, ®ion, x, y, width, height); } - if (image->type == BITS && lcg_rand_n (8) != 0) + if (image->type == BITS && prng_rand_n (8) != 0) { uint32_t width, height; int x, y; @@ -463,10 +463,10 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) */ for (i = 0; i < 5; ++i) { - x = lcg_rand_n (2 * image->bits.width) - image->bits.width; - y = lcg_rand_n (2 * image->bits.height) - image->bits.height; - width = lcg_rand_n (image->bits.width) - x + 10; - height = lcg_rand_n (image->bits.height) - y + 10; + x = prng_rand_n (2 * image->bits.width) - image->bits.width; + y = prng_rand_n (2 * image->bits.height) - image->bits.height; + width = prng_rand_n (image->bits.width) - x + 10; + height = prng_rand_n (image->bits.height) - y + 10; if (width + x < x) width = INT32_MAX - x; @@ -484,13 +484,13 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) } /* Whether source clipping is enabled */ - pixman_image_set_source_clipping (image, !!lcg_rand_n (2)); + pixman_image_set_source_clipping (image, !!prng_rand_n (2)); /* Client clip */ - pixman_image_set_has_client_clip (image, !!lcg_rand_n (2)); + pixman_image_set_has_client_clip (image, !!prng_rand_n (2)); /* Transform */ - if (lcg_rand_n (5) < 2) + if (prng_rand_n (5) < 2) { pixman_transform_t xform; int i, j, k; @@ -504,39 +504,39 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) for (k = 0; k < 3; ++k) { - switch (lcg_rand_n (4)) + switch (prng_rand_n (4)) { case 0: /* rotation */ - c = lcg_rand_N (2 * 65536) - 65536; - s = lcg_rand_N (2 * 65536) - 65536; + c = prng_rand_n (2 * 65536) - 65536; + s = prng_rand_n (2 * 65536) - 65536; pixman_transform_rotate (&xform, NULL, c, s); break; case 1: /* translation */ - tx = lcg_rand_u32(); - ty = lcg_rand_u32(); + tx = prng_rand(); + ty = prng_rand(); pixman_transform_translate (&xform, NULL, tx, ty); break; case 2: /* scale */ - sx = lcg_rand_u32(); - sy = lcg_rand_u32(); + sx = prng_rand(); + sy = prng_rand(); pixman_transform_scale (&xform, NULL, sx, sy); break; case 3: - if (lcg_rand_n (16) == 0) + if (prng_rand_n (16) == 0) { /* random */ for (i = 0; i < 3; ++i) for (j = 0; j < 3; ++j) - xform.matrix[i][j] = lcg_rand_u32(); + xform.matrix[i][j] = prng_rand(); break; } - else if (lcg_rand_n (16) == 0) + else if (prng_rand_n (16) == 0) { /* zero */ memset (&xform, 0, sizeof xform); @@ -554,10 +554,10 @@ random_color (void) { pixman_color_t color = { - lcg_rand() & 0xffff, - lcg_rand() & 0xffff, - lcg_rand() & 0xffff, - lcg_rand() & 0xffff, + prng_rand() & 0xffff, + prng_rand() & 0xffff, + prng_rand() & 0xffff, + prng_rand() & 0xffff, }; return color; @@ -581,7 +581,7 @@ create_random_stops (int *n_stops) int i; pixman_gradient_stop_t *stops; - *n_stops = lcg_rand_n (50) + 1; + *n_stops = prng_rand_n (50) + 1; step = pixman_fixed_1 / *n_stops; @@ -646,8 +646,8 @@ create_random_radial_image (void) inner_c = create_random_point(); outer_c = create_random_point(); - inner_r = lcg_rand(); - outer_r = lcg_rand(); + inner_r = prng_rand(); + outer_r = prng_rand(); stops = create_random_stops (&n_stops); @@ -672,7 +672,7 @@ create_random_conical_image (void) pixman_image_t *result; c = create_random_point(); - angle = lcg_rand(); + angle = prng_rand(); stops = create_random_stops (&n_stops); @@ -691,7 +691,7 @@ create_random_image (void) { pixman_image_t *result; - switch (lcg_rand_n (5)) + switch (prng_rand_n (5)) { default: case 0: @@ -793,7 +793,7 @@ run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod) printf ("Seed 0x%08x\n", seed); } - lcg_srand (seed); + prng_srand (seed); source = create_random_image (); mask = create_random_image (); @@ -803,7 +803,7 @@ run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod) { set_general_properties (dest, TRUE); - op = op_list [lcg_rand_n (ARRAY_LENGTH (op_list))]; + op = op_list [prng_rand_n (ARRAY_LENGTH (op_list))]; pixman_image_composite32 (op, source, mask, dest, diff --git a/pixman/test/utils-prng.c b/pixman/test/utils-prng.c new file mode 100644 index 000000000..7c2dd6a9a --- /dev/null +++ b/pixman/test/utils-prng.c @@ -0,0 +1,238 @@ +/* + * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * Based on the public domain implementation of small noncryptographic PRNG + * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "utils.h" +#include "utils-prng.h" + +void smallprng_srand_r (smallprng_t *x, uint32_t seed) +{ + uint32_t i; + x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; + for (i = 0; i < 20; ++i) + smallprng_rand_r (x); +} + +/* + * Set a 32-bit seed for PRNG + * + * LCG is used here for generating independent seeds for different + * smallprng instances (in the case if smallprng is also used for + * generating these seeds, "Big Crush" test from TestU01 detects + * some problems in the glued 'prng_rand_128_r' output data). + * Actually we might be even better using some cryptographic + * hash for this purpose, but LCG seems to be also enough for + * passing "Big Crush". + */ +void prng_srand_r (prng_t *x, uint32_t seed) +{ +#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED + int i; + prng_rand_128_data_t dummy; + smallprng_srand_r (&x->p0, seed); + x->a[0] = x->a[1] = x->a[2] = x->a[3] = 0xf1ea5eed; + x->b[0] = x->c[0] = x->d[0] = (seed = seed * 1103515245 + 12345); + x->b[1] = x->c[1] = x->d[1] = (seed = seed * 1103515245 + 12345); + x->b[2] = x->c[2] = x->d[2] = (seed = seed * 1103515245 + 12345); + x->b[3] = x->c[3] = x->d[3] = (seed = seed * 1103515245 + 12345); + for (i = 0; i < 20; ++i) + prng_rand_128_r (x, &dummy); +#else + smallprng_srand_r (&x->p0, seed); + smallprng_srand_r (&x->p1, (seed = seed * 1103515245 + 12345)); + smallprng_srand_r (&x->p2, (seed = seed * 1103515245 + 12345)); + smallprng_srand_r (&x->p3, (seed = seed * 1103515245 + 12345)); + smallprng_srand_r (&x->p4, (seed = seed * 1103515245 + 12345)); +#endif +} + +static force_inline void +store_rand_128_data (void *addr, prng_rand_128_data_t *d, int aligned) +{ +#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED + if (aligned) + { + *(uint8x16 *)addr = d->vb; + return; + } +#endif + /* we could try something better for unaligned writes (packed attribute), + * but GCC is not very reliable: http://gcc.gnu.org/PR55454 */ + memcpy (addr, d, 16); +} + +/* + * Helper function and the actual code for "prng_randmemset_r" function + */ +static force_inline void +randmemset_internal (prng_t *prng, + uint8_t *buf, + size_t size, + prng_randmemset_flags_t flags, + int aligned) +{ + prng_t local_prng = *prng; + prng_rand_128_data_t randdata; + + while (size >= 16) + { + prng_rand_128_data_t t; + if (flags == 0) + { + prng_rand_128_r (&local_prng, &randdata); + } + else + { + prng_rand_128_r (&local_prng, &t); + prng_rand_128_r (&local_prng, &randdata); +#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED + if (flags & RANDMEMSET_MORE_FF) + { + const uint8x16 const_C0 = + { + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0 + }; + randdata.vb |= (t.vb >= const_C0); + } + if (flags & RANDMEMSET_MORE_00) + { + const uint8x16 const_40 = + { + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 + }; + randdata.vb &= (t.vb >= const_40); + } +#else + #define PROCESS_ONE_LANE(i) \ + if (flags & RANDMEMSET_MORE_FF) \ + { \ + uint32_t mask_ff = (t.w[i] & (t.w[i] << 1)) & 0x80808080; \ + mask_ff |= mask_ff >> 1; \ + mask_ff |= mask_ff >> 2; \ + mask_ff |= mask_ff >> 4; \ + randdata.w[i] |= mask_ff; \ + } \ + if (flags & RANDMEMSET_MORE_00) \ + { \ + uint32_t mask_00 = (t.w[i] | (t.w[i] << 1)) & 0x80808080; \ + mask_00 |= mask_00 >> 1; \ + mask_00 |= mask_00 >> 2; \ + mask_00 |= mask_00 >> 4; \ + randdata.w[i] &= mask_00; \ + } + + PROCESS_ONE_LANE (0) + PROCESS_ONE_LANE (1) + PROCESS_ONE_LANE (2) + PROCESS_ONE_LANE (3) +#endif + } + if (is_little_endian ()) + { + store_rand_128_data (buf, &randdata, aligned); + buf += 16; + } + else + { +#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED + const uint8x16 bswap_shufflemask = + { + 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + }; + randdata.vb = __builtin_shuffle (randdata.vb, bswap_shufflemask); + store_rand_128_data (buf, &randdata, aligned); + buf += 16; +#else + uint8_t t1, t2, t3, t4; + #define STORE_ONE_LANE(i) \ + t1 = randdata.b[i * 4 + 3]; \ + t2 = randdata.b[i * 4 + 2]; \ + t3 = randdata.b[i * 4 + 1]; \ + t4 = randdata.b[i * 4 + 0]; \ + *buf++ = t1; \ + *buf++ = t2; \ + *buf++ = t3; \ + *buf++ = t4; + + STORE_ONE_LANE (0) + STORE_ONE_LANE (1) + STORE_ONE_LANE (2) + STORE_ONE_LANE (3) +#endif + } + size -= 16; + } + while (size > 0) + { + uint8_t randbyte = prng_rand_r (&local_prng) & 0xFF; + if (flags != 0) + { + uint8_t t = prng_rand_r (&local_prng) & 0xFF; + if ((flags & RANDMEMSET_MORE_FF) && (t >= 0xC0)) + randbyte = 0xFF; + if ((flags & RANDMEMSET_MORE_00) && (t < 0x40)) + randbyte = 0x00; + } + *buf++ = randbyte; + size--; + } + *prng = local_prng; +} + +/* + * Fill memory buffer with random data. Flags argument may be used + * to tweak some statistics properties: + * RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00 + * RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF + */ +void prng_randmemset_r (prng_t *prng, + void *voidbuf, + size_t size, + prng_randmemset_flags_t flags) +{ + uint8_t *buf = (uint8_t *)voidbuf; + if ((uintptr_t)buf & 15) + { + /* unaligned buffer */ + if (flags == 0) + randmemset_internal (prng, buf, size, 0, 0); + else if (flags == RANDMEMSET_MORE_00_AND_FF) + randmemset_internal (prng, buf, size, RANDMEMSET_MORE_00_AND_FF, 0); + else + randmemset_internal (prng, buf, size, flags, 0); + } + else + { + /* aligned buffer */ + if (flags == 0) + randmemset_internal (prng, buf, size, 0, 1); + else if (flags == RANDMEMSET_MORE_00_AND_FF) + randmemset_internal (prng, buf, size, RANDMEMSET_MORE_00_AND_FF, 1); + else + randmemset_internal (prng, buf, size, flags, 1); + } +} diff --git a/pixman/test/utils-prng.h b/pixman/test/utils-prng.h new file mode 100644 index 000000000..285107f08 --- /dev/null +++ b/pixman/test/utils-prng.h @@ -0,0 +1,168 @@ +/* + * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * Based on the public domain implementation of small noncryptographic PRNG + * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __UTILS_PRNG_H__ +#define __UTILS_PRNG_H__ + +/* + * This file provides a fast SIMD-optimized noncryptographic PRNG (pseudorandom + * number generator), with the output good enough to pass "Big Crush" tests + * from TestU01 (http://en.wikipedia.org/wiki/TestU01). + * + * SIMD code uses http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + * which is a GCC specific extension. There is also a slower alternative + * code path, which should work with any C compiler. + * + * The "prng_t" structure keeps the internal state of the random number + * generator. It is possible to have multiple instances of the random number + * generator active at the same time, in this case each of them needs to have + * its own "prng_t". All the functions take a pointer to "prng_t" + * as the first argument. + * + * Functions: + * + * ---------------------------------------------------------------------------- + * void prng_srand_r (prng_t *prng, uint32_t seed); + * + * Initialize the pseudorandom number generator. The sequence of preudorandom + * numbers is deterministic and only depends on "seed". Any two generators + * initialized with the same seed will produce exactly the same sequence. + * + * ---------------------------------------------------------------------------- + * uint32_t prng_rand_r (prng_t *prng); + * + * Generate a single uniformly distributed 32-bit pseudorandom value. + * + * ---------------------------------------------------------------------------- + * void prng_randmemset_r (prng_t *prng, + * void *buffer, + * size_t size, + * prng_randmemset_flags_t flags); + * + * Fills the memory buffer "buffer" with "size" bytes of pseudorandom data. + * The "flags" argument may be used to tweak some statistics properties: + * RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00 + * RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF + * The flags can be combined. This allows a bit better simulation of typical + * pixel data, which normally contains a lot of fully transparent or fully + * opaque pixels. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "pixman-private.h" + +/*****************************************************************************/ + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) +#define GCC_VECTOR_EXTENSIONS_SUPPORTED +typedef uint32_t uint32x4 __attribute__ ((vector_size(16))); +typedef uint8_t uint8x16 __attribute__ ((vector_size(16))); +#endif + +typedef struct +{ + uint32_t a, b, c, d; +} smallprng_t; + +typedef struct +{ +#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED + uint32x4 a, b, c, d; +#else + smallprng_t p1, p2, p3, p4; +#endif + smallprng_t p0; +} prng_t; + +typedef union +{ + uint8_t b[16]; + uint32_t w[4]; +#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED + uint8x16 vb; + uint32x4 vw; +#endif +} prng_rand_128_data_t; + +/*****************************************************************************/ + +static force_inline uint32_t +smallprng_rand_r (smallprng_t *x) +{ + uint32_t e = x->a - ((x->b << 27) + (x->b >> (32 - 27))); + x->a = x->b ^ ((x->c << 17) ^ (x->c >> (32 - 17))); + x->b = x->c + x->d; + x->c = x->d + e; + x->d = e + x->a; + return x->d; +} + +/* Generate 4 bytes (32-bits) of random data */ +static force_inline uint32_t +prng_rand_r (prng_t *x) +{ + return smallprng_rand_r (&x->p0); +} + +/* Generate 16 bytes (128-bits) of random data */ +static force_inline void +prng_rand_128_r (prng_t *x, prng_rand_128_data_t *data) +{ +#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED + uint32x4 e = x->a - ((x->b << 27) + (x->b >> (32 - 27))); + x->a = x->b ^ ((x->c << 17) ^ (x->c >> (32 - 17))); + x->b = x->c + x->d; + x->c = x->d + e; + x->d = e + x->a; + data->vw = x->d; +#else + data->w[0] = smallprng_rand_r (&x->p1); + data->w[1] = smallprng_rand_r (&x->p2); + data->w[2] = smallprng_rand_r (&x->p3); + data->w[3] = smallprng_rand_r (&x->p4); +#endif +} + +typedef enum +{ + RANDMEMSET_MORE_00 = 1, /* ~25% chance for 0x00 bytes */ + RANDMEMSET_MORE_FF = 2, /* ~25% chance for 0xFF bytes */ + RANDMEMSET_MORE_00_AND_FF = (RANDMEMSET_MORE_00 | RANDMEMSET_MORE_FF) +} prng_randmemset_flags_t; + +/* Set the 32-bit seed for PRNG */ +void prng_srand_r (prng_t *prng, uint32_t seed); + +/* Fill memory buffer with random data */ +void prng_randmemset_r (prng_t *prng, + void *buffer, + size_t size, + prng_randmemset_flags_t flags); + +#endif diff --git a/pixman/test/utils.c b/pixman/test/utils.c index c887a6db9..66c8dcb89 100644 --- a/pixman/test/utils.c +++ b/pixman/test/utils.c @@ -27,10 +27,11 @@ #include <png.h> #endif -/* Random number seed +/* Random number generator state */ -uint32_t lcg_seed; +prng_t prng_state_data; +prng_t *prng_state; /*----------------------------------------------------------------------------*\ * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29. @@ -237,14 +238,6 @@ compute_crc32_for_image (uint32_t crc32, return crc32; } -pixman_bool_t -is_little_endian (void) -{ - volatile uint16_t endian_check_var = 0x1234; - - return (*(volatile uint8_t *)&endian_check_var == 0x34); -} - /* perform endian conversion of pixel data */ void @@ -431,13 +424,11 @@ uint8_t * make_random_bytes (int n_bytes) { uint8_t *bytes = fence_malloc (n_bytes); - int i; if (!bytes) return NULL; - for (i = 0; i < n_bytes; ++i) - bytes[i] = lcg_rand () & 0xff; + prng_randmemset (bytes, n_bytes, 0); return bytes; } @@ -689,9 +680,9 @@ get_random_seed (void) { union { double d; uint32_t u32; } t; t.d = gettime(); - lcg_srand (t.u32); + prng_srand (t.u32); - return lcg_rand_u32 (); + return prng_rand (); } #ifdef HAVE_SIGACTION @@ -785,7 +776,7 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb) uint32_t mask = (1 << depth) - 1; for (i = 0; i < 32768; ++i) - palette->ent[i] = lcg_rand() & mask; + palette->ent[i] = prng_rand() & mask; memset (palette->rgba, 0, sizeof (palette->rgba)); @@ -805,7 +796,7 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb) { uint32_t old_idx; - rgba24 = lcg_rand(); + rgba24 = prng_rand(); i15 = CONVERT_15 (rgba24, is_rgb); old_idx = palette->ent[i15]; diff --git a/pixman/test/utils.h b/pixman/test/utils.h index f7ea34c5f..78cf0d16d 100644 --- a/pixman/test/utils.h +++ b/pixman/test/utils.h @@ -4,6 +4,7 @@ #include <assert.h> #include "pixman-private.h" /* For 'inline' definition */ +#include "utils-prng.h" #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) @@ -11,49 +12,44 @@ * taken from POSIX.1-2001 example */ -extern uint32_t lcg_seed; +extern prng_t prng_state_data; +extern prng_t *prng_state; #ifdef USE_OPENMP -#pragma omp threadprivate(lcg_seed) +#pragma omp threadprivate(prng_state_data) +#pragma omp threadprivate(prng_state) #endif static inline uint32_t -lcg_rand (void) +prng_rand (void) { - lcg_seed = lcg_seed * 1103515245 + 12345; - return ((uint32_t)(lcg_seed / 65536) % 32768); + return prng_rand_r (prng_state); } static inline void -lcg_srand (uint32_t seed) +prng_srand (uint32_t seed) { - lcg_seed = seed; + if (!prng_state) + { + /* Without setting a seed, PRNG does not work properly (is just + * returning zeros). So we only initialize the pointer here to + * make sure that 'prng_srand' is always called before any + * other 'prng_*' function. The wrongdoers violating this order + * will get a segfault. */ + prng_state = &prng_state_data; + } + prng_srand_r (prng_state, seed); } static inline uint32_t -lcg_rand_n (int max) +prng_rand_n (int max) { - return lcg_rand () % max; + return prng_rand () % max; } -static inline uint32_t -lcg_rand_N (int max) -{ - uint32_t lo = lcg_rand (); - uint32_t hi = lcg_rand () << 15; - return (lo | hi) % max; -} - -static inline uint32_t -lcg_rand_u32 (void) +static inline void +prng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags) { - /* This uses the 10/11 most significant bits from the 3 lcg results - * (and mixes them with the low from the adjacent one). - */ - uint32_t lo = lcg_rand() >> -(32 - 15 - 11 * 2); - uint32_t mid = lcg_rand() << (32 - 15 - 11 * 1); - uint32_t hi = lcg_rand() << (32 - 15 - 11 * 0); - - return (hi ^ mid ^ lo); + prng_randmemset_r (prng_state, buffer, size, flags); } /* CRC 32 computation @@ -69,8 +65,12 @@ compute_crc32_for_image (uint32_t in_crc32, /* Returns TRUE if running on a little endian system */ -pixman_bool_t -is_little_endian (void); +static force_inline pixman_bool_t +is_little_endian (void) +{ + unsigned long endian_check_var = 1; + return *(unsigned char *)&endian_check_var == 1; +} /* perform endian conversion of pixel data */ |