Edit

IABSD.fr/xenocara/lib/pixman/test/thread-test.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2021-07-25 15:16:31
    Hash : 7a6d4716
    Message : pixman: update to 0.40.0

  • lib/pixman/test/thread-test.c
  • #include "utils.h"
    
    #if !defined (HAVE_PTHREADS) && !defined (_WIN32)
    
    int main ()
    {
        printf ("Skipped thread-test - pthreads or Windows Threads not supported\n");
        return 0;
    }
    
    #else
    
    #include <stdlib.h>
    
    #ifdef HAVE_PTHREADS
    # include <pthread.h>
    #elif defined (_WIN32)
    # define WIN32_LEAN_AND_MEAN
    # include <windows.h>
    #endif
    
    #define THREADS 16
    
    typedef struct
    {
        int       thread_no;
        uint32_t *dst_buf;
        prng_t    prng_state;
    #if defined (_WIN32) && !defined (HAVE_PTHREADS)
        uint32_t  crc32;
    #endif
    } info_t;
    
    static const pixman_op_t operators[] = 
    {
        PIXMAN_OP_SRC,
        PIXMAN_OP_OVER,
        PIXMAN_OP_ADD,
        PIXMAN_OP_CLEAR,
        PIXMAN_OP_SRC,
        PIXMAN_OP_DST,
        PIXMAN_OP_OVER,
        PIXMAN_OP_OVER_REVERSE,
        PIXMAN_OP_IN,
        PIXMAN_OP_IN_REVERSE,
        PIXMAN_OP_OUT,
        PIXMAN_OP_OUT_REVERSE,
        PIXMAN_OP_ATOP,
        PIXMAN_OP_ATOP_REVERSE,
        PIXMAN_OP_XOR,
        PIXMAN_OP_ADD,
        PIXMAN_OP_MULTIPLY,
        PIXMAN_OP_SCREEN,
        PIXMAN_OP_OVERLAY,
        PIXMAN_OP_DARKEN,
        PIXMAN_OP_LIGHTEN,
        PIXMAN_OP_HARD_LIGHT,
        PIXMAN_OP_DIFFERENCE,
        PIXMAN_OP_EXCLUSION,
    };
    
    static const pixman_format_code_t formats[] =
    {
        PIXMAN_a8r8g8b8,
        PIXMAN_r5g6b5,
        PIXMAN_a8,
        PIXMAN_a4,
        PIXMAN_a1,
        PIXMAN_b5g6r5,
        PIXMAN_r8g8b8a8,
        PIXMAN_a4r4g4b4
    };
    
    #define N_ROUNDS 8192
    
    #define RAND_ELT(arr)							\
        arr[prng_rand_r(&info->prng_state) % ARRAY_LENGTH (arr)]
    
    #define DEST_WIDTH (7)
    
    #ifdef HAVE_PTHREADS
    static void *
    thread (void *data)
    #elif defined (_WIN32)
    DWORD WINAPI
    thread (LPVOID data)
    #endif
    {
        info_t *info = data;
        uint32_t crc32 = 0x0;
        uint32_t src_buf[64];
        pixman_image_t *dst_img, *src_img;
        int i;
    
        prng_srand_r (&info->prng_state, info->thread_no);
    
        for (i = 0; i < N_ROUNDS; ++i)
        {
    	pixman_op_t op;
    	int rand1, rand2;
    
    	prng_randmemset_r (&info->prng_state, info->dst_buf,
    			   DEST_WIDTH * sizeof (uint32_t), 0);
    	prng_randmemset_r (&info->prng_state, src_buf,
    			   sizeof (src_buf), 0);
    
    	src_img = pixman_image_create_bits (
    	    RAND_ELT (formats), 4, 4, src_buf, 16);
    	dst_img = pixman_image_create_bits (
    	    RAND_ELT (formats), DEST_WIDTH, 1, info->dst_buf,
    	    DEST_WIDTH * sizeof (uint32_t));
    
    	image_endian_swap (src_img);
    	image_endian_swap (dst_img);
    	
    	rand2 = prng_rand_r (&info->prng_state) % 4;
    	rand1 = prng_rand_r (&info->prng_state) % 4;
    	op = RAND_ELT (operators);
    
    	pixman_image_composite32 (
    	    op,
    	    src_img, NULL, dst_img,
    	    rand1, rand2, 0, 0, 0, 0, DEST_WIDTH, 1);
    
    	crc32 = compute_crc32_for_image (crc32, dst_img);
    
    	pixman_image_unref (src_img);
    	pixman_image_unref (dst_img);
        }
    
    #ifdef HAVE_PTHREADS
        return (void *)(uintptr_t)crc32;
    #elif defined (_WIN32)
        info->crc32 = crc32;
        return 0;
    #endif
    }
    
    static inline uint32_t
    byteswap32 (uint32_t x)
    {
        return ((x & ((uint32_t)0xFF << 24)) >> 24) |
               ((x & ((uint32_t)0xFF << 16)) >>  8) |
               ((x & ((uint32_t)0xFF <<  8)) <<  8) |
               ((x & ((uint32_t)0xFF <<  0)) << 24);
    }
    
    int
    main (void)
    {
        uint32_t dest[THREADS * DEST_WIDTH];
        info_t info[THREADS] = { { 0 } };
    
    #ifdef HAVE_PTHREADS
        pthread_t threads[THREADS];
        void *retvals[THREADS];
    #elif defined (_WIN32)
        HANDLE  hThreadArray[THREADS];
        DWORD   dwThreadIdArray[THREADS];
    #endif
    
        uint32_t crc32s[THREADS], crc32;
        int i;
    
        for (i = 0; i < THREADS; ++i)
        {
    	info[i].thread_no = i;
    	info[i].dst_buf = &dest[i * DEST_WIDTH];
        }
    
    #ifdef HAVE_PTHREADS
        for (i = 0; i < THREADS; ++i)
          pthread_create (&threads[i], NULL, thread, &info[i]);
    
        for (i = 0; i < THREADS; ++i)
    	  pthread_join (threads[i], &retvals[i]);
    
        for (i = 0; i < THREADS; ++i)
        {
    	crc32s[i] = (uintptr_t)retvals[i];
    
    	if (is_little_endian())
    	    crc32s[i] = byteswap32 (crc32s[i]);
        }
    
    #elif defined (_WIN32)
        for (i = 0; i < THREADS; ++i)
          {
            hThreadArray[i] = CreateThread(NULL,
                                           0,
                                           thread,
                                           &info[i],
                                           0,
                                           &dwThreadIdArray[i]);
            if (hThreadArray[i] == NULL)
              {
                printf ("Windows thread creation failed!\n");
                return 1;
              }
          }
        for (i = 0; i < THREADS; ++i)
          {
            WaitForSingleObject (hThreadArray[i], INFINITE);
            CloseHandle(hThreadArray[i]);
          }
    
        for (i = 0; i < THREADS; ++i)
          {
            crc32s[i] = info[i].crc32;
    
            if (is_little_endian())
              crc32s[i] = byteswap32 (crc32s[i]);
          }
    #endif
    
        crc32 = compute_crc32 (0, crc32s, sizeof crc32s);
    
    #define EXPECTED 0x82C4D9FB
    
        if (crc32 != EXPECTED)
        {
    	printf ("thread-test failed. Got checksum 0x%08X, expected 0x%08X\n",
    		crc32, EXPECTED);
    	return 1;
        }
    
        return 0;
    }
    
    #endif